-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial version of new CustomSelectControl
- Loading branch information
Showing
13 changed files
with
434 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
...s/components/src/custom-select-control-new/custom-select-control-item/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# CustomSelectControlItem | ||
|
||
TODO |
32 changes: 32 additions & 0 deletions
32
packages/components/src/custom-select-control-new/custom-select-control-item/component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import type { ForwardedRef } from 'react'; | ||
import { SelectItem } from 'ariakit/select'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { forwardRef } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { useSelectControlItem } from './hook'; | ||
import { WordPressComponentProps } from '../../ui/context'; | ||
import type { SelectControlItemProps } from '../types'; | ||
|
||
const UnforwardedSelectControlItem = ( | ||
props: WordPressComponentProps< SelectControlItemProps, 'div', false >, | ||
forwardedRef: ForwardedRef< any > | ||
) => { | ||
const allProps = useSelectControlItem( props ); | ||
|
||
// TODO: investigate incompatibility with the "as" prop. | ||
return <SelectItem { ...allProps } ref={ forwardedRef } />; | ||
}; | ||
|
||
// TODO: JSDocs | ||
export const SelectControlItem = forwardRef( UnforwardedSelectControlItem ); | ||
|
||
export default SelectControlItem; |
31 changes: 31 additions & 0 deletions
31
packages/components/src/custom-select-control-new/custom-select-control-item/hook.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useMemo } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import * as styles from '../styles'; | ||
import type { WordPressComponentProps } from '../../ui/context'; | ||
import { useCx } from '../../utils/hooks/use-cx'; | ||
import { SelectControlItemProps } from '../types'; | ||
|
||
// TODO: | ||
// - should we use 'option' instead of `div` for props inheritance? | ||
// - should we allow polymorphism ? | ||
export const useSelectControlItem = ( { | ||
className, | ||
...props | ||
}: WordPressComponentProps< SelectControlItemProps, 'div', false > ) => { | ||
const cx = useCx(); | ||
const itemClassName = useMemo( | ||
() => cx( styles.item, className ), | ||
[ className, cx ] | ||
); | ||
|
||
return { | ||
...props, | ||
className: itemClassName, | ||
}; | ||
}; |
2 changes: 2 additions & 0 deletions
2
packages/components/src/custom-select-control-new/custom-select-control-item/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default } from './component'; | ||
export { useSelectControlItem } from './hook'; |
3 changes: 3 additions & 0 deletions
3
packages/components/src/custom-select-control-new/custom-select-control/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# CustomSelectControl | ||
|
||
TODO |
94 changes: 94 additions & 0 deletions
94
packages/components/src/custom-select-control-new/custom-select-control/component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import type { ForwardedRef } from 'react'; | ||
import { | ||
Select, | ||
SelectLabel, | ||
SelectPopover, | ||
SelectArrow, | ||
} from 'ariakit/select'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { forwardRef } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
|
||
import { useSelectControl } from './hook'; | ||
import { WordPressComponentProps } from '../../ui/context'; | ||
import { CustomSelectControlItem } from '../'; | ||
import type { SelectControlOption, SelectControlProps } from '../types'; | ||
|
||
const SelectControlCustomSelectLabel = ( { | ||
options, | ||
value, | ||
}: { | ||
options: SelectControlOption[]; | ||
value?: string; | ||
} ) => ( | ||
<> | ||
{ /* Use the label associated to the option's value, fallback to the value itself */ } | ||
{ options.find( ( option ) => option.value === value )?.label ?? value } | ||
<SelectArrow /> | ||
</> | ||
); | ||
|
||
const UnforwardedSelectControl = ( | ||
props: WordPressComponentProps< SelectControlProps, 'select', false >, | ||
forwardedRef: ForwardedRef< any > | ||
) => { | ||
const { | ||
label, | ||
options, | ||
children, | ||
selectState, | ||
wrapperClassName, | ||
labelClassName, | ||
selectClassName, | ||
popoverClassName, | ||
} = useSelectControl( props ); | ||
|
||
return ( | ||
<div className={ wrapperClassName }> | ||
<SelectLabel state={ selectState } className={ labelClassName }> | ||
{ label } | ||
</SelectLabel> | ||
<Select state={ selectState } className={ selectClassName }> | ||
{ options?.length ? ( | ||
<SelectControlCustomSelectLabel | ||
options={ options } | ||
value={ selectState.value } | ||
/> | ||
) : ( | ||
selectState.value | ||
) } | ||
</Select> | ||
<SelectPopover state={ selectState } className={ popoverClassName }> | ||
{ children ?? | ||
options?.map( ( option, index ) => { | ||
const key = | ||
option.id || | ||
`${ option.label }-${ option.value }-${ index }`; | ||
return ( | ||
<CustomSelectControlItem | ||
key={ key } | ||
value={ option.value } | ||
disabled={ option.disabled } | ||
> | ||
{ option.label } | ||
</CustomSelectControlItem> | ||
); | ||
} ) } | ||
</SelectPopover> | ||
</div> | ||
); | ||
}; | ||
|
||
// TODO: JSDocs | ||
export const SelectControl = forwardRef( UnforwardedSelectControl ); | ||
|
||
export default SelectControl; |
64 changes: 64 additions & 0 deletions
64
packages/components/src/custom-select-control-new/custom-select-control/hook.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { useSelectState } from 'ariakit/select'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useMemo } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import * as styles from '../styles'; | ||
import type { WordPressComponentProps } from '../../ui/context'; | ||
import { useCx } from '../../utils/hooks/use-cx'; | ||
import { SelectControlProps } from '../types'; | ||
|
||
// TODO: | ||
// - should we use 'select' instead of `div` for props inheritance? | ||
// - should we allow polymorphism ? | ||
export const useSelectControl = ( { | ||
value, | ||
className, | ||
...props | ||
}: WordPressComponentProps< SelectControlProps, 'select', false > ) => { | ||
// TODO: take some of these settings as props? | ||
const selectState = useSelectState( { | ||
// TODO: check if it works, understand if we should expose | ||
// a different prop for the initial value? | ||
defaultValue: value, | ||
sameWidth: true, | ||
gutter: 4, | ||
} ); | ||
|
||
// TODO: deprecate options prop | ||
|
||
const cx = useCx(); | ||
const wrapperClassName = useMemo( | ||
() => cx( styles.wrapper, className ), | ||
[ className, cx ] | ||
); | ||
const labelClassName = useMemo( | ||
() => cx( styles.label, className ), | ||
[ className, cx ] | ||
); | ||
const selectClassName = useMemo( | ||
() => cx( styles.select, className ), | ||
[ className, cx ] | ||
); | ||
const popoverClassName = useMemo( | ||
() => cx( styles.popover, className ), | ||
[ className, cx ] | ||
); | ||
|
||
return { | ||
...props, | ||
selectState, | ||
wrapperClassName, | ||
labelClassName, | ||
selectClassName, | ||
popoverClassName, | ||
}; | ||
}; |
2 changes: 2 additions & 0 deletions
2
packages/components/src/custom-select-control-new/custom-select-control/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default } from './component'; | ||
export { useSelectControl } from './hook'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default as CustomSelectControl } from './custom-select-control'; | ||
export { default as CustomSelectControlItem } from './custom-select-control-item'; |
58 changes: 58 additions & 0 deletions
58
packages/components/src/custom-select-control-new/stories/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import type { ComponentMeta, ComponentStory } from '@storybook/react'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
// import { useState } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { CustomSelectControl, CustomSelectControlItem } from '../'; | ||
|
||
const meta: ComponentMeta< typeof CustomSelectControl > = { | ||
component: CustomSelectControl, | ||
title: 'Components (Experimental)/CustomSelectControlNew', | ||
argTypes: {}, | ||
parameters: { | ||
controls: { | ||
expanded: true, | ||
}, | ||
docs: { source: { state: 'open' } }, | ||
}, | ||
}; | ||
export default meta; | ||
|
||
// TODO: | ||
// - with options prop | ||
// - controlled vs uncontrolled | ||
// - with HTML "options"? | ||
// - example with custom author dropdown | ||
|
||
const DefaultTemplate: ComponentStory< typeof CustomSelectControl > = ( { | ||
onChange, | ||
...args | ||
} ) => { | ||
// const [ value, setValue ] = useState< string | undefined >( '10px' ); | ||
|
||
return ( | ||
<CustomSelectControl { ...args }> | ||
<CustomSelectControlItem value="Venus" /> | ||
<CustomSelectControlItem value="Earth"> | ||
Planet Earth | ||
</CustomSelectControlItem> | ||
<CustomSelectControlItem value="Mars" /> | ||
<CustomSelectControlItem value="Jupiter" disabled /> | ||
<CustomSelectControlItem value="Neptune" /> | ||
</CustomSelectControl> | ||
); | ||
}; | ||
|
||
export const Default: ComponentStory< typeof CustomSelectControl > = | ||
DefaultTemplate.bind( {} ); | ||
Default.args = { | ||
label: 'With `CustomSelectControlItem` children', | ||
}; |
Oops, something went wrong.