-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
CustomSelectControlV2: Use InputBase
for styling
#60261
Changes from 4 commits
55f5b1f
b24f0f1
46eeb44
a45ee08
5c58d6c
106f28a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,23 +3,20 @@ | |
*/ | ||
// eslint-disable-next-line no-restricted-imports | ||
import * as Ariakit from '@ariakit/react'; | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useMemo } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import _CustomSelect from '../custom-select'; | ||
import CustomSelectItem from '../item'; | ||
import type { LegacyCustomSelectProps } from '../types'; | ||
import * as Styled from '../styles'; | ||
import { ContextSystemProvider } from '../../context'; | ||
|
||
function CustomSelectControl( props: LegacyCustomSelectProps ) { | ||
const { | ||
__experimentalShowSelectedHint, | ||
__next40pxDefaultSize = false, | ||
describedBy, | ||
options, | ||
onChange, | ||
size = 'default', | ||
|
@@ -94,39 +91,33 @@ function CustomSelectControl( props: LegacyCustomSelectProps ) { | |
); | ||
}; | ||
|
||
// translate legacy button sizing | ||
const contextSystemValue = useMemo( () => { | ||
let selectedSize; | ||
|
||
const translatedSize = ( () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a good reason for the IIFE here? Can be a simple There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To me, this takes the least cognitive load to read because it doesn't introduce a mutable variable ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Primitive values cannot be mutated, so we're technically not really mutating anything. Also, the IIFE makes the code a bit more complex to read than if we were using a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Touché, I should've said reassignment! I always considered variable reassignment to be a form of mutation (as in mutable state), but I guess those two terms should be differentiated in JS at least. |
||
if ( | ||
( __next40pxDefaultSize && size === 'default' ) || | ||
size === '__unstable-large' | ||
) { | ||
selectedSize = 'default'; | ||
} else if ( ! __next40pxDefaultSize && size === 'default' ) { | ||
selectedSize = 'compact'; | ||
} else { | ||
selectedSize = size; | ||
return 'default'; | ||
} | ||
|
||
return { | ||
CustomSelectControlButton: { _overrides: { size: selectedSize } }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No more need to tunnel this via context system, because we can directly set the newly exposed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see 👍🏻 (regarding https://github.com/WordPress/gutenberg/pull/60261/files#r1616307373). |
||
}; | ||
}, [ __next40pxDefaultSize, size ] ); | ||
|
||
const translatedProps = { | ||
'aria-describedby': props.describedBy, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
children, | ||
renderSelectedValue: __experimentalShowSelectedHint | ||
? renderSelectedValueHint | ||
: undefined, | ||
...restProps, | ||
}; | ||
Comment on lines
-117
to
-124
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I replaced this with direct prop assignments on the |
||
if ( ! __next40pxDefaultSize && size === 'default' ) { | ||
return 'compact'; | ||
} | ||
return size; | ||
} )(); | ||
|
||
return ( | ||
<ContextSystemProvider value={ contextSystemValue }> | ||
<_CustomSelect { ...translatedProps } store={ store } /> | ||
</ContextSystemProvider> | ||
<_CustomSelect | ||
aria-describedby={ describedBy } | ||
renderSelectedValue={ | ||
__experimentalShowSelectedHint | ||
? renderSelectedValueHint | ||
: undefined | ||
} | ||
size={ translatedSize } | ||
store={ store } | ||
{ ...restProps } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we intentionally allow the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Everything that can't be merged should be overridable, as per the open/closed pattern. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also No strong opinion, but I think the general strategy of "keep everything overridable unless there is a specific, strong reason not to" would be fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be much better if JS supported |
||
> | ||
{ children } | ||
</_CustomSelect> | ||
); | ||
} | ||
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I refactored some of these types because the rejiggering work I did in this PR surfaced some mistakes in how we were using them. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,19 @@ export type CustomSelectStore = { | |
|
||
export type CustomSelectContext = CustomSelectStore | undefined; | ||
|
||
type CustomSelectSize< Size = 'compact' | 'default' > = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For context, the public interface of |
||
/** | ||
* The size of the control. | ||
* | ||
* @default 'default' | ||
*/ | ||
size?: Size; | ||
}; | ||
|
||
export type CustomSelectButtonSize = CustomSelectSize< | ||
'compact' | 'default' | 'small' | ||
>; | ||
|
||
export type CustomSelectButtonProps = { | ||
/** | ||
* An optional default value for the control when used in uncontrolled mode. | ||
|
@@ -30,19 +43,13 @@ export type CustomSelectButtonProps = { | |
renderSelectedValue?: ( | ||
selectedValue: string | string[] | ||
) => React.ReactNode; | ||
/** | ||
* The size of the control. | ||
* | ||
* @default 'default' | ||
*/ | ||
size?: 'compact' | 'default' | 'small'; | ||
/** | ||
* The value of the control when used in uncontrolled mode. | ||
*/ | ||
value?: string | string[]; | ||
}; | ||
|
||
export type _CustomSelectProps = { | ||
export type _CustomSelectProps = CustomSelectButtonProps & { | ||
/** | ||
* The child elements. This should be composed of `CustomSelectItem` components. | ||
*/ | ||
|
@@ -60,14 +67,8 @@ export type _CustomSelectProps = { | |
}; | ||
|
||
export type CustomSelectProps = _CustomSelectProps & | ||
Omit< CustomSelectButtonProps, 'size' > & { | ||
/** | ||
* The size of the control. | ||
* | ||
* @default 'default' | ||
*/ | ||
size?: Exclude< CustomSelectButtonProps[ 'size' ], 'small' >; | ||
}; | ||
CustomSelectButtonProps & | ||
CustomSelectSize; | ||
|
||
/** | ||
* The legacy object structure for the options array. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,7 +64,7 @@ function getUIFlexProps( labelPosition?: LabelPosition ) { | |
return props; | ||
} | ||
|
||
export function InputBase( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed this unused export, because a consumer can erroneously import this named version instead of the default export which is properly wrapped in a (This happened to me while working on this PR and it wasted a couple minutes of my life 😇) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, but, what is the current convention for components - should we provide both (named, default) or just one - and if so, it seems Another approach would be to connect before while assigning to a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. We do indeed have some conventions that are actually for accommodating our current docgen, more than anything else. Doesn't matter that much for internal components like |
||
function InputBase( | ||
props: WordPressComponentProps< InputBaseProps, 'div' >, | ||
ref: ForwardedRef< HTMLDivElement > | ||
) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to connect this to the context system anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind elaborating on why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, already seen #60261 (comment) 👍🏻