diff --git a/packages/block-editor/src/hooks/position.jsx b/packages/block-editor/src/hooks/position.jsx index 8ff0a29fac193d..e69579bcc1cb4f 100644 --- a/packages/block-editor/src/hooks/position.jsx +++ b/packages/block-editor/src/hooks/position.jsx @@ -4,7 +4,6 @@ import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks'; import { useInstanceId } from '@wordpress/compose'; import { useSelect } from '@wordpress/data'; import { useMemo } from '@wordpress/element'; -// eslint-disable-next-line @wordpress/use-recommended-components -- Use the portal-based popup to avoid inspector clipping. import { SelectControl } from '@wordpress/ui'; import { useSettings } from '../components/use-settings'; import InspectorControls from '../components/inspector-controls'; diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 4d7723b519875c..647bdd2c6f39af 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -11,6 +11,7 @@ ### Enhancements +- `SelectControl`: Mark as not recommended for use in a WordPress environment, in favour of `SelectControl` from `@wordpress/ui` ([#83030](https://github.com/WordPress/gutenberg/pull/83030)). - `PaletteEdit`: Use standard menu semantics and keyboard navigation for palette option actions through `Menu` from `@wordpress/ui` ([#82768](https://github.com/WordPress/gutenberg/pull/82768)). - `CheckboxControl`: Match the `@wordpress/ui` checkmark size and disabled fill ([#82555](https://github.com/WordPress/gutenberg/pull/82555)). - `Snackbar`: Show the action's focus ring with the design system's outline instead of a legacy dotted outline, and let `Button`/`ExternalLink` own the ring ([#82640](https://github.com/WordPress/gutenberg/pull/82640)). diff --git a/packages/components/src/select-control/stories/index.story.tsx b/packages/components/src/select-control/stories/index.story.tsx index 88202ff6120955..476f42d076ef05 100644 --- a/packages/components/src/select-control/stories/index.story.tsx +++ b/packages/components/src/select-control/stories/index.story.tsx @@ -5,7 +5,6 @@ import SelectControl from '../'; import { InputControlPrefixWrapper } from '../../input-control/input-prefix-wrapper'; const meta: Meta< typeof SelectControl > = { - tags: [ 'manifest' ], title: 'Components/Selection & Input/Common/SelectControl', id: 'components-selectcontrol', component: SelectControl, @@ -23,9 +22,9 @@ const meta: Meta< typeof SelectControl > = { controls: { expanded: true }, docs: { canvas: { sourceState: 'shown' } }, componentStatus: { - status: 'recommended', + status: 'not-recommended', whereUsed: 'global', - notes: 'Will be superseded by [`SelectControl`](?path=/docs/design-system-components-form-selectcontrol--docs) in `@wordpress/ui`, but continue using for now.', + notes: 'Use [`SelectControl`](?path=/docs/design-system-components-form-selectcontrol--docs) from `@wordpress/ui` instead. For the `minimal` variant, use the [`Select`](?path=/docs/design-system-components-form-primitives-select--docs) primitive rather than `SelectControl`.', }, }, }; diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 1ea454c1c35630..3a6a2e8da5f863 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -8,6 +8,7 @@ ### Enhancements +- Update `use-recommended-components` rule to mark `Select` and `SelectControl` from `@wordpress/ui` as recommended ([#83030](https://github.com/WordPress/gutenberg/pull/83030)). - `recommended`: Apply the TypeScript rules and parser to `.mts` and `.cts` files ([#83071](https://github.com/WordPress/gutenberg/pull/83071)). - `recommended`: Resolve imports through `.mjs`, `.cjs`, `.mts` and `.cts`, and exempt `.d.mts` and `.d.cts` from the TypeScript resolver settings alongside `.d.ts` ([#83071](https://github.com/WordPress/gutenberg/pull/83071)). - `no-i18n-in-save`: Recognise the `.mjs`, `.cjs`, `.mts` and `.cts` spellings of `save` and `deprecated` ([#83071](https://github.com/WordPress/gutenberg/pull/83071)). diff --git a/packages/eslint-plugin/rules/use-recommended-components.js b/packages/eslint-plugin/rules/use-recommended-components.js index 268cbe729791b2..f151463ee7793a 100644 --- a/packages/eslint-plugin/rules/use-recommended-components.js +++ b/packages/eslint-plugin/rules/use-recommended-components.js @@ -36,6 +36,8 @@ const ALLOWLIST = { 'RangeCalendar', 'SearchableChipSelect', 'SearchableChipSelectControl', + 'Select', + 'SelectControl', 'Skeleton', 'Spinner', 'Stack', diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md index 91b7c9356d89b5..44d67fc82b6140 100644 --- a/packages/ui/CHANGELOG.md +++ b/packages/ui/CHANGELOG.md @@ -13,6 +13,7 @@ ### Enhancements +- `Select`, `SelectControl`: Mark as recommended for use in a WordPress environment ([#83030](https://github.com/WordPress/gutenberg/pull/83030)). - `Select`, `SelectControl`: Add `ItemLabel` and `ItemDescription` subcomponents. Multiple descriptions contribute to `aria-describedby` in DOM order. `SelectControl` `items` may include an optional `description` string. ([#82369](https://github.com/WordPress/gutenberg/pull/82369)) - `Select`, `SelectControl`: Align the selected item with the trigger by default, and drop the popup max-height cap when that alignment is enabled ([#82043](https://github.com/WordPress/gutenberg/pull/82043)). - `Select`, `Combobox`, `Autocomplete`: Allow browsing read-only controls while keeping their value unchanged ([#82835](https://github.com/WordPress/gutenberg/pull/82835)). diff --git a/packages/ui/src/form/primitives/select/root.tsx b/packages/ui/src/form/primitives/select/root.tsx index 058d68153ed629..6cb13b6320740f 100644 --- a/packages/ui/src/form/primitives/select/root.tsx +++ b/packages/ui/src/form/primitives/select/root.tsx @@ -5,6 +5,8 @@ import { DirectionProvider } from '../../../utils/direction-provider'; /** * A component that lets users choose one option from a list. * + * Prefer `SelectControl` when using with a standard label and description. + * * When using object values, pass an `items` array so `Select.Trigger` can * auto-resolve the selected item's label. By default, items should use a * `{ value, label }` shape, or provide `itemToStringLabel` for a custom shape. diff --git a/packages/ui/src/form/primitives/select/stories/index.story.tsx b/packages/ui/src/form/primitives/select/stories/index.story.tsx index 5b61baf8c0ccf7..e6895ae78c9d42 100644 --- a/packages/ui/src/form/primitives/select/stories/index.story.tsx +++ b/packages/ui/src/form/primitives/select/stories/index.story.tsx @@ -2,8 +2,14 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import * as Select from '../'; const meta: Meta< typeof Select.Root > = { + tags: [ 'manifest' ], title: 'Design System/Components/Form/Primitives/Select', component: Select.Root, + // Temporary: Due to an upstream bug, render the root explicitly so the + // components manifest extractor can resolve props from the JSX. + // + // See: https://github.com/storybookjs/storybook/issues/34877 + render: ( args ) => , subcomponents: { 'Select.Trigger': Select.Trigger, 'Select.Portal': Select.Portal, @@ -17,9 +23,8 @@ const meta: Meta< typeof Select.Root > = { }, parameters: { componentStatus: { - status: 'use-with-caution', + status: 'recommended', whereUsed: 'global', - notes: 'Not yet recommended for use alongside components from `@wordpress/components`, pending review of style consistency with `@wordpress/components`, overlays compatibility, and component set completeness. See [WordPress/gutenberg#76135](https://github.com/WordPress/gutenberg/issues/76135).', }, }, }; diff --git a/packages/ui/src/form/select-control/stories/index.story.tsx b/packages/ui/src/form/select-control/stories/index.story.tsx index 8a6a43b19b5f47..60ec9e3b1f956e 100644 --- a/packages/ui/src/form/select-control/stories/index.story.tsx +++ b/packages/ui/src/form/select-control/stories/index.story.tsx @@ -8,8 +8,14 @@ import { } from '../../stories/shared'; const meta: Meta< typeof SelectControl > = { + tags: [ 'manifest' ], title: 'Design System/Components/Form/SelectControl', component: SelectControl, + // Temporary: Due to an upstream bug, render the root explicitly so the + // components manifest extractor can resolve props from the JSX. + // + // See: https://github.com/storybookjs/storybook/issues/34877 + render: ( args ) => , subcomponents: { 'SelectControl.Group': SelectControl.Group, 'SelectControl.GroupLabel': SelectControl.GroupLabel, @@ -20,6 +26,12 @@ const meta: Meta< typeof SelectControl > = { argTypes: { onValueChange: { action: 'onValueChange' }, }, + parameters: { + componentStatus: { + status: 'recommended', + whereUsed: 'global', + }, + }, }; export default meta; diff --git a/storybook/components-manifest.yml b/storybook/components-manifest.yml index e10db8ca8f9bd3..d3a943932976b2 100644 --- a/storybook/components-manifest.yml +++ b/storybook/components-manifest.yml @@ -1272,26 +1272,182 @@ - placeholder - size - value +- name: Select.Root + props: + - actionsRef + - autoComplete + - children + - defaultOpen + - defaultValue + - disabled + - form + - highlightItemOnHover + - id + - inputRef + - isItemEqualToValue + - items + - itemToStringLabel + - itemToStringValue + - modal + - name + - onOpenChange + - onOpenChangeComplete + - onValueChange + - open + - readOnly + - required + - value + subcomponents: + - name: Select.Group + props: + - children + - className + - render + - style + - name: Select.GroupLabel + props: + - children + - className + - render + - style + - name: Select.Item + props: + - children + - className + - disabled + - label + - nativeButton + - render + - size + - style + - value + - name: Select.ItemDescription + props: + - children + - className + - render + - style + - name: Select.ItemLabel + props: + - children + - className + - render + - style + - name: Select.Popup + props: + - children + - className + - finalFocus + - portal + - positioner + - render + - style + - width + - name: Select.Portal + props: + - className + - container + - render + - style + - name: Select.Positioner + props: + - align + - alignItemWithTrigger + - alignOffset + - anchor + - arrowPadding + - className + - collisionAvoidance + - collisionBoundary + - collisionPadding + - disableAnchorTracking + - positionMethod + - render + - side + - sideOffset + - sticky + - style + - name: Select.Trigger + props: + - children + - className + - disabled + - nativeButton + - placeholder + - render + - size + - style + - variant - name: SelectControl props: - - __next36pxDefaultSize - - __next40pxDefaultSize - - __nextHasNoMarginBottom + - actionsRef + - autoComplete - children + - className + - defaultOpen + - defaultValue + - description + - details - disabled - - help + - form - hideLabelFromVision + - highlightItemOnHover + - id + - isItemEqualToValue + - items + - itemToStringLabel + - itemToStringValue + - key - label - - labelPosition - - multiple - - onChange - - options - - prefix + - modal + - name + - onOpenChange + - onOpenChangeComplete + - onValueChange + - open + - placeholder + - popupWidth + - readOnly - ref + - required - size - - suffix + - triggerContent - value - - variant + subcomponents: + - name: SelectControl.Group + props: + - children + - className + - render + - style + - name: SelectControl.GroupLabel + props: + - children + - className + - render + - style + - name: SelectControl.Item + props: + - children + - className + - disabled + - label + - nativeButton + - render + - style + - value + - name: SelectControl.ItemDescription + props: + - children + - className + - render + - style + - name: SelectControl.ItemLabel + props: + - children + - className + - render + - style - name: Shortcut props: - className diff --git a/storybook/prop-description-allowlist.json b/storybook/prop-description-allowlist.json index c3ea0e720b992b..0b72d525203acf 100644 --- a/storybook/prop-description-allowlist.json +++ b/storybook/prop-description-allowlist.json @@ -97,7 +97,17 @@ "SearchableChipSelectControl>SearchableChipSelectControl.GroupLabel:children", "SearchableChipSelectControl>SearchableChipSelectControl.Item", "SearchableChipSelectControl>SearchableChipSelectControl.Item:children", - "SelectControl:ref", + "Select.Root:children", + "Select.Root>Select.Group:children", + "Select.Root>Select.GroupLabel:children", + "Select.Root>Select.Item", + "Select.Root>Select.Popup", + "Select.Root>Select.Trigger", + "SelectControl:children", + "SelectControl:key", + "SelectControl>SelectControl.Group:children", + "SelectControl>SelectControl.GroupLabel:children", + "SelectControl>SelectControl.Item", "Slot>Fill", "Slot>SlotFillProvider", "ToggleControl:className",