From cac25d8dbec3973dee634a26b1d6bc41c7baeb29 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Tue, 26 Mar 2024 01:02:37 +0900 Subject: [PATCH 1/5] CustomSelectControlV2: Rename for consistency --- .../src/custom-select-control-v2/README.md | 54 +++++++++---------- .../default-component/index.tsx | 4 +- .../src/custom-select-control-v2/index.tsx | 8 ++- .../{custom-select-item.tsx => item.tsx} | 2 + .../legacy-component/index.tsx | 6 +-- .../stories/default.story.tsx | 33 ++++++------ .../stories/legacy.story.tsx | 16 +++--- .../custom-select-control-v2/test/index.tsx | 34 +++++++----- 8 files changed, 86 insertions(+), 71 deletions(-) rename packages/components/src/custom-select-control-v2/{custom-select-item.tsx => item.tsx} (93%) diff --git a/packages/components/src/custom-select-control-v2/README.md b/packages/components/src/custom-select-control-v2/README.md index 634b25808c7d4..488194c067b5c 100644 --- a/packages/components/src/custom-select-control-v2/README.md +++ b/packages/components/src/custom-select-control-v2/README.md @@ -1,4 +1,4 @@ -# CustomSelect +# CustomSelectControlV2
This feature is still experimental. “Experimental” means this is an early implementation subject to drastic and breaking changes. @@ -12,31 +12,31 @@ Used to render a customizable select control component. #### Uncontrolled Mode -CustomSelect can be used in an uncontrolled mode, where the component manages its own state. In this mode, the `defaultValue` prop can be used to set the initial selected value. If this prop is not set, the first value from the children will be selected by default. +CustomSelectControlV2 can be used in an uncontrolled mode, where the component manages its own state. In this mode, the `defaultValue` prop can be used to set the initial selected value. If this prop is not set, the first value from the children will be selected by default. ```jsx -const UncontrolledCustomSelect = () => ( - - +const UncontrolledCustomSelectControlV2 = () => ( + + { /* The `defaultValue` since it wasn't defined */ } Blue - - + + Purple - - + + Pink - - + + ); ``` #### Controlled Mode -CustomSelect can also be used in a controlled mode, where the parent component specifies the `value` and the `onChange` props to control selection. +CustomSelectControlV2 can also be used in a controlled mode, where the parent component specifies the `value` and the `onChange` props to control selection. ```jsx -const ControlledCustomSelect = () => { +const ControlledCustomSelectControlV2 = () => { const [ value, setValue ] = useState< string | string[] >(); const renderControlledValue = ( renderValue: string | string[] ) => ( @@ -46,7 +46,7 @@ const ControlledCustomSelect = () => { ); return ( - { setValue( nextValue ); @@ -55,11 +55,11 @@ const ControlledCustomSelect = () => { value={ value } > { [ 'blue', 'purple', 'pink' ].map( ( option ) => ( - + { renderControlledValue( option ) } - + ) ) } - + ); }; ``` @@ -70,23 +70,23 @@ Multiple selection can be enabled by using an array for the `value` and `defaultValue` props. The argument of the `onChange` function will also change accordingly. ```jsx -const MultiSelectCustomSelect = () => ( - +const MultiSelectCustomSelectControlV2 = () => ( + { [ 'blue', 'purple', 'pink' ].map( ( item ) => ( - + { item } - + ) ) } - + ); ``` ### Components and Sub-components -CustomSelect is comprised of two individual components: +CustomSelectControlV2 is comprised of two individual components: -- `CustomSelect`: a wrapper component and context provider. It is responsible for managing the state of the `CustomSelectItem` children. -- `CustomSelectItem`: renders a single select item. The first `CustomSelectItem` child will be used as the `defaultValue` when `defaultValue` is undefined. +- `CustomSelectControlV2`: a wrapper component and context provider. It is responsible for managing the state of the `CustomSelectControlV2.Item` children. +- `CustomSelectControlV2.Item`: renders a single select item. The first `CustomSelectControlV2.Item` child will be used as the `defaultValue` when `defaultValue` is undefined. #### Props @@ -94,7 +94,7 @@ The component accepts the following props: ##### `children`: `React.ReactNode` -The child elements. This should be composed of CustomSelect.Item components. +The child elements. This should be composed of CustomSelectControlV2.Item components. - Required: yes @@ -142,7 +142,7 @@ Can be used to externally control the value of the control. - Required: no -### `CustomSelectItem` +### `CustomSelectControlV2.Item` Used to render a select item. diff --git a/packages/components/src/custom-select-control-v2/default-component/index.tsx b/packages/components/src/custom-select-control-v2/default-component/index.tsx index e5650202a4160..d1a41d5156ea7 100644 --- a/packages/components/src/custom-select-control-v2/default-component/index.tsx +++ b/packages/components/src/custom-select-control-v2/default-component/index.tsx @@ -10,7 +10,7 @@ import _CustomSelect from '../custom-select'; import type { CustomSelectProps } from '../types'; import type { WordPressComponentProps } from '../../context'; -function CustomSelect( +function CustomSelectControlV2( props: WordPressComponentProps< CustomSelectProps, 'button', false > ) { const { defaultValue, onChange, value, ...restProps } = props; @@ -24,4 +24,4 @@ function CustomSelect( return <_CustomSelect { ...restProps } store={ store } />; } -export default CustomSelect; +export default CustomSelectControlV2; diff --git a/packages/components/src/custom-select-control-v2/index.tsx b/packages/components/src/custom-select-control-v2/index.tsx index f05191ad8fc0b..db273a83c4b91 100644 --- a/packages/components/src/custom-select-control-v2/index.tsx +++ b/packages/components/src/custom-select-control-v2/index.tsx @@ -1,5 +1,9 @@ /** * Internal dependencies */ -export { default as CustomSelect } from './default-component'; -export { default as CustomSelectItem } from './custom-select-item'; +import CustomSelect from './default-component'; +import Item from './item'; + +const CustomSelectControlV2 = Object.assign( CustomSelect, { Item } ); + +export default CustomSelectControlV2; diff --git a/packages/components/src/custom-select-control-v2/custom-select-item.tsx b/packages/components/src/custom-select-control-v2/item.tsx similarity index 93% rename from packages/components/src/custom-select-control-v2/custom-select-item.tsx rename to packages/components/src/custom-select-control-v2/item.tsx index b3e8cfeb1363e..bd60f974cc43a 100644 --- a/packages/components/src/custom-select-control-v2/custom-select-item.tsx +++ b/packages/components/src/custom-select-control-v2/item.tsx @@ -26,4 +26,6 @@ export function CustomSelectItem( { ); } +CustomSelectItem.displayName = 'CustomSelectControlV2.Item'; + export default CustomSelectItem; diff --git a/packages/components/src/custom-select-control-v2/legacy-component/index.tsx b/packages/components/src/custom-select-control-v2/legacy-component/index.tsx index 49c640581c377..76de170ee179e 100644 --- a/packages/components/src/custom-select-control-v2/legacy-component/index.tsx +++ b/packages/components/src/custom-select-control-v2/legacy-component/index.tsx @@ -11,12 +11,12 @@ import { useMemo } from '@wordpress/element'; * Internal dependencies */ import _CustomSelect from '../custom-select'; +import CustomSelectItem from '../item'; import type { LegacyCustomSelectProps } from '../types'; -import { CustomSelectItem } from '..'; import * as Styled from '../styles'; import { ContextSystemProvider } from '../../context'; -function CustomSelect( props: LegacyCustomSelectProps ) { +function CustomSelectControl( props: LegacyCustomSelectProps ) { const { __experimentalShowSelectedHint, __next40pxDefaultSize = false, @@ -130,4 +130,4 @@ function CustomSelect( props: LegacyCustomSelectProps ) { ); } -export default CustomSelect; +export default CustomSelectControl; diff --git a/packages/components/src/custom-select-control-v2/stories/default.story.tsx b/packages/components/src/custom-select-control-v2/stories/default.story.tsx index ee7dba0694c27..ac2f9a51d5951 100644 --- a/packages/components/src/custom-select-control-v2/stories/default.story.tsx +++ b/packages/components/src/custom-select-control-v2/stories/default.story.tsx @@ -11,15 +11,14 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import CustomSelect from '../default-component'; -import { CustomSelectItem } from '..'; +import CustomSelectControlV2 from '..'; -const meta: Meta< typeof CustomSelect > = { +const meta: Meta< typeof CustomSelectControlV2 > = { title: 'Components (Experimental)/CustomSelectControl v2/Default', - component: CustomSelect, + component: CustomSelectControlV2, subcomponents: { // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - CustomSelectItem, + 'CustomSelectControlV2.Item': CustomSelectControlV2.Item, }, argTypes: { children: { control: { type: null } }, @@ -48,10 +47,10 @@ const meta: Meta< typeof CustomSelect > = { }; export default meta; -const Template: StoryFn< typeof CustomSelect > = ( props ) => { +const Template: StoryFn< typeof CustomSelectControlV2 > = ( props ) => { const [ value, setValue ] = useState< string | string[] >(); return ( - { setValue( nextValue ); @@ -68,15 +67,15 @@ Default.args = { defaultValue: 'Select a color...', children: ( <> - + Blue - - + + Purple - - + + Pink - + ), }; @@ -100,9 +99,9 @@ MultipleSelection.args = { 'maroon', 'tangerine', ].map( ( item ) => ( - + { item } - + ) ) } ), @@ -134,9 +133,9 @@ CustomSelectedValue.args = { <> { [ 'mystery-person', 'identicon', 'wavatar', 'retro' ].map( ( option ) => ( - + { renderItem( option ) } - + ) ) } diff --git a/packages/components/src/custom-select-control-v2/stories/legacy.story.tsx b/packages/components/src/custom-select-control-v2/stories/legacy.story.tsx index f97b2376e9deb..bb721f2521c26 100644 --- a/packages/components/src/custom-select-control-v2/stories/legacy.story.tsx +++ b/packages/components/src/custom-select-control-v2/stories/legacy.story.tsx @@ -11,11 +11,11 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import CustomSelect from '../legacy-component'; +import CustomSelectControl from '../legacy-component'; -const meta: Meta< typeof CustomSelect > = { +const meta: Meta< typeof CustomSelectControl > = { title: 'Components (Experimental)/CustomSelectControl v2/Legacy', - component: CustomSelect, + component: CustomSelectControl, argTypes: { onChange: { control: { type: null } }, value: { control: { type: null } }, @@ -42,18 +42,22 @@ const meta: Meta< typeof CustomSelect > = { }; export default meta; -const Template: StoryFn< typeof CustomSelect > = ( props ) => { +const Template: StoryFn< typeof CustomSelectControl > = ( props ) => { const [ fontSize, setFontSize ] = useState( props.options[ 0 ] ); const onChange: React.ComponentProps< - typeof CustomSelect + typeof CustomSelectControl >[ 'onChange' ] = ( changeObject ) => { setFontSize( changeObject.selectedItem ); props.onChange?.( changeObject ); }; return ( - + ); }; diff --git a/packages/components/src/custom-select-control-v2/test/index.tsx b/packages/components/src/custom-select-control-v2/test/index.tsx index 52097e4f8bc5b..353660d0b4cf1 100644 --- a/packages/components/src/custom-select-control-v2/test/index.tsx +++ b/packages/components/src/custom-select-control-v2/test/index.tsx @@ -12,7 +12,7 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import { CustomSelect as UncontrolledCustomSelect, CustomSelectItem } from '..'; +import UncontrolledCustomSelectControl from '..'; import type { CustomSelectProps } from '../types'; const items = [ @@ -41,14 +41,14 @@ const items = [ const defaultProps = { label: 'label!', children: items.map( ( { value, key } ) => ( - + ) ), }; -const ControlledCustomSelect = ( props: CustomSelectProps ) => { +const ControlledCustomSelectControl = ( props: CustomSelectProps ) => { const [ value, setValue ] = useState< string | string[] >(); return ( - { setValue( nextValue ); @@ -60,8 +60,8 @@ const ControlledCustomSelect = ( props: CustomSelectProps ) => { }; describe.each( [ - [ 'Uncontrolled', UncontrolledCustomSelect ], - [ 'Controlled', ControlledCustomSelect ], + [ 'Uncontrolled', UncontrolledCustomSelectControl ], + [ 'Controlled', ControlledCustomSelectControl ], ] )( 'CustomSelectControlV2 (%s)', ( ...modeAndComponent ) => { const [ , Component ] = modeAndComponent; @@ -257,9 +257,12 @@ describe.each( [ 'rose blush', 'ultraviolet morning light', ].map( ( item ) => ( - + { item } - + ) ) } ); @@ -326,9 +329,12 @@ describe.each( [ render( { defaultValues.map( ( item ) => ( - + { item } - + ) ) } ); @@ -378,12 +384,12 @@ describe.each( [ render( - + { renderValue( 'april-29' ) } - - + + { renderValue( 'july-9' ) } - + ); From a64759cf70536cac9b60b7b7d784e59f7e66b333 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Tue, 26 Mar 2024 02:03:47 +0900 Subject: [PATCH 2/5] Add changelog --- packages/components/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 68368efca525b..b28279670a86d 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -6,6 +6,10 @@ - `InputControl`: Ignore IME events when `isPressEnterToChange` is enabled ([#60090](https://github.com/WordPress/gutenberg/pull/60090)). +### Experimental + +- `CustomSelectControlV2`: Rename for consistency ([#60178](https://github.com/WordPress/gutenberg/pull/60178)). + ### Internal - `Popover`, `ColorPicker`: Obviate pointer event trap #59449 ([#59449](https://github.com/WordPress/gutenberg/pull/59449)). From bf056b68756f3a24a97b26b63e66cbdd9e7e8f9a Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Wed, 27 Mar 2024 06:14:40 +0900 Subject: [PATCH 3/5] Improve naming consistency in tests --- .../legacy-component/test/index.tsx | 12 +++++----- .../custom-select-control-v2/test/index.tsx | 24 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/components/src/custom-select-control-v2/legacy-component/test/index.tsx b/packages/components/src/custom-select-control-v2/legacy-component/test/index.tsx index 906bf1cde0290..5fd66ac1112b7 100644 --- a/packages/components/src/custom-select-control-v2/legacy-component/test/index.tsx +++ b/packages/components/src/custom-select-control-v2/legacy-component/test/index.tsx @@ -12,7 +12,7 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import UncontrolledCustomSelect from '..'; +import UncontrolledCustomSelectControl from '..'; const customClass = 'amber-skies'; @@ -48,14 +48,14 @@ const legacyProps = { ], }; -const LegacyControlledCustomSelect = ( { +const ControlledCustomSelectControl = ( { options, onChange, ...restProps -}: React.ComponentProps< typeof UncontrolledCustomSelect > ) => { +}: React.ComponentProps< typeof UncontrolledCustomSelectControl > ) => { const [ value, setValue ] = useState( options[ 0 ] ); return ( - { @@ -70,8 +70,8 @@ const LegacyControlledCustomSelect = ( { }; describe.each( [ - [ 'Uncontrolled', UncontrolledCustomSelect ], - [ 'Controlled', LegacyControlledCustomSelect ], + [ 'Uncontrolled', UncontrolledCustomSelectControl ], + [ 'Controlled', ControlledCustomSelectControl ], ] )( 'CustomSelectControl (%s)', ( ...modeAndComponent ) => { const [ , Component ] = modeAndComponent; diff --git a/packages/components/src/custom-select-control-v2/test/index.tsx b/packages/components/src/custom-select-control-v2/test/index.tsx index 353660d0b4cf1..13421479c0dd5 100644 --- a/packages/components/src/custom-select-control-v2/test/index.tsx +++ b/packages/components/src/custom-select-control-v2/test/index.tsx @@ -12,7 +12,7 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import UncontrolledCustomSelectControl from '..'; +import UncontrolledCustomSelectControlV2 from '..'; import type { CustomSelectProps } from '../types'; const items = [ @@ -41,14 +41,14 @@ const items = [ const defaultProps = { label: 'label!', children: items.map( ( { value, key } ) => ( - + ) ), }; const ControlledCustomSelectControl = ( props: CustomSelectProps ) => { const [ value, setValue ] = useState< string | string[] >(); return ( - { setValue( nextValue ); @@ -60,7 +60,7 @@ const ControlledCustomSelectControl = ( props: CustomSelectProps ) => { }; describe.each( [ - [ 'Uncontrolled', UncontrolledCustomSelectControl ], + [ 'Uncontrolled', UncontrolledCustomSelectControlV2 ], [ 'Controlled', ControlledCustomSelectControl ], ] )( 'CustomSelectControlV2 (%s)', ( ...modeAndComponent ) => { const [ , Component ] = modeAndComponent; @@ -257,12 +257,12 @@ describe.each( [ 'rose blush', 'ultraviolet morning light', ].map( ( item ) => ( - { item } - + ) ) } ); @@ -329,12 +329,12 @@ describe.each( [ render( { defaultValues.map( ( item ) => ( - { item } - + ) ) } ); @@ -384,12 +384,12 @@ describe.each( [ render( - + { renderValue( 'april-29' ) } - - + + { renderValue( 'july-9' ) } - + ); From 7b678d4097ffff5824d6c8b2bf78205ed8ac64fe Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Wed, 27 Mar 2024 06:15:26 +0900 Subject: [PATCH 4/5] Simply subcomponent composition and exports --- .../custom-select-control-v2/default-component/index.tsx | 3 +++ packages/components/src/custom-select-control-v2/index.tsx | 7 +------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/components/src/custom-select-control-v2/default-component/index.tsx b/packages/components/src/custom-select-control-v2/default-component/index.tsx index d1a41d5156ea7..e9a2a9d8f5918 100644 --- a/packages/components/src/custom-select-control-v2/default-component/index.tsx +++ b/packages/components/src/custom-select-control-v2/default-component/index.tsx @@ -9,6 +9,7 @@ import * as Ariakit from '@ariakit/react'; import _CustomSelect from '../custom-select'; import type { CustomSelectProps } from '../types'; import type { WordPressComponentProps } from '../../context'; +import Item from '../item'; function CustomSelectControlV2( props: WordPressComponentProps< CustomSelectProps, 'button', false > @@ -24,4 +25,6 @@ function CustomSelectControlV2( return <_CustomSelect { ...restProps } store={ store } />; } +CustomSelectControlV2.Item = Item; + export default CustomSelectControlV2; diff --git a/packages/components/src/custom-select-control-v2/index.tsx b/packages/components/src/custom-select-control-v2/index.tsx index db273a83c4b91..f07e8f6f9f311 100644 --- a/packages/components/src/custom-select-control-v2/index.tsx +++ b/packages/components/src/custom-select-control-v2/index.tsx @@ -1,9 +1,4 @@ /** * Internal dependencies */ -import CustomSelect from './default-component'; -import Item from './item'; - -const CustomSelectControlV2 = Object.assign( CustomSelect, { Item } ); - -export default CustomSelectControlV2; +export { default } from './default-component'; From 75cbc0d22ab427434ef5e1b95450ccbef6d0795a Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Wed, 27 Mar 2024 06:35:18 +0900 Subject: [PATCH 5/5] Apply suggestions to readme Co-authored-by: Marin Atanasov <8436925+tyxla@users.noreply.github.com> --- .../components/src/custom-select-control-v2/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/components/src/custom-select-control-v2/README.md b/packages/components/src/custom-select-control-v2/README.md index 488194c067b5c..e44801681128b 100644 --- a/packages/components/src/custom-select-control-v2/README.md +++ b/packages/components/src/custom-select-control-v2/README.md @@ -12,7 +12,7 @@ Used to render a customizable select control component. #### Uncontrolled Mode -CustomSelectControlV2 can be used in an uncontrolled mode, where the component manages its own state. In this mode, the `defaultValue` prop can be used to set the initial selected value. If this prop is not set, the first value from the children will be selected by default. +`CustomSelectControlV2` can be used in an uncontrolled mode, where the component manages its own state. In this mode, the `defaultValue` prop can be used to set the initial selected value. If this prop is not set, the first value from the children will be selected by default. ```jsx const UncontrolledCustomSelectControlV2 = () => ( @@ -33,7 +33,7 @@ const UncontrolledCustomSelectControlV2 = () => ( #### Controlled Mode -CustomSelectControlV2 can also be used in a controlled mode, where the parent component specifies the `value` and the `onChange` props to control selection. +`CustomSelectControlV2` can also be used in a controlled mode, where the parent component specifies the `value` and the `onChange` props to control selection. ```jsx const ControlledCustomSelectControlV2 = () => { @@ -83,7 +83,7 @@ const MultiSelectCustomSelectControlV2 = () => ( ### Components and Sub-components -CustomSelectControlV2 is comprised of two individual components: +`CustomSelectControlV2` is comprised of two individual components: - `CustomSelectControlV2`: a wrapper component and context provider. It is responsible for managing the state of the `CustomSelectControlV2.Item` children. - `CustomSelectControlV2.Item`: renders a single select item. The first `CustomSelectControlV2.Item` child will be used as the `defaultValue` when `defaultValue` is undefined. @@ -94,7 +94,7 @@ The component accepts the following props: ##### `children`: `React.ReactNode` -The child elements. This should be composed of CustomSelectControlV2.Item components. +The child elements. This should be composed of `CustomSelectControlV2.Item` components. - Required: yes