Introduction to controls
The controls api provides an extensible interface for specifying and using input controls to enter component property values at run-time.
You can also check the list of pre-defined controls that are available for creating interactive examples of your components.
- Attach a controls object to your
example
- Ensure your
example
accepts the same parameters as declared in the controls object.
import { ControlTypes } from '@component-controls/core';export const textControl = ({ text }) => (<div>{props.text}</div>);textControl.controls = {text: { type: ControlTypes.TEXT, value: 'some text'}};
import { ControlTypes } from '@component-controls/core';import { Story, Playground, PropsTable } from '@component-controls/blocks';<Story name="text-control" controls={{ text: { type: ControlTypes.TEXT, value: 'some text'} }}>{props => (<div>{props.text}</div>)}</Story>
The component-controls built-in instrumentation module provides the ability to smartly detect any properties passed to your "stories" and creates the controls table accordingly.
- No properties are passed to the example. In this case, no controls will be used at run-time, since the properties can not be passed to the example:
export const overview = () => <button>no props</button>
Name | Description | Default |
---|
- Some named properties are passed to the example. In this case, only the properties specifically listed will be available at run-time (ie:
backgroundColor
):
export const overview = ({ backgroundColor }) => <button style={{ backgroundColor }}>some props</button>
Name | Description | Default | Controls |
---|---|---|---|
backgroundColor | ControlTypes.COLOR | grey | Invalid Type |
- All the properties are passed. In this case, all listed controls will be available at run-time:
export const overview = props => <button style={props}>all props</button>
Name | Description | Default | Controls |
---|---|---|---|
backgroundColor | ControlTypes.COLOR | grey | Invalid Type |
padding | ControlTypes.NUMBER | 10 | Invalid Type |
All controls can receive the following configuration properties
Full text property description with markdown support. It is used in the Props table.
some text
Name | Description | Default | Controls |
---|---|---|---|
text | a description with markdown support ControlTypes.TEXT | some text | Invalid Type |
Hide the property editor for this property will only use the value.
Name | Description | Default |
---|
Label to display next to the field editor by default uses the property name itself.
some text
Name | Description | Default | Controls |
---|---|---|---|
Enter some text: | ControlTypes.TEXT | some text | Invalid Type |
Allows custom sorting of the properties if 'order' is not provided, the props will be sorted by the order/key of the object (unreliable)
text 1/text 2
Name | Description | Default | Controls |
---|---|---|---|
text2 | ControlTypes.TEXT | text 2 | Invalid Type |
text1 | ControlTypes.TEXT | text 1 | Invalid Type |
Visually display the control property as required in the Props table.
some text
Name | Description | Default | Controls |
---|---|---|---|
text | ControlTypes.TEXT | some text | Invalid Type |
The default value that will be displayed in the Props table and the value that will be reverted to when the user clicks on reset. By default it is set from the value field of the control but you can also assign it manually.
some text
Name | Description | Default | Controls |
---|---|---|---|
text | ControlTypes.TEXT | a default value | Invalid Type |
data: {name: string; //faker.js name of data generatoroptions: object; // options to be passed to the faker data generator}
export const overview = ({ street }) => street;overview.controls = {street: {type: ControlTypes.TEXT,label: 'Street',value: '30333 Atlantic Ave.',data: { name: 'address.streetAddress' },},};
30333 Atlantic Ave.
Name | Description | Default | Controls |
---|---|---|---|
Street | ControlTypes.TEXT | 30333 Atlantic Ave. | Invalid Type |
export const overview = ({ number }) => number;overview.controls = {number: {type: ControlTypes.NUMBER,label: 'A number',value: 10,data: { name: 'random.number', options: { min: 50, max: 100 } },}}
10
Name | Description | Default | Controls |
---|---|---|---|
Street | ControlTypes.TEXT | 30333 Atlantic Ave. | Invalid Type |
The controls module can automatically extract component properties from the components prop info (ie typescript interfaces or react-props). This extraction process is called
smart-props
.- You also need to pass some parameters to your stories:
import { Button } from '../components/Button';export default {title: 'Smart Controls',component: Button,};export const smart = props => <Button {...props} />;
---title: Smart Controlscomponent: Button---import { Story, Playground, PropsTable } from '@component-controls/blocks';import { Button } from '../components/Button';<Playground><Story name='smart'>{props => <Button {...props} />}</Story></Playground><PropsTable name="smart" />
You can the behavior or smart-controls using the
smartControls
story propertyIf you assign false to
smartControls
, the system will skip creating automatically smart controls for the story.ESM
import { Button } from '../components/Button';export default {title: 'Smart Controls',};export const smart = props => <Button {...props} />;smart.component = Button;smart.smartControls = false;
MDX
---title: Smart Controls---import { Story, Playground, PropsTable } from '@component-controls/blocks';import { Button } from '../components/Button';<Playground><Story name='smart' component={Button} smartControls={false}>{props => <Button {...props} />}</Story></Playground><PropsTable name="smart" />
You might want to configure only some properties of your components to be editable.
ESM
import { Button } from '../components/Button';export default {title: 'Smart Controls',};export const smart = props => <Button {...props} />;smart.component = Button;smart.smartControls = {include: ['color', 'backgroundColor'],};
MDX
---title: Smart Controls---import { Story, Playground, PropsTable } from '@component-controls/blocks';import { Button } from '../components/Button';<Playground><Story name='smart' component={Button} smartControls={{ include: ['color', 'backgroundColor'] }}>{props => <Button {...props} />}</Story></Playground><PropsTable name="smart" />
You might want to prevent some properties of your components to be editable.
ESM
import { Button } from '../components/Button';export default {title: 'Smart Controls',};export const smart = props => <Button {...props} />;smart.component = Button;smart.smartControls = {exclude: ['color', 'backgroundColor'],};
MDX
---title: Smart Controls---import { Story, Playground, PropsTable } from '@component-controls/blocks';import { Button } from '../components/Button';<Playground><Story name='smart' component={Button} smartControls={{ exclude: ['color', 'backgroundColor'] }}>{props => <Button {...props} />}</Story></Playground><PropsTable name="smart" />
By assigning a
groupId
property you can display the properties grouped in different tabs. This works both when creating controls from scratch, or using smart-controls and just overriding their groupId field.ESM
import { Button } from '../components/Button';export default {title: 'Smart Controls',};export const smart = props => <Button {...props} />;smart.component = Button;smart.controls = {color: { groupId: 'Colors' },backgroundColor: { groupId: 'Colors' }};
MDX
---title: Smart Controls---import { Story, Playground, PropsTable } from '@component-controls/blocks';import { Button } from '../components/Button';<Playground><Story name='smart'component={Button}controls={{color: { groupId: 'Colors' },backgroundColor: { groupId: 'Colors' }}}>{props => <Button {...props} />}</Story></Playground><PropsTable name="smart" />
Name | Description | Default | Controls | |
---|---|---|---|---|
-(3 properties) | ||||
disabled | boolean | - | ||
type | options | button | ||
padding | number | 5 | ||
Colors(2 properties) |