A next-generation tool to create blazing-fast documentation sites
API
created:8/18/2020
updated:8/18/2020

Overview

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.
in action

Background

You can use controls in both formats ESM and MDX.

Basic usage

  1. Attach a controls object to your example
  2. Ensure your example accepts the same parameters as declared in the controls object.

ESM

import { ControlTypes } from '@component-controls/core';
export const textControl = ({ text }) => (<div>{props.text}</div>);
textControl.controls = {
text: { type: ControlTypes.TEXT, value: 'some text'}
};

MDX

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>

Smart properties

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.
  1. 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
  1. 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
  1. 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

Display options

All controls can receive the following configuration properties

description

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

hidden

Hide the property editor for this property will only use the value.
some text
Name
Description
Default

label

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

order

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

required

Visually display the control property as required in the Props table.
some text
Name
Description
Default
Controls
text
ControlTypes.TEXT
some text
Invalid Type

defaultValue

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

Randomize data

data helper information to generate random data will be used in conjunction with faker.js.
data: {
name: string; //faker.js name of data generator
options: object; // options to be passed to the faker data generator
}

Custom generator name

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

Custom generator options

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

Smart controls

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.
  1. The make smart-props work, you need to assign a component to your ESM or MDX documents (will aplpy to all stories defined) or to a specific story.
  2. You also need to pass some parameters to your stories:

ESM

import { Button } from '../components/Button';
export default {
title: 'Smart Controls',
component: Button,
};
export const smart = props => <Button {...props} />;

MDX

---
title: Smart Controls
component: 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" />
Name
Description
Default
Controls
disabled
boolean
-
backgroundColor
color
#fefefe
color
color
black
type
options
button
padding
number
5

Configure smart-controls

You can the behavior or smart-controls using the smartControls story property

Disable

If 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" />

Include only specific properties

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" />
Name
Description
Default
Controls
backgroundColor
color
#fefefe
color
color
black

Exclude specific properties

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" />
Name
Description
Default
Controls
disabled
boolean
-
type
options
button
padding
number
5

Grouping

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)