-
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.
CustomSelect: Adapt component for legacy props (#57902)
* Move components to own files * Add legacy adapter * Add legacy tests * Update naming and remove unnecessary tests * Add legacy props to adapter * Create new component to forward store * Create legacy component * Remove useDeprecatedProps hook and update adapter * Separate stories * Update stories and types * Convert function into variable instead * Update legacy changeObject to match existing properties * Add tests for onChange function * add rest of legacy props * Update sizing * Memoize selected render value * Remove deprecated prop to fix test failures * Add `unmountOnHide` and require `defaultValue` as a result See: ariakit/ariakit#3374 (comment) * Update styling for experimental hint * Connect CustomSelectButton to context system for legacy sizing * Update sizing logic and types * Fix styling to match legacy including hints * Clean up props * Omit ‘onChange’ from WordPressComponentProps to prevent conflict * Update checkmark icon * Update select arrow * Update types * Add static typing test * Update story for better manual testing * Control mount state for legacy keyboard behaviour * Remove export that is no longer needed * Update legacy onChange type * Update tests * Update naming * Try mounting on first render to avoid required defaultValue * Add WordPressComponentProps to default export * Update types * Replace RTL/userEvent with ariakit/test * Remove unmountOnHide and related logic for first iteration * Update docs * Update naming * Merge new tests and update to ariakit/test * Fix typo in readme * Legacy: Clean up stories * Default: Clean up stories * Add todo comment about BaseControl * Fix styles * Rename styled components for consistency * Fix typo in readme * Rename for clarity * Update changelog --------- Co-authored-by: brookewp <brookemk@git.wordpress.org> Co-authored-by: mirka <0mirka00@git.wordpress.org> Co-authored-by: ciampo <mciampini@git.wordpress.org> Co-authored-by: diegohaz <hazdiego@git.wordpress.org>
- Loading branch information
1 parent
19622fa
commit 5939c41
Showing
13 changed files
with
1,568 additions
and
347 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
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
29 changes: 29 additions & 0 deletions
29
packages/components/src/custom-select-control-v2/custom-select-item.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,29 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useContext } from '@wordpress/element'; | ||
import { Icon, check } from '@wordpress/icons'; | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { CustomSelectItemProps } from './types'; | ||
import type { WordPressComponentProps } from '../context'; | ||
import * as Styled from './styles'; | ||
import { CustomSelectContext } from './custom-select'; | ||
|
||
export function CustomSelectItem( { | ||
children, | ||
...props | ||
}: WordPressComponentProps< CustomSelectItemProps, 'div', false > ) { | ||
const customSelectContext = useContext( CustomSelectContext ); | ||
return ( | ||
<Styled.SelectItem store={ customSelectContext?.store } { ...props }> | ||
{ children ?? props.value } | ||
<Styled.SelectedItemCheck> | ||
<Icon icon={ check } /> | ||
</Styled.SelectedItemCheck> | ||
</Styled.SelectItem> | ||
); | ||
} | ||
|
||
export default CustomSelectItem; |
122 changes: 122 additions & 0 deletions
122
packages/components/src/custom-select-control-v2/custom-select.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,122 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { createContext, useMemo } from '@wordpress/element'; | ||
import { __, sprintf } from '@wordpress/i18n'; | ||
import { Icon, chevronDown } from '@wordpress/icons'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { VisuallyHidden } from '..'; | ||
import * as Styled from './styles'; | ||
import type { | ||
CustomSelectContext as CustomSelectContextType, | ||
CustomSelectStore, | ||
CustomSelectButtonProps, | ||
_CustomSelectProps, | ||
} from './types'; | ||
import { | ||
contextConnectWithoutRef, | ||
useContextSystem, | ||
type WordPressComponentProps, | ||
} from '../context'; | ||
|
||
export const CustomSelectContext = | ||
createContext< CustomSelectContextType >( undefined ); | ||
|
||
function defaultRenderSelectedValue( | ||
value: CustomSelectButtonProps[ 'value' ] | ||
) { | ||
const isValueEmpty = Array.isArray( value ) | ||
? value.length === 0 | ||
: value === undefined || value === null; | ||
|
||
if ( isValueEmpty ) { | ||
return __( 'Select an item' ); | ||
} | ||
|
||
if ( Array.isArray( value ) ) { | ||
return value.length === 1 | ||
? value[ 0 ] | ||
: // translators: %s: number of items selected (it will always be 2 or more items) | ||
sprintf( __( '%s items selected' ), value.length ); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
const UnconnectedCustomSelectButton = ( | ||
props: Omit< | ||
WordPressComponentProps< | ||
CustomSelectButtonProps & CustomSelectStore, | ||
'button', | ||
false | ||
>, | ||
'onChange' | ||
> | ||
) => { | ||
const { | ||
renderSelectedValue, | ||
size = 'default', | ||
store, | ||
...restProps | ||
} = useContextSystem( props, 'CustomSelectControlButton' ); | ||
|
||
const { value: currentValue } = store.useState(); | ||
|
||
const computedRenderSelectedValue = useMemo( | ||
() => renderSelectedValue ?? defaultRenderSelectedValue, | ||
[ renderSelectedValue ] | ||
); | ||
|
||
return ( | ||
<Styled.Select | ||
{ ...restProps } | ||
size={ size } | ||
hasCustomRenderProp={ !! renderSelectedValue } | ||
store={ store } | ||
// to match legacy behavior where using arrow keys | ||
// move selection rather than open the popover | ||
showOnKeyDown={ false } | ||
> | ||
<div>{ computedRenderSelectedValue( currentValue ) }</div> | ||
<Icon icon={ chevronDown } size={ 18 } /> | ||
</Styled.Select> | ||
); | ||
}; | ||
|
||
const CustomSelectButton = contextConnectWithoutRef( | ||
UnconnectedCustomSelectButton, | ||
'CustomSelectControlButton' | ||
); | ||
|
||
function _CustomSelect( props: _CustomSelectProps & CustomSelectStore ) { | ||
const { | ||
children, | ||
hideLabelFromVision = false, | ||
label, | ||
store, | ||
...restProps | ||
} = props; | ||
|
||
return ( | ||
<> | ||
{ hideLabelFromVision ? ( // TODO: Replace with BaseControl | ||
<VisuallyHidden as="label">{ label }</VisuallyHidden> | ||
) : ( | ||
<Styled.SelectLabel store={ store }> | ||
{ label } | ||
</Styled.SelectLabel> | ||
) } | ||
<CustomSelectButton { ...restProps } store={ store } /> | ||
<Styled.SelectPopover gutter={ 12 } store={ store } sameWidth> | ||
<CustomSelectContext.Provider value={ { store } }> | ||
{ children } | ||
</CustomSelectContext.Provider> | ||
</Styled.SelectPopover> | ||
</> | ||
); | ||
} | ||
|
||
export default _CustomSelect; |
24 changes: 24 additions & 0 deletions
24
packages/components/src/custom-select-control-v2/default-component/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,24 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
// eslint-disable-next-line no-restricted-imports | ||
import * as Ariakit from '@ariakit/react'; | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import _CustomSelect from '../custom-select'; | ||
import type { CustomSelectProps } from '../types'; | ||
|
||
function CustomSelect( props: CustomSelectProps ) { | ||
const { defaultValue, onChange, value, ...restProps } = props; | ||
// Forward props + store from v2 implementation | ||
const store = Ariakit.useSelectStore( { | ||
setValue: ( nextValue ) => onChange?.( nextValue ), | ||
defaultValue, | ||
value, | ||
} ); | ||
|
||
return <_CustomSelect { ...restProps } store={ store } />; | ||
} | ||
|
||
export default CustomSelect; |
Oops, something went wrong.