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 {
|
||||
overflow: hidden;
|
||||
.indicator {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.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 { useSelector } from '../store'
|
||||
import { selectPivotizedSegment, selectOffset } from '../store/selectors'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import styles from './Segment.css'
|
||||
import { pivotize } from '../lib/pivotize'
|
||||
|
||||
export const Segment = () => {
|
||||
const [prefix, pivot, suffix] = useSelector(selectPivotizedSegment)
|
||||
const offset = useSelector(selectOffset)
|
||||
export const Segment = ({ children = '' }) => {
|
||||
const [prefix, pivot, suffix] = pivotize(children)
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.container} style={{ left: offset + '%' }}>
|
||||
<div className={styles.container}>
|
||||
<span className={styles.prefix}>{prefix}</span>
|
||||
<span className={styles.pivot}>{pivot}</span>
|
||||
<span className={styles.suffix}>{suffix}</span>
|
||||
</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