Skip to content

Commit

Permalink
BorderBoxControl: Refactor stories to TypeScript and Controls (#45002)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Oct 26, 2022
1 parent 91b2a2e commit 1cff757
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 118 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- `TabPanel`: updated to satisfy `react/exhaustive-deps` eslint rule ([#44935](https://github.com/WordPress/gutenberg/pull/44935))
- `ColorPalette`: Convert to TypeScript ([#44632](https://github.com/WordPress/gutenberg/pull/44632)).
- `UnitControl`: Add tests ([#45260](https://github.com/WordPress/gutenberg/pull/45260)).
- `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,
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

0 comments on commit 1cff757

Please sign in to comment.