Add storybook
parent
4656f5b280
commit
a81a5a2458
@ -0,0 +1,13 @@
|
|||||||
|
module.exports = {
|
||||||
|
stories: ['../src/components/**/*.stories.js'],
|
||||||
|
addons: [
|
||||||
|
'@storybook/addon-knobs/register',
|
||||||
|
'@storybook/addon-actions',
|
||||||
|
'@storybook/addon-links'
|
||||||
|
],
|
||||||
|
webpackFinal: async config => {
|
||||||
|
// do mutation to the config
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
import { addDecorator } from '@storybook/react'
|
||||||
|
import { withInfo } from '@storybook/addon-info'
|
||||||
|
import { withKnobs } from '@storybook/addon-knobs'
|
||||||
|
import { withConsole } from '@storybook/addon-console'
|
||||||
|
|
||||||
|
addDecorator(withInfo({ inline: true }))
|
||||||
|
addDecorator(withKnobs)
|
||||||
|
addDecorator((storyFn, context) => withConsole()(storyFn)(context))
|
@ -0,0 +1,23 @@
|
|||||||
|
module.exports = {
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: 'style-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: {
|
||||||
|
modules: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'postcss-loader'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
.wrapper {
|
.indicator {
|
||||||
overflow: hidden;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border {
|
.border {
|
@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import styles from './Indicator.css'
|
||||||
|
|
||||||
|
export const Indicator = ({ type = 'border', children }) => {
|
||||||
|
const IndicatorType = indicatorByType(type)
|
||||||
|
return (
|
||||||
|
<div className={styles.indicator}>
|
||||||
|
<IndicatorType>{children}</IndicatorType>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const indicatorByType = type => {
|
||||||
|
switch (type) {
|
||||||
|
case 'border':
|
||||||
|
return BorderIndicator
|
||||||
|
case 'pipe':
|
||||||
|
return PipeIndicator
|
||||||
|
default:
|
||||||
|
throw Error(`Indicator of type ${type} is not defined`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const BorderIndicator = ({ children }) => (
|
||||||
|
<>
|
||||||
|
<div className={styles.border}></div>
|
||||||
|
<div className={styles.marker}></div>
|
||||||
|
{children}
|
||||||
|
<div className={styles.marker}></div>
|
||||||
|
<div className={styles.border}></div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
const PipeIndicator = ({ children }) => (
|
||||||
|
<>
|
||||||
|
<div>|</div>
|
||||||
|
{children}
|
||||||
|
<div>|</div>
|
||||||
|
</>
|
||||||
|
)
|
@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Indicator } from './Indicator'
|
||||||
|
import { Segment } from './Segment'
|
||||||
|
import { radios } from '@storybook/addon-knobs'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
component: Indicator,
|
||||||
|
title: 'Indicator'
|
||||||
|
}
|
||||||
|
|
||||||
|
const typeKnob = () =>
|
||||||
|
radios('Type', { Border: 'border', Pipe: 'pipe' }, 'border')
|
||||||
|
|
||||||
|
export const HappyPath = () => {
|
||||||
|
return <Indicator type={typeKnob()}>Hello World</Indicator>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WithSegment = () => {
|
||||||
|
return (
|
||||||
|
<Indicator type={typeKnob()}>
|
||||||
|
<Segment>Hello World</Segment>
|
||||||
|
</Indicator>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper that is of double width while hiding its overflow.
|
||||||
|
* Place children with offset (from -50 to 50, 0 is center)
|
||||||
|
*/
|
||||||
|
export const Offset = ({ offset = 0, children }) => {
|
||||||
|
offset = (offset - 50) / 2
|
||||||
|
return (
|
||||||
|
<div style={{ overflow: 'hidden' }}>
|
||||||
|
<div style={{ width: '200%' }}>
|
||||||
|
<div style={{ position: 'relative', left: `${offset}%` }}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset.propTypes = {
|
||||||
|
offset: PropTypes.number
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { number } from '@storybook/addon-knobs'
|
||||||
|
|
||||||
|
import { Offset } from './Offset'
|
||||||
|
import { Indicator } from './Indicator'
|
||||||
|
import { Segment } from './Segment'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
component: Offset,
|
||||||
|
title: 'Offset'
|
||||||
|
}
|
||||||
|
|
||||||
|
const offsetKnob = () =>
|
||||||
|
number('Offset', 0, {
|
||||||
|
range: true,
|
||||||
|
min: -50,
|
||||||
|
max: 50,
|
||||||
|
step: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
export const BlockElement = () => (
|
||||||
|
<Offset offset={offsetKnob()}>
|
||||||
|
<div style={{ textAlign: 'center' }}>This text is centered</div>
|
||||||
|
</Offset>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const InlineElement = () => (
|
||||||
|
<Offset offset={offsetKnob()}>
|
||||||
|
This a long text to see that inline elements get pushed far to the left. To
|
||||||
|
be precise they get pushed half the container with to the left. Use
|
||||||
|
text-align: center for better display.
|
||||||
|
</Offset>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const WithIndicator = () => (
|
||||||
|
<Offset offset={offsetKnob()}>
|
||||||
|
<Indicator>
|
||||||
|
<Segment>Hello World</Segment>
|
||||||
|
</Indicator>
|
||||||
|
</Offset>
|
||||||
|
)
|
@ -1,28 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { useSelector } from '../store'
|
|
||||||
|
|
||||||
import styles from './PivotMarker.css'
|
|
||||||
import { selectOffset } from '../store/selectors'
|
|
||||||
|
|
||||||
export const PipeMarker = ({ children }) => (
|
|
||||||
<div>
|
|
||||||
<div style={{ textAlign: 'center' }}>|</div>
|
|
||||||
{children}
|
|
||||||
<div style={{ textAlign: 'center' }}>|</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
export const BorderMarker = ({ children }) => {
|
|
||||||
const offset = useSelector(selectOffset)
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className={styles.border}></div>
|
|
||||||
<div className={styles.wrapper}>
|
|
||||||
<div className={styles.marker} style={{ left: offset + '%' }}></div>
|
|
||||||
{children}
|
|
||||||
<div className={styles.marker} style={{ left: offset + '%' }}></div>
|
|
||||||
</div>
|
|
||||||
<div className={styles.border}></div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,19 +1,20 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useSelector } from '../store'
|
import PropTypes from 'prop-types'
|
||||||
import { selectPivotizedSegment, selectOffset } from '../store/selectors'
|
|
||||||
|
|
||||||
import styles from './Segment.css'
|
import styles from './Segment.css'
|
||||||
|
import { pivotize } from '../lib/pivotize'
|
||||||
|
|
||||||
export const Segment = () => {
|
export const Segment = ({ children = '' }) => {
|
||||||
const [prefix, pivot, suffix] = useSelector(selectPivotizedSegment)
|
const [prefix, pivot, suffix] = pivotize(children)
|
||||||
const offset = useSelector(selectOffset)
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrapper}>
|
<div className={styles.container}>
|
||||||
<div className={styles.container} style={{ left: offset + '%' }}>
|
|
||||||
<span className={styles.prefix}>{prefix}</span>
|
<span className={styles.prefix}>{prefix}</span>
|
||||||
<span className={styles.pivot}>{pivot}</span>
|
<span className={styles.pivot}>{pivot}</span>
|
||||||
<span className={styles.suffix}>{suffix}</span>
|
<span className={styles.suffix}>{suffix}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Segment.propTypes = {
|
||||||
|
children: PropTypes.string.isRequired
|
||||||
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { text } from '@storybook/addon-knobs'
|
||||||
|
|
||||||
|
import { Segment } from './Segment'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
component: Segment,
|
||||||
|
title: 'Segment'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const HappyPath = () => {
|
||||||
|
return <Segment>{text('Text', 'Hello')}</Segment>
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { action } from '@storybook/addon-actions'
|
||||||
|
|
||||||
|
import { Slider } from './Slider'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
component: Slider,
|
||||||
|
title: 'Slider'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Default = () => <Slider onChange={action()} />
|
||||||
|
|
||||||
|
export const CustomRange = () => <Slider onChange={action()} min={5} max={15} />
|
||||||
|
|
||||||
|
export const CustomStep = () => <Slider onChange={action()} step={5} />
|
Loading…
Reference in New Issue