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

BorderBoxControl: Refactor stories to TypeScript and Controls #45002

Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- `SlotFill`: updated to satisfy `react/exhaustive-deps` eslint rule ([#44403](https://github.com/WordPress/gutenberg/pull/44403))
- `Context`: updated to ignore `react/exhaustive-deps` eslint rule ([#45044](https://github.com/WordPress/gutenberg/pull/45044))
- `Button`: Refactor Storybook to controls and align docs ([#44105](https://github.com/WordPress/gutenberg/pull/44105)).
- `BorderBoxControl`: Convert stories to TypeScript and use Controls ([#45002](https://github.com/WordPress/gutenberg/pull/45002)).

## 21.3.0 (2022-10-19)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const BorderLabel = ( props: LabelProps ) => {
);
};

const BorderBoxControl = (
props: WordPressComponentProps< BorderBoxControlProps, 'div' >,
const UnconnectedBorderBoxControl = (
props: WordPressComponentProps< BorderBoxControlProps, 'div', false >,
forwardedRef: React.ForwardedRef< any >
) => {
const {
Expand Down Expand Up @@ -153,9 +153,58 @@ const BorderBoxControl = (
);
};

const ConnectedBorderBoxControl = contextConnect(
BorderBoxControl,
/**
* The `BorderBoxControl` effectively has two view states. The first, a "linked"
* view, allows configuration of a flat border via a single `BorderControl`.
* The second, a "split" view, contains a `BorderControl` for each side
* as well as a visualizer for the currently selected borders. Each view also
* contains a button to toggle between the two.
*
* When switching from the "split" view to "linked", if the individual side
* borders are not consistent, the "linked" view will display any border
* properties selections that are consistent while showing a mixed state for
* those that aren't. For example, if all borders had the same color and style
* but different widths, then the border dropdown in the "linked" view's
* `BorderControl` would show that consistent color and style but the "linked"
* view's width input would show "Mixed" placeholder text.
*
* ```jsx
* import { __experimentalBorderBoxControl as BorderBoxControl } from '@wordpress/components';
* import { __ } from '@wordpress/i18n';
*
* const colors = [
* { name: 'Blue 20', color: '#72aee6' },
* // ...
* ];
*
* const MyBorderBoxControl = () => {
* const defaultBorder = {
* color: '#72aee6',
* style: 'dashed',
* width: '1px',
* };
* const [ borders, setBorders ] = useState( {
* top: defaultBorder,
* right: defaultBorder,
* bottom: defaultBorder,
* left: defaultBorder,
* } );
* const onChange = ( newBorders ) => setBorders( newBorders );
*
* return (
* <BorderBoxControl
* colors={ colors }
* label={ __( 'Borders' ) }
* onChange={ onChange }
* value={ borders }
* />
* );
* };
* ```
*/
export const BorderBoxControl = contextConnect(
UnconnectedBorderBoxControl,
'BorderBoxControl'
);

export default ConnectedBorderBoxControl;
export default BorderBoxControl;
106 changes: 0 additions & 106 deletions packages/components/src/border-box-control/stories/index.js

This file was deleted.

92 changes: 92 additions & 0 deletions packages/components/src/border-box-control/stories/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* External dependencies
*/
import type { ComponentMeta, ComponentStory } from '@storybook/react';
import type { ComponentProps } from 'react';

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

/**
* Internal dependencies
*/
import Button from '../../button';
import Popover from '../../popover';
import { BorderBoxControl } from '../';
import { Provider as SlotFillProvider } from '../../slot-fill';

const meta: ComponentMeta< typeof BorderBoxControl > = {
title: 'Components (Experimental)/BorderBoxControl',
component: BorderBoxControl,
argTypes: {
onChange: { action: 'onChange' },
value: { control: { type: null } },
},
parameters: {
controls: { expanded: true },
docs: { source: { state: 'open' } },
},
};
export default meta;

// Available border colors.
const colors = [
{ name: 'Blue 20', color: '#72aee6' },
{ name: 'Blue 40', color: '#3582c4' },
{ name: 'Red 40', color: '#e65054' },
{ name: 'Red 70', color: '#8a2424' },
{ name: 'Yellow 10', color: '#f2d675' },
{ name: 'Yellow 40', color: '#bd8600' },
];

const Template: ComponentStory< typeof BorderBoxControl > = ( props ) => {
const { onChange, ...otherProps } = props;
const [ borders, setBorders ] = useState< typeof props[ 'value' ] >();

const onChangeMerged: ComponentProps<
typeof BorderBoxControl
>[ 'onChange' ] = ( newBorders ) => {
setBorders( newBorders );
onChange( newBorders );
};

return (
<SlotFillProvider>
<div style={ { maxWidth: '248px', padding: '16px' } }>
<BorderBoxControl
{ ...otherProps }
onChange={ onChangeMerged }
value={ borders }
/>
</div>
<hr
style={ {
marginTop: '100px',
borderColor: '#ddd',
borderStyle: 'solid',
borderBottom: 'none',
} }
/>
<p style={ { color: '#aaa', fontSize: '0.9em' } }>
The BorderBoxControl is intended to be used within a component
that will provide reset controls. The button below is only for
convenience.
</p>
<Button
variant="primary"
onClick={ () => onChangeMerged( undefined ) }
>
Reset
</Button>
{ /* @ts-expect-error Ignore until Popover.Slot is converted to TS */ }
<Popover.Slot />
</SlotFillProvider>
);
};
export const Default = Template.bind( {} );
Default.args = {
colors,
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
label: 'Borders',
};
14 changes: 7 additions & 7 deletions packages/components/src/border-control/stories/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ export default meta;

// Available border colors.
const colors = [
{ name: 'Blue', color: '#72aee6' },
{ name: 'Red', color: '#e65054' },
{ name: 'Yellow', color: '#f2d675' },
{ name: 'Blue', color: '#72aee6' },
{ name: 'Red', color: '#e65054' },
{ name: 'Yellow', color: '#f2d675' },
{ name: 'Blue 20', color: '#72aee6' },
{ name: 'Blue 40', color: '#3582c4' },
{ name: 'Red 40', color: '#e65054' },
{ name: 'Red 70', color: '#8a2424' },
{ name: 'Yellow 10', color: '#f2d675' },
{ name: 'Yellow 40', color: '#bd8600' },
];

// Multiple origin colors.
Expand Down Expand Up @@ -91,7 +91,7 @@ const Template: ComponentStory< typeof BorderControl > = ( {
{ ...props }
/>
</div>
{ /* @ts-expect-error Ignore until Popover is converted to TS */ }
{ /* @ts-expect-error Ignore until Popover.Slot is converted to TS */ }
<Popover.Slot />
</SlotFillProvider>
);
Expand Down