A React-component for creating demos of other components. See also react-demo-library
import React from 'react'
import Demo, {props as P} from 'react-demo'
import MyButton from './my-components/MyButton'
React.render(<Demo
target={MyButton}
props={{
label: P.string('Click me'),
disabled: P.bool(false),
onClick: P.callback.log(),
}}
/>, el)
See examples/index.js for more examples. To run them locally do the following:
$ npm install
$ npm run examples
$ open http://localhost:3000
$ npm install react-demo
Demo
is the main component of this library. It allows us to create a demo
of our components with controllable props.
import Demo from 'react-demo'
<Demo
target={DemoTargetComponent}
fullWidth={false}
panelBelow={false}
background="light"
codeIndentDepth={3}
props={propsConfig}
/>
The target component that we want to create a demo of.
If set to true
full page width will be available to the demo target component.
More precisely full width that avaliable to the Demo
component.
Sets the background of the demo. Available options are "light"
, "dark"
, and "none"
.
The default value is "light"
which gives us a Photoshop style light "transparent" background.
Specifies indentation of component code that is shown in control panel. The more the value the deeper indentation will go.
This property allows us to configure the props for the demo target.
Accepts an object {[propName]: propConfig}
.
For each specified propName
will be created a control on the panel,
and the prop value will pe passed to the target component.
The functions that can create propConfig
objects are available in Demo.props
,
and described bellow in this docs.
Creates a string input in the panel.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.string('bar'),
}}
/>
Creates a number input in the panel.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.number(10),
}}
/>
The same as props.string
but uses a textarea as the control, which allows us
to input multiline strings.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.text('foo\nbar'),
}}
/>
Creates a checkbox on the panel.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.bool(false),
}}
/>
Creates a select input in the panel. The options
argument can be either
an array of available options, or an object {[label]: value}
.
Note that we can pass objects of any type in options
no matter
if we use array or object. When array is used the values will be stringified
before using as labels in the control.
Acepts optional initialValue
as a second argument.
By default the first option is used as the initial value.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.choices([1, 'two', <Three />]),
bar: P.choices({
one: 1,
two: 'two',
three: <Three />,
}),
}}
/>
Creates a nested object properties configuration which can include any property configuration from this list.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
author: P.shape({
firstName: P.string('John'),
lastName: P.string('Doe'),
}),
title: P.string('My cool post'),
}}
/>
Allows us to input arbitrary json as a prop value. Uses enhanced textarea as a control.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.json({bar: 'baz'}),
}}
/>
Allows us set a constant value for a prop. Doesn't create a control on the panel.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.constant('bar'),
}}
/>
Creates a log widget in the panel, and passes a callback to the target component.
Accepts optional mapFn
that allows us to transform callback args
before they will be shown in the log. Usable when we don't want to see huge
event objects in the log for instance.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.callback.log()
}}
/>
Same as callback.log
, but shows only the last item in the log.
Usable if callback may be called too frequently.
import Demo, {props as P} from 'react-demo'
<Demo
...
props={{
foo: P.callback.logLatest()
}}
/>
The advanced mode allows us to create more complex demos.
To use advanced mode instead of specifying target
prop,
pass a custom render function as a child of Demo
.
The custom render fucntion accepts props
as the first argument.
The following two snippets are equivalent.
// Normal mode
<Demo target={Foo} ... />
// Same in advanced mode
<Demo ... >
{props => <Foo {...props} />}
</Demo>
In the advanced mode we also get access to the update
function,
using which we are able to update the demo props' values.
The update
function is passed as a second argument
to the custom render function. We're supossed to call update()
similary
to setState()
— passing an object with props that we want to change.
<Demo props={{value: P.string('foo')}}>
{
(props, update) =>
<input
value={props.value}
onChange={e => {update({value: e.target.value})}}
/>
}
</Demo>