Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RangeControl: Refactor stories to use Controls #39357

Merged
merged 3 commits into from
Mar 21, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 91 additions & 119 deletions packages/components/src/range-control/stories/index.js
Original file line number Diff line number Diff line change
@@ -1,145 +1,128 @@
/**
* External dependencies
*/
import styled from '@emotion/styled';
import { boolean, number, text } from '@storybook/addon-knobs';

/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { wordpress } from '@wordpress/icons';
import { styles, wordpress } from '@wordpress/icons';

/**
* Internal dependencies
*/
import RangeControl from '../index';
import { COLORS } from '../../utils';

const ICONS = { styles, wordpress };

export default {
title: 'Components/RangeControl',
component: RangeControl,
argTypes: {
afterIcon: {
control: { type: 'select' },
options: Object.keys( ICONS ),
mapping: ICONS,
},
allowReset: { control: { type: 'boolean' } },
beforeIcon: {
control: { type: 'select' },
options: Object.keys( ICONS ),
mapping: ICONS,
},
color: { control: { type: 'color' } },
disabled: { control: { type: 'boolean' } },
help: { control: { type: 'text' } },
initialPosition: { control: { type: 'number' } },
marks: { control: { type: 'object' } },
min: { control: { type: 'number' } },
max: { control: { type: 'number' } },
railColor: { control: { type: 'color' } },
showTooltip: { control: { type: 'boolean' } },
step: { control: { type: 'number' } },
trackColor: { control: { type: 'color' } },
withInputField: { control: { type: 'boolean' } },
},
parameters: {
knobs: { disable: false },
docs: { source: { state: 'open' } },
},
};

const RangeControlWithState = ( props ) => {
const initialValue = props.value === undefined ? 5 : props.value;
const [ value, setValue ] = useState( initialValue );
const [ value, setValue ] = useState();

return <RangeControl { ...props } value={ value } onChange={ setValue } />;
};

const DefaultExample = () => {
const [ value, setValue ] = useState( undefined );

const showBeforeIcon = boolean( 'beforeIcon', false );
const showAfterIcon = boolean( 'afterIcon', false );

const props = {
afterIcon: showAfterIcon ? wordpress : undefined,
allowReset: boolean( 'allowReset', false ),
beforeIcon: showBeforeIcon ? wordpress : undefined,
color: text( 'color', COLORS.ui.theme ),
disabled: boolean( 'disabled', false ),
help: text( 'help', '' ),
label: text( 'label', 'Range Label' ),
marks: boolean( 'marks', false ),
max: number( 'max', 100 ),
min: number( 'min', 0 ),
showTooltip: boolean( 'showTooltip', false ),
step: text( 'step', 1 ),
railColor: text( 'railColor', null ),
trackColor: text( 'trackColor', null ),
withInputField: boolean( 'withInputField', true ),
value,
onChange: setValue,
};

return (
<Wrapper>
<RangeControl { ...props } />
</Wrapper>
);
};

const RangeControlLabeledByMarksType = ( props ) => {
const label = Array.isArray( props.marks ) ? 'Custom' : 'Automatic';
return <RangeControl { ...{ ...props, label } } />;
export const Default = RangeControlWithState.bind( {} );
Default.args = {
label: 'Range label',
};

export const _default = () => {
return <DefaultExample />;
/**
* The `initialPosition` prop sets the starting position of the slider when no `value` is provided.
*/
export const InitialValueZero = RangeControlWithState.bind( {} );
InitialValueZero.args = {
...Default.args,
initialPosition: 0,
mirka marked this conversation as resolved.
Show resolved Hide resolved
max: 20,
};

export const InitialValueZero = () => {
const label = text( 'Label', 'How many columns should this use?' );
/**
* Setting the `step` prop to `"any"` will allow users to select non-integer values.
* This also overrides both `withInputField` and `showTooltip` props to `false`.
*/
export const WithAnyStep = ( props ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use RangeControlWithState instead? (in that case, the additional initialValue prop would actually come in handy)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of thought it was useful to have the current value showing for this example, otherwise it's impossible to see that it's a float.

Copy link
Contributor

@ciampo ciampo Mar 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good point. I had forgotten about this 😅 Let's leave it as-is

const [ value, setValue ] = useState( 1.2345 );

return (
<RangeControlWithState
initialPosition={ 0 }
label={ label }
max={ 20 }
min={ 0 }
value={ null }
/>
<>
<RangeControl value={ value } onChange={ setValue } { ...props } />
<p>Current value: { value }</p>
</>
);
};

export const withAnyStep = () => {
return <RangeControlWithState label="Brightness" step="any" />;
WithAnyStep.args = {
label: 'Brightness',
step: 'any',
};

export const withHelp = () => {
const label = text( 'Label', 'How many columns should this use?' );
const help = text(
'Help Text',
'Please select the number of columns you would like this to contain.'
);

return <RangeControlWithState label={ label } help={ help } />;
export const WithHelp = RangeControlWithState.bind( {} );
WithHelp.args = {
...Default.args,
label: 'How many columns should this use?',
help: 'Please select the number of columns you would like this to contain.',
};

export const withMinimumAndMaximumLimits = () => {
const label = text( 'Label', 'How many columns should this use?' );
const min = number( 'Min Value', 2 );
const max = number( 'Max Value', 10 );

return <RangeControlWithState label={ label } min={ min } max={ max } />;
/**
* Set `min` and `max` values to constrain the range of allowed values.
*/
export const WithMinimumAndMaximumLimits = RangeControlWithState.bind( {} );
WithMinimumAndMaximumLimits.args = {
...Default.args,
min: 2,
max: 10,
};

export const withIconBefore = () => {
const label = text( 'Label', 'How many columns should this use?' );
const showIcon = boolean( 'icon', true );

return (
<RangeControlWithState
label={ label }
beforeIcon={ showIcon ? wordpress : undefined }
/>
);
export const WithIconBefore = RangeControlWithState.bind( {} );
WithIconBefore.args = {
...Default.args,
beforeIcon: wordpress,
};

export const withIconAfter = () => {
const label = text( 'Label', 'How many columns should this use?' );
const showIcon = boolean( 'icon', true );

return (
<RangeControlWithState
label={ label }
afterIcon={ showIcon ? wordpress : undefined }
/>
);
export const WithIconAfter = RangeControlWithState.bind( {} );
WithIconAfter.args = {
...Default.args,
afterIcon: wordpress,
};

export const withReset = () => {
const label = text( 'Label', 'How many columns should this use?' );

return <RangeControlWithState label={ label } allowReset />;
export const WithReset = RangeControlWithState.bind( {} );
WithReset.args = {
...Default.args,
allowReset: true,
};

export const marks = () => {
/**
* Use `marks` to render a visual representation of `step` ticks. Custom mark indicators can be provided by an `Array`.
*/
export const WithMarks = ( props ) => {
const marksBase = [
{ value: 0, label: '0' },
{ value: 1, label: '1' },
Expand All @@ -164,11 +147,15 @@ export const marks = () => {
const minNegative = { min: -10, max: 10, step: 1 };
const rangeNegative = { min: -10, max: -1, step: 1 };

// Use a short alias to keep formatting to fewer lines.
const Range = RangeControlLabeledByMarksType;
const Range = ( localProps ) => {
const label = Array.isArray( localProps.marks )
? 'Custom'
: 'Automatic';
return <RangeControl { ...{ ...localProps, ...props, label } } />;
};

return (
<Wrapper>
<>
<h2>Integer Step</h2>
<Range marks { ...stepInteger } />
<Range marks={ marksBase } { ...stepInteger } />
Expand All @@ -188,21 +175,6 @@ export const marks = () => {
<h2>Any Step</h2>
<Range marks { ...{ ...stepInteger, step: 'any' } } />
<Range marks={ marksBase } { ...{ ...stepInteger, step: 'any' } } />
</Wrapper>
</>
);
};

export const multiple = () => {
mirka marked this conversation as resolved.
Show resolved Hide resolved
return (
<Wrapper>
<RangeControlWithState />
<RangeControlWithState />
<RangeControlWithState />
<RangeControlWithState />
</Wrapper>
);
};

const Wrapper = styled.div`
padding: 60px 40px;
`;