From c8567d7d44f2f7f8cd8a05aba3a058477c23f349 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:05:28 +0200 Subject: [PATCH 01/39] Point legacy exports directly to the source (instead of folder root) --- packages/components/src/composite/index.ts | 3 --- packages/components/src/composite/legacy/index.tsx | 5 +++++ packages/components/src/index.ts | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts index aa06a6adf36ef2..f9ad4512ced67d 100644 --- a/packages/components/src/composite/index.ts +++ b/packages/components/src/composite/index.ts @@ -1,6 +1,3 @@ -// Originally this pointed at a Reakit implementation of -// `Composite`, but we are removing Reakit entirely from the -// codebase. We will continue to support the Reakit API // through the 'legacy' version, which uses Ariakit under // the hood. diff --git a/packages/components/src/composite/legacy/index.tsx b/packages/components/src/composite/legacy/index.tsx index 5c5c674b5086b8..2d237956f246f3 100644 --- a/packages/components/src/composite/legacy/index.tsx +++ b/packages/components/src/composite/legacy/index.tsx @@ -5,6 +5,11 @@ * tab stop for the whole Composite element. This means that it can behave as * a roving tabindex or aria-activedescendant container. * + * This file aims at providing component that are as close as possible to the + * original `reakit`-based implementation (which was removed from the codebase), + * although it is recommended that consumers of the package switch to the stable, + * un-prefixed, ariakit-based version of `Composite`. + * * @see https://ariakit.org/components/composite */ diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index f0ea4a4b7e86b8..6483e34dc222a8 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -61,7 +61,7 @@ export { CompositeGroup as __unstableCompositeGroup, CompositeItem as __unstableCompositeItem, useCompositeState as __unstableUseCompositeState, -} from './composite'; +} from './composite/legacy'; export { ConfirmDialog as __experimentalConfirmDialog } from './confirm-dialog'; export { default as CustomSelectControl } from './custom-select-control'; export { default as Dashicon } from './dashicon'; From 9f65aafd9e0f7b194851bf32b5f6ed638fcbc12c Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:06:00 +0200 Subject: [PATCH 02/39] Swap default folder export to new version --- packages/components/src/composite/index.ts | 5 +---- packages/components/src/composite/v2.ts | 4 ---- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 packages/components/src/composite/v2.ts diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts index f9ad4512ced67d..f77be7eb0c88de 100644 --- a/packages/components/src/composite/index.ts +++ b/packages/components/src/composite/index.ts @@ -1,4 +1 @@ -// through the 'legacy' version, which uses Ariakit under -// the hood. - -export * from './legacy'; +export * from './current'; diff --git a/packages/components/src/composite/v2.ts b/packages/components/src/composite/v2.ts deleted file mode 100644 index 38d3f628d368b6..00000000000000 --- a/packages/components/src/composite/v2.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Although we have migrated away from Reakit, the 'current' -// Ariakit implementation is still considered a v2. - -export * from './current'; From 89f623cb299777193fba9a188537f9ab5473b5f3 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:06:45 +0200 Subject: [PATCH 03/39] Apply compound component naming --- .../components/src/composite/current/index.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/components/src/composite/current/index.ts b/packages/components/src/composite/current/index.ts index 96379f00296516..98ca2a51752eb7 100644 --- a/packages/components/src/composite/current/index.ts +++ b/packages/components/src/composite/current/index.ts @@ -8,7 +8,10 @@ * @see https://ariakit.org/components/composite */ -export { +/** + * External dependencies + */ +import { Composite, CompositeGroup, CompositeGroupLabel, @@ -16,5 +19,15 @@ export { CompositeRow, useCompositeStore, } from '@ariakit/react'; +import type { CompositeStore, CompositeStoreProps } from '@ariakit/react'; + +// Exports +export const useStore = useCompositeStore; +export const Root = Composite; +export const Group = CompositeGroup; +export const GroupLabel = CompositeGroupLabel; +export const Item = CompositeItem; +export const Row = CompositeRow; -export type { CompositeStore, CompositeStoreProps } from '@ariakit/react'; +export type Store = CompositeStore; +export type StoreProps = CompositeStoreProps; From 0e0a729ca5396c2f185367fc537eb43f1af3c487 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:06:56 +0200 Subject: [PATCH 04/39] Export new version from the package --- packages/components/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 6483e34dc222a8..937d11d89a2382 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -62,6 +62,7 @@ export { CompositeItem as __unstableCompositeItem, useCompositeState as __unstableUseCompositeState, } from './composite/legacy'; +export * as Composite from './composite'; export { ConfirmDialog as __experimentalConfirmDialog } from './confirm-dialog'; export { default as CustomSelectControl } from './custom-select-control'; export { default as Dashicon } from './dashicon'; From bf8cf39ffceed521e350c169f108a7a73e12d918 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:07:15 +0200 Subject: [PATCH 05/39] Update (fix) private APIs exports --- packages/components/src/private-apis.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/components/src/private-apis.ts b/packages/components/src/private-apis.ts index 5ff39ba364a041..c48b20407079a9 100644 --- a/packages/components/src/private-apis.ts +++ b/packages/components/src/private-apis.ts @@ -1,13 +1,7 @@ /** * Internal dependencies */ -import { - Composite as CompositeV2, - CompositeGroup as CompositeGroupV2, - CompositeItem as CompositeItemV2, - CompositeRow as CompositeRowV2, - useCompositeStore as useCompositeStoreV2, -} from './composite/v2'; +import * as Composite from './composite'; import { positionToPlacement as __experimentalPopoverLegacyPositionToPlacement } from './popover/utils'; import { createPrivateSlotFill } from './slot-fill'; import { @@ -28,11 +22,11 @@ import { lock } from './lock-unlock'; export const privateApis = {}; lock( privateApis, { - CompositeV2, - CompositeGroupV2, - CompositeItemV2, - CompositeRowV2, - useCompositeStoreV2, + CompositeV2: Composite.Root, + CompositeGroupV2: Composite.Group, + CompositeItemV2: Composite.Item, + CompositeRowV2: Composite.Row, + useCompositeStoreV2: Composite.useStore, __experimentalPopoverLegacyPositionToPlacement, createPrivateSlotFill, ComponentsContext, From 951b7c8df97c8149010b34c42f403173b5f60bb7 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:08:43 +0200 Subject: [PATCH 06/39] Update composite implementation to use new compound naming --- .../composite/current/stories/index.story.tsx | 56 +++++++++---------- .../components/src/composite/legacy/index.tsx | 21 +++---- 2 files changed, 36 insertions(+), 41 deletions(-) diff --git a/packages/components/src/composite/current/stories/index.story.tsx b/packages/components/src/composite/current/stories/index.story.tsx index 335ebc3244c918..44591390eebad2 100644 --- a/packages/components/src/composite/current/stories/index.story.tsx +++ b/packages/components/src/composite/current/stories/index.story.tsx @@ -11,13 +11,7 @@ import { isRTL } from '@wordpress/i18n'; /** * Internal dependencies */ -import { - Composite, - CompositeGroup, - CompositeRow, - CompositeItem, - useCompositeStore, -} from '..'; +import * as Composite from '..'; import { UseCompositeStorePlaceholder, transform } from './utils'; const meta: Meta< typeof UseCompositeStorePlaceholder > = { @@ -25,13 +19,13 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { component: UseCompositeStorePlaceholder, subcomponents: { // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - Composite, + Root: Composite.Root, // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - CompositeGroup, + Group: Composite.Group, // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - CompositeRow, + Row: Composite.Row, // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - CompositeItem, + Item: Composite.Item, }, tags: [ 'status-private' ], parameters: { @@ -62,25 +56,29 @@ export default meta; export const Default: StoryFn< typeof Composite > = ( { ...initialState } ) => { const rtl = isRTL(); - const store = useCompositeStore( { rtl, ...initialState } ); + const store = Composite.useStore( { rtl, ...initialState } ); return ( - - - Item A1 - Item A2 - Item A3 - - - Item B1 - Item B2 - Item B3 - - - Item C1 - Item C2 - Item C3 - - + + + Item A1 + Item A2 + Item A3 + + + Item B1 + Item B2 + Item B3 + + + Item C1 + Item C2 + Item C3 + + ); }; diff --git a/packages/components/src/composite/legacy/index.tsx b/packages/components/src/composite/legacy/index.tsx index 2d237956f246f3..12f251d478f089 100644 --- a/packages/components/src/composite/legacy/index.tsx +++ b/packages/components/src/composite/legacy/index.tsx @@ -78,7 +78,7 @@ export interface LegacyStateOptions { type Component = React.FunctionComponent< any >; -type CompositeStore = ReturnType< typeof Current.useCompositeStore >; +type CompositeStore = ReturnType< typeof Current.useStore >; type CompositeStoreState = { store: CompositeStore }; export type CompositeState = CompositeStoreState & Required< Pick< LegacyStateOptions, 'baseId' > >; @@ -98,9 +98,9 @@ type CompositeComponent< C extends Component > = ( ) => React.ReactElement; type CompositeComponentProps = CompositeState & ( - | ComponentProps< typeof Current.CompositeGroup > - | ComponentProps< typeof Current.CompositeItem > - | ComponentProps< typeof Current.CompositeRow > + | ComponentProps< typeof Current.Group > + | ComponentProps< typeof Current.Item > + | ComponentProps< typeof Current.Row > ); function mapLegacyStatePropsToComponentProps( @@ -150,19 +150,16 @@ function proxyComposite< C extends Component >( // provided role, and returning the appropriate component. const unproxiedCompositeGroup = forwardRef< any, - React.ComponentPropsWithoutRef< - typeof Current.CompositeGroup | typeof Current.CompositeRow - > + React.ComponentPropsWithoutRef< typeof Current.Group | typeof Current.Row > >( ( { role, ...props }, ref ) => { - const Component = - role === 'row' ? Current.CompositeRow : Current.CompositeGroup; + const Component = role === 'row' ? Current.Row : Current.Group; return ; } ); unproxiedCompositeGroup.displayName = 'CompositeGroup'; -export const Composite = proxyComposite( Current.Composite, { baseId: 'id' } ); +export const Composite = proxyComposite( Current.Root, { baseId: 'id' } ); export const CompositeGroup = proxyComposite( unproxiedCompositeGroup ); -export const CompositeItem = proxyComposite( Current.CompositeItem, { +export const CompositeItem = proxyComposite( Current.Item, { focusable: 'accessibleWhenDisabled', } ); @@ -183,7 +180,7 @@ export function useCompositeState( return { baseId: useInstanceId( Composite, 'composite', baseId ), - store: Current.useCompositeStore( { + store: Current.useStore( { defaultActiveId, rtl, orientation, From 0da1b623728e1aac4f347c00b66975cde0f2f09b Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:09:35 +0200 Subject: [PATCH 07/39] Update references to Composite inside components package --- .../components/src/alignment-matrix-control/cell.tsx | 6 +++--- .../src/alignment-matrix-control/index.tsx | 12 ++++++------ .../circular-option-picker-option.tsx | 4 ++-- .../circular-option-picker.tsx | 8 ++++---- .../components/src/circular-option-picker/types.ts | 2 +- .../src/composite/current/stories/utils.tsx | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/components/src/alignment-matrix-control/cell.tsx b/packages/components/src/alignment-matrix-control/cell.tsx index 162ca879f1a7e5..485b1476b4209c 100644 --- a/packages/components/src/alignment-matrix-control/cell.tsx +++ b/packages/components/src/alignment-matrix-control/cell.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { CompositeItem } from '../composite/v2'; +import * as Composite from '../composite'; import Tooltip from '../tooltip'; import { VisuallyHidden } from '../visually-hidden'; @@ -26,7 +26,7 @@ export default function Cell( { return ( - } > @@ -35,7 +35,7 @@ export default function Cell( { hidden element instead of aria-label. */ } { value } - + ); } diff --git a/packages/components/src/alignment-matrix-control/index.tsx b/packages/components/src/alignment-matrix-control/index.tsx index eaec8a285b0c57..074812a900972a 100644 --- a/packages/components/src/alignment-matrix-control/index.tsx +++ b/packages/components/src/alignment-matrix-control/index.tsx @@ -13,7 +13,7 @@ import { useInstanceId } from '@wordpress/compose'; * Internal dependencies */ import Cell from './cell'; -import { Composite, CompositeRow, useCompositeStore } from '../composite/v2'; +import * as Composite from '../composite'; import { Root, Row } from './styles/alignment-matrix-control-styles'; import AlignmentMatrixControlIcon from './icon'; import { GRID, getItemId, getItemValue } from './utils'; @@ -56,7 +56,7 @@ export function AlignmentMatrixControl( { id ); - const compositeStore = useCompositeStore( { + const compositeStore = Composite.useStore( { defaultActiveId: getItemId( baseId, defaultValue ), activeId: getItemId( baseId, value ), setActiveId: ( nextActiveId ) => { @@ -73,7 +73,7 @@ export function AlignmentMatrixControl( { const classes = clsx( 'component-alignment-matrix-control', className ); return ( - { GRID.map( ( cells, index ) => ( - } key={ index }> + } key={ index }> { cells.map( ( cell ) => { const cellId = getItemId( baseId, cell ); const isActive = cellId === activeId; @@ -101,9 +101,9 @@ export function AlignmentMatrixControl( { /> ); } ) } - + ) ) } - + ); } diff --git a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx index 6c00a0e5d0bf1a..1c93cb869ed72a 100644 --- a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx +++ b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx @@ -16,7 +16,7 @@ import { Icon, check } from '@wordpress/icons'; */ import { CircularOptionPickerContext } from './circular-option-picker-context'; import Button from '../button'; -import { CompositeItem } from '../composite/v2'; +import * as Composite from '../composite'; import Tooltip from '../tooltip'; import type { OptionProps, CircularOptionPickerCompositeStore } from './types'; @@ -57,7 +57,7 @@ function UnforwardedOptionAsOption( } return ( - - { options } - + { children } { actions } diff --git a/packages/components/src/circular-option-picker/types.ts b/packages/components/src/circular-option-picker/types.ts index 519d81d5905107..61dcc82c98746e 100644 --- a/packages/components/src/circular-option-picker/types.ts +++ b/packages/components/src/circular-option-picker/types.ts @@ -14,7 +14,7 @@ import type { Icon } from '@wordpress/icons'; import type { ButtonAsButtonProps } from '../button/types'; import type { DropdownProps } from '../dropdown/types'; import type { WordPressComponentProps } from '../context'; -import type { CompositeStore } from '../composite/v2'; +import type { Store as CompositeStore } from '../composite'; type CommonCircularOptionPickerProps = { /** diff --git a/packages/components/src/composite/current/stories/utils.tsx b/packages/components/src/composite/current/stories/utils.tsx index 4b2d1bba4b312b..cea76fb887177a 100644 --- a/packages/components/src/composite/current/stories/utils.tsx +++ b/packages/components/src/composite/current/stories/utils.tsx @@ -6,7 +6,7 @@ import type { StoryContext } from '@storybook/react'; /** * Internal dependencies */ -import type { CompositeStoreProps } from '..'; +import type { StoreProps as CompositeStoreProps } from '..'; export function UseCompositeStorePlaceholder( props: CompositeStoreProps ) { return ( From e737a18dddb5a785d77473d89323f8fbb1fb0d61 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:10:41 +0200 Subject: [PATCH 08/39] Update Storybook entry points for both legacy and current --- .../components/src/composite/current/stories/index.story.tsx | 3 +-- .../components/src/composite/legacy/stories/index.story.tsx | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/src/composite/current/stories/index.story.tsx b/packages/components/src/composite/current/stories/index.story.tsx index 44591390eebad2..cac47c431b2680 100644 --- a/packages/components/src/composite/current/stories/index.story.tsx +++ b/packages/components/src/composite/current/stories/index.story.tsx @@ -15,7 +15,7 @@ import * as Composite from '..'; import { UseCompositeStorePlaceholder, transform } from './utils'; const meta: Meta< typeof UseCompositeStorePlaceholder > = { - title: 'Components/Composite (V2)', + title: 'Components/Composite', component: UseCompositeStorePlaceholder, subcomponents: { // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 @@ -27,7 +27,6 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 Item: Composite.Item, }, - tags: [ 'status-private' ], parameters: { docs: { canvas: { sourceState: 'shown' }, diff --git a/packages/components/src/composite/legacy/stories/index.story.tsx b/packages/components/src/composite/legacy/stories/index.story.tsx index e46d656a16810e..5caf31b90cfcc3 100644 --- a/packages/components/src/composite/legacy/stories/index.story.tsx +++ b/packages/components/src/composite/legacy/stories/index.story.tsx @@ -15,7 +15,8 @@ import { import { UseCompositeStatePlaceholder, transform } from './utils'; const meta: Meta< typeof UseCompositeStatePlaceholder > = { - title: 'Components/Composite', + // TODO: should we keep this story around? If so, how should we call it? + title: 'Components/Composite/Legacy', component: UseCompositeStatePlaceholder, subcomponents: { Composite, From 5c65788937f0995ce6469a1a2e428dc84a2c170c Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:10:58 +0200 Subject: [PATCH 09/39] Fix Storybook generated docs --- .../src/composite/current/stories/index.story.tsx | 5 ++++- .../components/src/composite/current/stories/utils.tsx | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/components/src/composite/current/stories/index.story.tsx b/packages/components/src/composite/current/stories/index.story.tsx index cac47c431b2680..1c42f5a13552a4 100644 --- a/packages/components/src/composite/current/stories/index.story.tsx +++ b/packages/components/src/composite/current/stories/index.story.tsx @@ -32,7 +32,10 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { canvas: { sourceState: 'shown' }, source: { transform }, extractArgTypes: ( component: React.FunctionComponent ) => { - const name = component.displayName; + const name = + component.displayName === 'useStore' + ? 'useCompositeStore' + : component.displayName; const path = name ?.replace( /([a-z])([A-Z])/g, diff --git a/packages/components/src/composite/current/stories/utils.tsx b/packages/components/src/composite/current/stories/utils.tsx index cea76fb887177a..a86d041bb493f8 100644 --- a/packages/components/src/composite/current/stories/utils.tsx +++ b/packages/components/src/composite/current/stories/utils.tsx @@ -20,7 +20,8 @@ export function UseCompositeStorePlaceholder( props: CompositeStoreProps ) { ); } -UseCompositeStorePlaceholder.displayName = 'useCompositeStore'; +UseCompositeStorePlaceholder.displayName = 'useStore'; +UseCompositeStorePlaceholder.ariakitAliasName = 'useStore'; export function transform( code: string, context: StoryContext ) { // The output generated by Storybook for these components is @@ -30,9 +31,9 @@ export function transform( code: string, context: StoryContext ) { const state = config.replace( ' {} ', '' ); return [ // Include a setup line, showing how to make use of - // `useCompositeStore` to convert store options into + // `Composite.useStore` to convert store options into // a composite store prop. - `const store = useCompositeStore(${ state });`, + `const store = Composite.useStore(${ state });`, '', 'return (', ' ' + From 051fb4a39ce5eb6ce210e76e2244ebd733056335 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:11:04 +0200 Subject: [PATCH 10/39] Add todo --- packages/dataviews/src/dataviews-layouts/list/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/dataviews/src/dataviews-layouts/list/index.tsx b/packages/dataviews/src/dataviews-layouts/list/index.tsx index 00939a12984856..70eaf3af1cd619 100644 --- a/packages/dataviews/src/dataviews-layouts/list/index.tsx +++ b/packages/dataviews/src/dataviews-layouts/list/index.tsx @@ -2,6 +2,7 @@ * External dependencies */ import clsx from 'clsx'; +// TODO: use the @wordpress/components one once public // Import CompositeStore type, which is not exported from @wordpress/components. // eslint-disable-next-line no-restricted-imports import type { CompositeStore } from '@ariakit/react'; From 45f8dcb4575de5d5b5d1c09cabbe3f2a1717cb82 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:22:52 +0200 Subject: [PATCH 11/39] Remove unncecessary code --- packages/components/src/composite/current/stories/utils.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/src/composite/current/stories/utils.tsx b/packages/components/src/composite/current/stories/utils.tsx index a86d041bb493f8..6e4ed10caa178a 100644 --- a/packages/components/src/composite/current/stories/utils.tsx +++ b/packages/components/src/composite/current/stories/utils.tsx @@ -21,7 +21,6 @@ export function UseCompositeStorePlaceholder( props: CompositeStoreProps ) { ); } UseCompositeStorePlaceholder.displayName = 'useStore'; -UseCompositeStorePlaceholder.ariakitAliasName = 'useStore'; export function transform( code: string, context: StoryContext ) { // The output generated by Storybook for these components is From 8d5778904d242b1c2d80bf3f4e84f92a6d49e92b Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:32:24 +0200 Subject: [PATCH 12/39] CHANGELOG --- packages/components/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 47afb0711090d8..dca5b6e03dedc3 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New Features + +- `Composite`: add stable version of the component ([#63564](https://github.com/WordPress/gutenberg/pull/63564)). + ### Enhancements - `TimePicker`: add `hideLabelFromVision` prop ([#64267](https://github.com/WordPress/gutenberg/pull/64267)). From d706c5e666054e62b820a942fd35d42c23eaece4 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 15:32:40 +0200 Subject: [PATCH 13/39] README --- packages/components/src/composite/current/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/components/src/composite/current/README.md diff --git a/packages/components/src/composite/current/README.md b/packages/components/src/composite/current/README.md new file mode 100644 index 00000000000000..0a7e4fff4f4385 --- /dev/null +++ b/packages/components/src/composite/current/README.md @@ -0,0 +1,5 @@ +# `Composite` + +`Composite` provides a single tab stop on the page and allows navigation through the focusable descendants with arrow keys. This abstract component is based on the [WAI-ARIA Composite Role⁠](https://w3c.github.io/aria/#composite). + +See the [Ariakit docs for the `Composite` component](https://ariakit.org/components/composite). From 0a68587dbf8e65e6eb134267c7cf2948d3eb35bd Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 16:41:58 +0200 Subject: [PATCH 14/39] Add JSDocs to Composite exports --- .../components/src/composite/current/index.ts | 104 +++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/packages/components/src/composite/current/index.ts b/packages/components/src/composite/current/index.ts index 98ca2a51752eb7..c2559c290362a4 100644 --- a/packages/components/src/composite/current/index.ts +++ b/packages/components/src/composite/current/index.ts @@ -21,12 +21,114 @@ import { } from '@ariakit/react'; import type { CompositeStore, CompositeStoreProps } from '@ariakit/react'; -// Exports +/** + * Creates a composite store. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * Item + * Item + * Item + * + * ``` + */ export const useStore = useCompositeStore; + +/** + * Renders a composite widget. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * Item 1 + * Item 2 + * + * ``` + */ export const Root = Composite; + +/** + * Renders a group element for composite items. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * + * Label + * Item 1 + * Item 2 + * + * + * ``` + */ export const Group = CompositeGroup; + +/** + * Renders a label in a composite group. This component must be wrapped with + * `CompositeGroup` so the `aria-labelledby` prop is properly set on the + * composite group element. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * + * Label + * Item 1 + * Item 2 + * + * + * ``` + */ export const GroupLabel = CompositeGroupLabel; + +/** + * Renders a composite item. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * Item 1 + * Item 2 + * Item 3 + * + * ``` + */ export const Item = CompositeItem; + +/** + * Renders a composite row. Wrapping `Composite.Item` elements within + * `Composite.Row` will create a two-dimensional composite widget, such as a + * grid. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * + * Item 1.1 + * Item 1.2 + * Item 1.3 + * + * + * Item 2.1 + * Item 2.2 + * Item 2.3 + * + * + * ``` + */ export const Row = CompositeRow; export type Store = CompositeStore; From 1acf18da62ece0eb16500b3ebd9d89406ef29894 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 16:53:47 +0200 Subject: [PATCH 15/39] Move current implementation out of `current` folder --- .../src/composite/{current => }/README.md | 0 .../components/src/composite/current/index.ts | 135 ----------------- packages/components/src/composite/index.ts | 136 +++++++++++++++++- .../{current => }/stories/index.story.tsx | 0 .../composite/{current => }/stories/utils.tsx | 0 5 files changed, 135 insertions(+), 136 deletions(-) rename packages/components/src/composite/{current => }/README.md (100%) delete mode 100644 packages/components/src/composite/current/index.ts rename packages/components/src/composite/{current => }/stories/index.story.tsx (100%) rename packages/components/src/composite/{current => }/stories/utils.tsx (100%) diff --git a/packages/components/src/composite/current/README.md b/packages/components/src/composite/README.md similarity index 100% rename from packages/components/src/composite/current/README.md rename to packages/components/src/composite/README.md diff --git a/packages/components/src/composite/current/index.ts b/packages/components/src/composite/current/index.ts deleted file mode 100644 index c2559c290362a4..00000000000000 --- a/packages/components/src/composite/current/index.ts +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Composite is a component that may contain navigable items represented by - * CompositeItem. It's inspired by the WAI-ARIA Composite Role and implements - * all the keyboard navigation mechanisms to ensure that there's only one - * tab stop for the whole Composite element. This means that it can behave as - * a roving tabindex or aria-activedescendant container. - * - * @see https://ariakit.org/components/composite - */ - -/** - * External dependencies - */ -import { - Composite, - CompositeGroup, - CompositeGroupLabel, - CompositeItem, - CompositeRow, - useCompositeStore, -} from '@ariakit/react'; -import type { CompositeStore, CompositeStoreProps } from '@ariakit/react'; - -/** - * Creates a composite store. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * Item - * Item - * Item - * - * ``` - */ -export const useStore = useCompositeStore; - -/** - * Renders a composite widget. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * Item 1 - * Item 2 - * - * ``` - */ -export const Root = Composite; - -/** - * Renders a group element for composite items. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * - * Label - * Item 1 - * Item 2 - * - * - * ``` - */ -export const Group = CompositeGroup; - -/** - * Renders a label in a composite group. This component must be wrapped with - * `CompositeGroup` so the `aria-labelledby` prop is properly set on the - * composite group element. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * - * Label - * Item 1 - * Item 2 - * - * - * ``` - */ -export const GroupLabel = CompositeGroupLabel; - -/** - * Renders a composite item. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * Item 1 - * Item 2 - * Item 3 - * - * ``` - */ -export const Item = CompositeItem; - -/** - * Renders a composite row. Wrapping `Composite.Item` elements within - * `Composite.Row` will create a two-dimensional composite widget, such as a - * grid. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * - * Item 1.1 - * Item 1.2 - * Item 1.3 - * - * - * Item 2.1 - * Item 2.2 - * Item 2.3 - * - * - * ``` - */ -export const Row = CompositeRow; - -export type Store = CompositeStore; -export type StoreProps = CompositeStoreProps; diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts index f77be7eb0c88de..c2559c290362a4 100644 --- a/packages/components/src/composite/index.ts +++ b/packages/components/src/composite/index.ts @@ -1 +1,135 @@ -export * from './current'; +/** + * Composite is a component that may contain navigable items represented by + * CompositeItem. It's inspired by the WAI-ARIA Composite Role and implements + * all the keyboard navigation mechanisms to ensure that there's only one + * tab stop for the whole Composite element. This means that it can behave as + * a roving tabindex or aria-activedescendant container. + * + * @see https://ariakit.org/components/composite + */ + +/** + * External dependencies + */ +import { + Composite, + CompositeGroup, + CompositeGroupLabel, + CompositeItem, + CompositeRow, + useCompositeStore, +} from '@ariakit/react'; +import type { CompositeStore, CompositeStoreProps } from '@ariakit/react'; + +/** + * Creates a composite store. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * Item + * Item + * Item + * + * ``` + */ +export const useStore = useCompositeStore; + +/** + * Renders a composite widget. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * Item 1 + * Item 2 + * + * ``` + */ +export const Root = Composite; + +/** + * Renders a group element for composite items. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * + * Label + * Item 1 + * Item 2 + * + * + * ``` + */ +export const Group = CompositeGroup; + +/** + * Renders a label in a composite group. This component must be wrapped with + * `CompositeGroup` so the `aria-labelledby` prop is properly set on the + * composite group element. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * + * Label + * Item 1 + * Item 2 + * + * + * ``` + */ +export const GroupLabel = CompositeGroupLabel; + +/** + * Renders a composite item. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * Item 1 + * Item 2 + * Item 3 + * + * ``` + */ +export const Item = CompositeItem; + +/** + * Renders a composite row. Wrapping `Composite.Item` elements within + * `Composite.Row` will create a two-dimensional composite widget, such as a + * grid. + * @see https://ariakit.org/components/composite + * @example + * ```jsx + * const useCompositeStore = Composite.useStore; + * const store = useCompositeStore(); + * + * + * Item 1.1 + * Item 1.2 + * Item 1.3 + * + * + * Item 2.1 + * Item 2.2 + * Item 2.3 + * + * + * ``` + */ +export const Row = CompositeRow; + +export type Store = CompositeStore; +export type StoreProps = CompositeStoreProps; diff --git a/packages/components/src/composite/current/stories/index.story.tsx b/packages/components/src/composite/stories/index.story.tsx similarity index 100% rename from packages/components/src/composite/current/stories/index.story.tsx rename to packages/components/src/composite/stories/index.story.tsx diff --git a/packages/components/src/composite/current/stories/utils.tsx b/packages/components/src/composite/stories/utils.tsx similarity index 100% rename from packages/components/src/composite/current/stories/utils.tsx rename to packages/components/src/composite/stories/utils.tsx From a5b0ae49055f0bcd42bd83bad394aa12181178d1 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 16:54:00 +0200 Subject: [PATCH 16/39] Fix import in the legacy implementation --- packages/components/src/composite/legacy/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/composite/legacy/index.tsx b/packages/components/src/composite/legacy/index.tsx index 12f251d478f089..bdbfdc928f98b2 100644 --- a/packages/components/src/composite/legacy/index.tsx +++ b/packages/components/src/composite/legacy/index.tsx @@ -21,7 +21,7 @@ import { forwardRef } from '@wordpress/element'; /** * Internal dependencies */ -import * as Current from '../current'; +import * as Current from '..'; import { useInstanceId } from '@wordpress/compose'; type Orientation = 'horizontal' | 'vertical'; From f648f693ed5bcefaceb3c54456a0c4cd987537da Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 16:54:42 +0200 Subject: [PATCH 17/39] Update docs manifest --- docs/manifest.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/manifest.json b/docs/manifest.json index 1704e6d711510f..b483449872cc76 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -767,6 +767,12 @@ "markdown_source": "../packages/components/src/combobox-control/README.md", "parent": "components" }, + { + "title": "Composite", + "slug": "composite", + "markdown_source": "../packages/components/src/composite/README.md", + "parent": "components" + }, { "title": "ConfirmDialog", "slug": "confirm-dialog", From deab309cba5c9083e10a6ab8e29bc5eedc4b0cf7 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 16:55:00 +0200 Subject: [PATCH 18/39] Fix type in Storybook example --- packages/components/src/composite/stories/index.story.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/components/src/composite/stories/index.story.tsx b/packages/components/src/composite/stories/index.story.tsx index 1c42f5a13552a4..2ca5a535a004e5 100644 --- a/packages/components/src/composite/stories/index.story.tsx +++ b/packages/components/src/composite/stories/index.story.tsx @@ -56,7 +56,9 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { }; export default meta; -export const Default: StoryFn< typeof Composite > = ( { ...initialState } ) => { +export const Default: StoryFn< typeof Composite.Root > = ( { + ...initialState +} ) => { const rtl = isRTL(); const store = Composite.useStore( { rtl, ...initialState } ); From b9246dcc02c2fc655caa50ed84224a1459e5894c Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Mon, 15 Jul 2024 16:55:20 +0200 Subject: [PATCH 19/39] Add JSDocs for Storybook docs --- packages/components/src/composite/stories/utils.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/components/src/composite/stories/utils.tsx b/packages/components/src/composite/stories/utils.tsx index 6e4ed10caa178a..32afad6bfb3faf 100644 --- a/packages/components/src/composite/stories/utils.tsx +++ b/packages/components/src/composite/stories/utils.tsx @@ -8,6 +8,9 @@ import type { StoryContext } from '@storybook/react'; */ import type { StoreProps as CompositeStoreProps } from '..'; +/** + * Renders a composite widget. + */ export function UseCompositeStorePlaceholder( props: CompositeStoreProps ) { return (
From 2bd8e5e56eadbb20154fd36154b4f3354c28f323 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 31 Jul 2024 18:41:17 +0200 Subject: [PATCH 20/39] Apply Overloaded naming convention --- .../src/alignment-matrix-control/cell.tsx | 2 +- .../src/alignment-matrix-control/index.tsx | 8 +- .../circular-option-picker-option.tsx | 2 +- .../circular-option-picker.tsx | 8 +- packages/components/src/composite/index.ts | 194 +++++++++--------- .../components/src/composite/legacy/index.tsx | 12 +- .../composite/legacy/stories/index.story.tsx | 1 + .../src/composite/stories/index.story.tsx | 39 ++-- .../src/composite/stories/utils.tsx | 6 +- packages/components/src/index.ts | 2 +- packages/components/src/private-apis.ts | 6 +- 11 files changed, 138 insertions(+), 142 deletions(-) diff --git a/packages/components/src/alignment-matrix-control/cell.tsx b/packages/components/src/alignment-matrix-control/cell.tsx index 485b1476b4209c..6e045c26694f4e 100644 --- a/packages/components/src/alignment-matrix-control/cell.tsx +++ b/packages/components/src/alignment-matrix-control/cell.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import * as Composite from '../composite'; +import { Composite } from '../composite'; import Tooltip from '../tooltip'; import { VisuallyHidden } from '../visually-hidden'; diff --git a/packages/components/src/alignment-matrix-control/index.tsx b/packages/components/src/alignment-matrix-control/index.tsx index 074812a900972a..1d22c3560625db 100644 --- a/packages/components/src/alignment-matrix-control/index.tsx +++ b/packages/components/src/alignment-matrix-control/index.tsx @@ -13,7 +13,7 @@ import { useInstanceId } from '@wordpress/compose'; * Internal dependencies */ import Cell from './cell'; -import * as Composite from '../composite'; +import { Composite, useCompositeStore } from '../composite'; import { Root, Row } from './styles/alignment-matrix-control-styles'; import AlignmentMatrixControlIcon from './icon'; import { GRID, getItemId, getItemValue } from './utils'; @@ -56,7 +56,7 @@ export function AlignmentMatrixControl( { id ); - const compositeStore = Composite.useStore( { + const compositeStore = useCompositeStore( { defaultActiveId: getItemId( baseId, defaultValue ), activeId: getItemId( baseId, value ), setActiveId: ( nextActiveId ) => { @@ -73,7 +73,7 @@ export function AlignmentMatrixControl( { const classes = clsx( 'component-alignment-matrix-control', className ); return ( - ) ) } - + ); } diff --git a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx index 1c93cb869ed72a..2650416f4718ff 100644 --- a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx +++ b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx @@ -16,7 +16,7 @@ import { Icon, check } from '@wordpress/icons'; */ import { CircularOptionPickerContext } from './circular-option-picker-context'; import Button from '../button'; -import * as Composite from '../composite'; +import { Composite } from '../composite'; import Tooltip from '../tooltip'; import type { OptionProps, CircularOptionPickerCompositeStore } from './types'; diff --git a/packages/components/src/circular-option-picker/circular-option-picker.tsx b/packages/components/src/circular-option-picker/circular-option-picker.tsx index 2513713a2e1818..c1e719f2d4f665 100644 --- a/packages/components/src/circular-option-picker/circular-option-picker.tsx +++ b/packages/components/src/circular-option-picker/circular-option-picker.tsx @@ -13,7 +13,7 @@ import { isRTL } from '@wordpress/i18n'; * Internal dependencies */ import { CircularOptionPickerContext } from './circular-option-picker-context'; -import * as Composite from '../composite'; +import { Composite, useCompositeStore } from '../composite'; import type { CircularOptionPickerProps, ListboxCircularOptionPickerProps, @@ -85,7 +85,7 @@ function ListboxCircularOptionPicker( ...additionalProps } = props; - const compositeStore = Composite.useStore( { + const compositeStore = useCompositeStore( { focusLoop: loop, rtl: isRTL(), } ); @@ -98,14 +98,14 @@ function ListboxCircularOptionPicker( return (
- { options } - + { children } { actions } diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts index c2559c290362a4..2080f3cc105d19 100644 --- a/packages/components/src/composite/index.ts +++ b/packages/components/src/composite/index.ts @@ -1,6 +1,6 @@ /** * Composite is a component that may contain navigable items represented by - * CompositeItem. It's inspired by the WAI-ARIA Composite Role and implements + * Composite.Item. It's inspired by the WAI-ARIA Composite Role and implements * all the keyboard navigation mechanisms to ensure that there's only one * tab stop for the whole Composite element. This means that it can behave as * a roving tabindex or aria-activedescendant container. @@ -11,125 +11,127 @@ /** * External dependencies */ -import { - Composite, - CompositeGroup, - CompositeGroupLabel, - CompositeItem, - CompositeRow, - useCompositeStore, -} from '@ariakit/react'; +import * as Ariakit from '@ariakit/react'; import type { CompositeStore, CompositeStoreProps } from '@ariakit/react'; /** * Creates a composite store. - * @see https://ariakit.org/components/composite + * @see https://ariakit.org/reference/use-composite-store * @example * ```jsx - * const useCompositeStore = Composite.useStore; + * const useCompositeStore = useCompositeStore(); * const store = useCompositeStore(); - * + * * Item * Item * Item - * + * * ``` */ -export const useStore = useCompositeStore; +export const useCompositeStore = Ariakit.useCompositeStore; -/** - * Renders a composite widget. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * Item 1 - * Item 2 - * - * ``` - */ -export const Root = Composite; +const Group = Ariakit.CompositeGroup; +Group.displayName = 'Composite.Group'; -/** - * Renders a group element for composite items. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * - * Label - * Item 1 - * Item 2 - * - * - * ``` - */ -export const Group = CompositeGroup; +export const GroupLabel = Ariakit.CompositeGroupLabel; +GroupLabel.displayName = 'Composite.GroupLabel'; -/** - * Renders a label in a composite group. This component must be wrapped with - * `CompositeGroup` so the `aria-labelledby` prop is properly set on the - * composite group element. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * - * Label - * Item 1 - * Item 2 - * - * - * ``` - */ -export const GroupLabel = CompositeGroupLabel; +export const Item = Ariakit.CompositeItem; +Item.displayName = 'Composite.Item'; + +export const Row = Ariakit.Composite.Row; +Row.displayName = 'Composite.Row'; /** - * Renders a composite item. - * @see https://ariakit.org/components/composite + * Renders a composite widget. + * @see https://ariakit.org/reference/composite * @example * ```jsx - * const useCompositeStore = Composite.useStore; + * const useCompositeStore = useCompositeStore(); * const store = useCompositeStore(); - * + * * Item 1 * Item 2 - * Item 3 - * - * ``` - */ -export const Item = CompositeItem; - -/** - * Renders a composite row. Wrapping `Composite.Item` elements within - * `Composite.Row` will create a two-dimensional composite widget, such as a - * grid. - * @see https://ariakit.org/components/composite - * @example - * ```jsx - * const useCompositeStore = Composite.useStore; - * const store = useCompositeStore(); - * - * - * Item 1.1 - * Item 1.2 - * Item 1.3 - * - * - * Item 2.1 - * Item 2.2 - * Item 2.3 - * - * + * * ``` */ -export const Row = CompositeRow; +export const Composite = Object.assign( Ariakit.Composite, { + /** + * Renders a group element for composite items. + * @see https://ariakit.org/reference/composite-group + * @example + * ```jsx + * const useCompositeStore = useCompositeStore(); + * const store = useCompositeStore(); + * + * + * Label + * Item 1 + * Item 2 + * + * + * ``` + */ + Group, + /** + * Renders a label in a composite group. This component must be wrapped with + * `Composite.Group` so the `aria-labelledby` prop is properly set on the + * composite group element. + * @see https://ariakit.org/reference/composite-group-label + * @example + * ```jsx + * const useCompositeStore = useCompositeStore(); + * const store = useCompositeStore(); + * + * + * Label + * Item 1 + * Item 2 + * + * + * ``` + */ + GroupLabel, + /** + * Renders a composite item. + * @see https://ariakit.org/reference/composite-item + * @example + * ```jsx + * const useCompositeStore = useCompositeStore(); + * const store = useCompositeStore(); + * + * Item 1 + * Item 2 + * Item 3 + * + * ``` + */ + Item, + /** + * Renders a composite row. Wrapping `Composite.Item` elements within + * `Composite.Row` will create a two-dimensional composite widget, such as a + * grid. + * @see https://ariakit.org/reference/composite-row + * @example + * ```jsx + * const useCompositeStore = useCompositeStore(); + * const store = useCompositeStore(); + * + * + * Item 1.1 + * Item 1.2 + * Item 1.3 + * + * + * Item 2.1 + * Item 2.2 + * Item 2.3 + * + * + * ``` + */ + Row, +} ); export type Store = CompositeStore; export type StoreProps = CompositeStoreProps; diff --git a/packages/components/src/composite/legacy/index.tsx b/packages/components/src/composite/legacy/index.tsx index bdbfdc928f98b2..d802d5eae377da 100644 --- a/packages/components/src/composite/legacy/index.tsx +++ b/packages/components/src/composite/legacy/index.tsx @@ -5,10 +5,10 @@ * tab stop for the whole Composite element. This means that it can behave as * a roving tabindex or aria-activedescendant container. * - * This file aims at providing component that are as close as possible to the + * This file aims at providing components that are as close as possible to the * original `reakit`-based implementation (which was removed from the codebase), * although it is recommended that consumers of the package switch to the stable, - * un-prefixed, ariakit-based version of `Composite`. + * un-prefixed, `ariakit`-based version of `Composite`. * * @see https://ariakit.org/components/composite */ @@ -21,7 +21,7 @@ import { forwardRef } from '@wordpress/element'; /** * Internal dependencies */ -import * as Current from '..'; +import { Composite as Current, useCompositeStore } from '..'; import { useInstanceId } from '@wordpress/compose'; type Orientation = 'horizontal' | 'vertical'; @@ -78,7 +78,7 @@ export interface LegacyStateOptions { type Component = React.FunctionComponent< any >; -type CompositeStore = ReturnType< typeof Current.useStore >; +type CompositeStore = ReturnType< typeof useCompositeStore >; type CompositeStoreState = { store: CompositeStore }; export type CompositeState = CompositeStoreState & Required< Pick< LegacyStateOptions, 'baseId' > >; @@ -157,7 +157,7 @@ const unproxiedCompositeGroup = forwardRef< } ); unproxiedCompositeGroup.displayName = 'CompositeGroup'; -export const Composite = proxyComposite( Current.Root, { baseId: 'id' } ); +export const Composite = proxyComposite( Current, { baseId: 'id' } ); export const CompositeGroup = proxyComposite( unproxiedCompositeGroup ); export const CompositeItem = proxyComposite( Current.Item, { focusable: 'accessibleWhenDisabled', @@ -180,7 +180,7 @@ export function useCompositeState( return { baseId: useInstanceId( Composite, 'composite', baseId ), - store: Current.useStore( { + store: useCompositeStore( { defaultActiveId, rtl, orientation, diff --git a/packages/components/src/composite/legacy/stories/index.story.tsx b/packages/components/src/composite/legacy/stories/index.story.tsx index 5caf31b90cfcc3..08eebc65edf638 100644 --- a/packages/components/src/composite/legacy/stories/index.story.tsx +++ b/packages/components/src/composite/legacy/stories/index.story.tsx @@ -19,6 +19,7 @@ const meta: Meta< typeof UseCompositeStatePlaceholder > = { title: 'Components/Composite/Legacy', component: UseCompositeStatePlaceholder, subcomponents: { + // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents Composite, CompositeGroup, CompositeItem, diff --git a/packages/components/src/composite/stories/index.story.tsx b/packages/components/src/composite/stories/index.story.tsx index 2ca5a535a004e5..0958f650cb2f76 100644 --- a/packages/components/src/composite/stories/index.story.tsx +++ b/packages/components/src/composite/stories/index.story.tsx @@ -11,31 +11,30 @@ import { isRTL } from '@wordpress/i18n'; /** * Internal dependencies */ -import * as Composite from '..'; +import { Composite, useCompositeStore } from '..'; import { UseCompositeStorePlaceholder, transform } from './utils'; const meta: Meta< typeof UseCompositeStorePlaceholder > = { title: 'Components/Composite', component: UseCompositeStorePlaceholder, subcomponents: { - // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - Root: Composite.Root, - // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - Group: Composite.Group, - // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - Row: Composite.Row, - // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 - Item: Composite.Item, + // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + Composite, + // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + 'Composite.Group': Composite.Group, + // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + 'Composite.GroupLabel': Composite.GroupLabel, + // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + 'Composite.Row': Composite.Row, + // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + 'Composite.Item': Composite.Item, }, parameters: { docs: { canvas: { sourceState: 'shown' }, source: { transform }, extractArgTypes: ( component: React.FunctionComponent ) => { - const name = - component.displayName === 'useStore' - ? 'useCompositeStore' - : component.displayName; + const name = component.displayName; const path = name ?.replace( /([a-z])([A-Z])/g, @@ -56,18 +55,12 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { }; export default meta; -export const Default: StoryFn< typeof Composite.Root > = ( { - ...initialState -} ) => { +export const Default: StoryFn< typeof Composite > = ( { ...initialState } ) => { const rtl = isRTL(); - const store = Composite.useStore( { rtl, ...initialState } ); + const store = useCompositeStore( { rtl, ...initialState } ); return ( - + Item A1 Item A2 @@ -83,6 +76,6 @@ export const Default: StoryFn< typeof Composite.Root > = ( { Item C2 Item C3 - + ); }; diff --git a/packages/components/src/composite/stories/utils.tsx b/packages/components/src/composite/stories/utils.tsx index 32afad6bfb3faf..10e9ac8036d879 100644 --- a/packages/components/src/composite/stories/utils.tsx +++ b/packages/components/src/composite/stories/utils.tsx @@ -23,7 +23,7 @@ export function UseCompositeStorePlaceholder( props: CompositeStoreProps ) {
); } -UseCompositeStorePlaceholder.displayName = 'useStore'; +UseCompositeStorePlaceholder.displayName = 'useCompositeStore'; export function transform( code: string, context: StoryContext ) { // The output generated by Storybook for these components is @@ -33,9 +33,9 @@ export function transform( code: string, context: StoryContext ) { const state = config.replace( ' {} ', '' ); return [ // Include a setup line, showing how to make use of - // `Composite.useStore` to convert store options into + // `useCompositeStore` to convert store options into // a composite store prop. - `const store = Composite.useStore(${ state });`, + `const store = useCompositeStore(${ state });`, '', 'return (', ' ' + diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 937d11d89a2382..4c724a461e6775 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -62,7 +62,7 @@ export { CompositeItem as __unstableCompositeItem, useCompositeState as __unstableUseCompositeState, } from './composite/legacy'; -export * as Composite from './composite'; +export { Composite } from './composite'; export { ConfirmDialog as __experimentalConfirmDialog } from './confirm-dialog'; export { default as CustomSelectControl } from './custom-select-control'; export { default as Dashicon } from './dashicon'; diff --git a/packages/components/src/private-apis.ts b/packages/components/src/private-apis.ts index c48b20407079a9..699911e5ba046b 100644 --- a/packages/components/src/private-apis.ts +++ b/packages/components/src/private-apis.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import * as Composite from './composite'; +import { Composite, useCompositeStore } from './composite'; import { positionToPlacement as __experimentalPopoverLegacyPositionToPlacement } from './popover/utils'; import { createPrivateSlotFill } from './slot-fill'; import { @@ -22,11 +22,11 @@ import { lock } from './lock-unlock'; export const privateApis = {}; lock( privateApis, { - CompositeV2: Composite.Root, + CompositeV2: Composite, CompositeGroupV2: Composite.Group, CompositeItemV2: Composite.Item, CompositeRowV2: Composite.Row, - useCompositeStoreV2: Composite.useStore, + useCompositeStoreV2: useCompositeStore, __experimentalPopoverLegacyPositionToPlacement, createPrivateSlotFill, ComponentsContext, From 0df3c5a0d201ae0dcfd77cc188f72dd043befd1e Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 31 Jul 2024 18:41:54 +0200 Subject: [PATCH 21/39] Update README --- packages/components/src/composite/README.md | 46 +++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/components/src/composite/README.md b/packages/components/src/composite/README.md index 0a7e4fff4f4385..bb37dd6712f404 100644 --- a/packages/components/src/composite/README.md +++ b/packages/components/src/composite/README.md @@ -3,3 +3,49 @@ `Composite` provides a single tab stop on the page and allows navigation through the focusable descendants with arrow keys. This abstract component is based on the [WAI-ARIA Composite Role⁠](https://w3c.github.io/aria/#composite). See the [Ariakit docs for the `Composite` component](https://ariakit.org/components/composite). + +## Usage + +```jsx +const useCompositeStore = useCompositeStore(); +const store = useCompositeStore(); + + + Label + Item 1 + Item 2 + + +``` + +## Components + +### `Composite` + +Renders a composite widget. + +See the [Ariakit docs for the `Composite` component](https://ariakit.org/reference/composite). + +### `Composite.Group` + +Renders a group element for composite items. + +See the [Ariakit docs for the `CompositeGroup` component](https://ariakit.org/reference/composite-group). + +### `Composite.GroupLabel` + +Renders a label in a composite group. This component must be wrapped with `Composite.Group` so the `aria-labelledby` prop is properly set on the composite group element. + +See the [Ariakit docs for the `CompositeGroupLabel` component](https://ariakit.org/reference/composite-group-label). + +### `Composite.Item` + +Renders a composite item. + +See the [Ariakit docs for the `CompositeItem` component](https://ariakit.org/reference/composite-item). + +### `Composite.Row` + +Renders a composite row. Wrapping `Composite.Item` elements within `Composite.Row` will create a two-dimensional composite widget, such as a grid. + +See the [Ariakit docs for the `CompositeItem` component](https://ariakit.org/reference/composite-row). From 1ef744c9cf99cc70dde94142775f906feb197313 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Wed, 31 Jul 2024 18:45:22 +0200 Subject: [PATCH 22/39] Fix typo --- packages/components/src/composite/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts index 2080f3cc105d19..c7a5b3234e3d06 100644 --- a/packages/components/src/composite/index.ts +++ b/packages/components/src/composite/index.ts @@ -39,7 +39,7 @@ GroupLabel.displayName = 'Composite.GroupLabel'; export const Item = Ariakit.CompositeItem; Item.displayName = 'Composite.Item'; -export const Row = Ariakit.Composite.Row; +export const Row = Ariakit.CompositeRow; Row.displayName = 'Composite.Row'; /** From cc11ab457289d4f45a440c56af04e1e13fcc4d81 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 10:06:49 +0200 Subject: [PATCH 23/39] Update legacy storybook title/id, make sure JSDocs refer to unstable version --- .../composite/legacy/stories/index.story.tsx | 4 ++-- .../src/composite/legacy/stories/utils.tsx | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/components/src/composite/legacy/stories/index.story.tsx b/packages/components/src/composite/legacy/stories/index.story.tsx index 08eebc65edf638..d3d3205afe714f 100644 --- a/packages/components/src/composite/legacy/stories/index.story.tsx +++ b/packages/components/src/composite/legacy/stories/index.story.tsx @@ -15,8 +15,8 @@ import { import { UseCompositeStatePlaceholder, transform } from './utils'; const meta: Meta< typeof UseCompositeStatePlaceholder > = { - // TODO: should we keep this story around? If so, how should we call it? - title: 'Components/Composite/Legacy', + title: 'Components (Deprecated)/Composite (Unstable)', + id: 'components-composite-unstable', component: UseCompositeStatePlaceholder, subcomponents: { // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents diff --git a/packages/components/src/composite/legacy/stories/utils.tsx b/packages/components/src/composite/legacy/stories/utils.tsx index 06edd348634695..2fb51c845f9fbe 100644 --- a/packages/components/src/composite/legacy/stories/utils.tsx +++ b/packages/components/src/composite/legacy/stories/utils.tsx @@ -8,6 +8,25 @@ import type { StoryContext } from '@storybook/react'; */ import type { LegacyStateOptions } from '..'; +/** + * Renders a composite widget. + * + * This unstable component is deprecated. Use `Composite` instead. + * + * ```jsx + * import { + * __unstableUseCompositeState as useCompositeState, + * __unstableComposite as Composite, + * __unstableCompositeItem as CompositeItem, + * } from '@wordpress/components'; + * + * const state = useCompositeState(); + * + * Item 1 + * Item 2 + * ; + * ``` + */ export function UseCompositeStatePlaceholder( props: LegacyStateOptions ) { return (
From ae1f17ff33a8697187772c3721eeb0f96f9dff73 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 10:17:45 +0200 Subject: [PATCH 24/39] Derive types instead of importing them directly from ariakit --- .../circular-option-picker-option.tsx | 6 ++++-- packages/components/src/circular-option-picker/types.ts | 5 ++--- packages/components/src/composite/index.ts | 4 ---- packages/components/src/composite/stories/utils.tsx | 6 ++++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx index 2650416f4718ff..cb4d5ae6472668 100644 --- a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx +++ b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx @@ -18,7 +18,7 @@ import { CircularOptionPickerContext } from './circular-option-picker-context'; import Button from '../button'; import { Composite } from '../composite'; import Tooltip from '../tooltip'; -import type { OptionProps, CircularOptionPickerCompositeStore } from './types'; +import type { OptionProps } from './types'; function UnforwardedOptionAsButton( props: { @@ -45,7 +45,9 @@ function UnforwardedOptionAsOption( id: string; className?: string; isSelected?: boolean; - compositeStore: CircularOptionPickerCompositeStore; + compositeStore: NonNullable< + React.ComponentProps< typeof Composite >[ 'store' ] + >; }, forwardedRef: ForwardedRef< any > ) { diff --git a/packages/components/src/circular-option-picker/types.ts b/packages/components/src/circular-option-picker/types.ts index 61dcc82c98746e..e23ff4165f0580 100644 --- a/packages/components/src/circular-option-picker/types.ts +++ b/packages/components/src/circular-option-picker/types.ts @@ -14,7 +14,7 @@ import type { Icon } from '@wordpress/icons'; import type { ButtonAsButtonProps } from '../button/types'; import type { DropdownProps } from '../dropdown/types'; import type { WordPressComponentProps } from '../context'; -import type { Store as CompositeStore } from '../composite'; +import type { Composite } from '../composite'; type CommonCircularOptionPickerProps = { /** @@ -123,8 +123,7 @@ export type OptionProps = Omit< >; }; -export type CircularOptionPickerCompositeStore = CompositeStore; export type CircularOptionPickerContextProps = { baseId?: string; - compositeStore?: CircularOptionPickerCompositeStore; + compositeStore?: React.ComponentProps< typeof Composite >[ 'store' ]; }; diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts index c7a5b3234e3d06..ac9acbc9750a1b 100644 --- a/packages/components/src/composite/index.ts +++ b/packages/components/src/composite/index.ts @@ -12,7 +12,6 @@ * External dependencies */ import * as Ariakit from '@ariakit/react'; -import type { CompositeStore, CompositeStoreProps } from '@ariakit/react'; /** * Creates a composite store. @@ -132,6 +131,3 @@ export const Composite = Object.assign( Ariakit.Composite, { */ Row, } ); - -export type Store = CompositeStore; -export type StoreProps = CompositeStoreProps; diff --git a/packages/components/src/composite/stories/utils.tsx b/packages/components/src/composite/stories/utils.tsx index 10e9ac8036d879..396703875f198d 100644 --- a/packages/components/src/composite/stories/utils.tsx +++ b/packages/components/src/composite/stories/utils.tsx @@ -6,12 +6,14 @@ import type { StoryContext } from '@storybook/react'; /** * Internal dependencies */ -import type { StoreProps as CompositeStoreProps } from '..'; +import type { useCompositeStore } from '..'; /** * Renders a composite widget. */ -export function UseCompositeStorePlaceholder( props: CompositeStoreProps ) { +export function UseCompositeStorePlaceholder( + props: Parameters< typeof useCompositeStore > +) { return (
{ Object.entries( props ).map( ( [ name, value ] ) => ( From e1ba58d3819666d8a2c0e8eea656e63e3a4a5c1f Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 10:20:54 +0200 Subject: [PATCH 25/39] Add JSDoc snippet for stable component --- packages/components/src/composite/stories/utils.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/components/src/composite/stories/utils.tsx b/packages/components/src/composite/stories/utils.tsx index 396703875f198d..e71aa10a72a241 100644 --- a/packages/components/src/composite/stories/utils.tsx +++ b/packages/components/src/composite/stories/utils.tsx @@ -10,6 +10,14 @@ import type { useCompositeStore } from '..'; /** * Renders a composite widget. + * + * ```jsx + * const store = useCompositeStore(); + * + * Item 1 + * Item 2 + * + * ``` */ export function UseCompositeStorePlaceholder( props: Parameters< typeof useCompositeStore > From ea4461bef9cbd5cdceaca7f864d43f49c7d3e1b2 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 10:47:54 +0200 Subject: [PATCH 26/39] Remove unnecessary JSDoc code --- packages/components/src/composite/README.md | 1 - packages/components/src/composite/index.ts | 6 ------ 2 files changed, 7 deletions(-) diff --git a/packages/components/src/composite/README.md b/packages/components/src/composite/README.md index bb37dd6712f404..31631281df3208 100644 --- a/packages/components/src/composite/README.md +++ b/packages/components/src/composite/README.md @@ -7,7 +7,6 @@ See the [Ariakit docs for the `Composite` component](https://ariakit.org/compone ## Usage ```jsx -const useCompositeStore = useCompositeStore(); const store = useCompositeStore(); diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts index ac9acbc9750a1b..a3999e7f4790a3 100644 --- a/packages/components/src/composite/index.ts +++ b/packages/components/src/composite/index.ts @@ -18,7 +18,6 @@ import * as Ariakit from '@ariakit/react'; * @see https://ariakit.org/reference/use-composite-store * @example * ```jsx - * const useCompositeStore = useCompositeStore(); * const store = useCompositeStore(); * * Item @@ -46,7 +45,6 @@ Row.displayName = 'Composite.Row'; * @see https://ariakit.org/reference/composite * @example * ```jsx - * const useCompositeStore = useCompositeStore(); * const store = useCompositeStore(); * * Item 1 @@ -60,7 +58,6 @@ export const Composite = Object.assign( Ariakit.Composite, { * @see https://ariakit.org/reference/composite-group * @example * ```jsx - * const useCompositeStore = useCompositeStore(); * const store = useCompositeStore(); * * @@ -79,7 +76,6 @@ export const Composite = Object.assign( Ariakit.Composite, { * @see https://ariakit.org/reference/composite-group-label * @example * ```jsx - * const useCompositeStore = useCompositeStore(); * const store = useCompositeStore(); * * @@ -96,7 +92,6 @@ export const Composite = Object.assign( Ariakit.Composite, { * @see https://ariakit.org/reference/composite-item * @example * ```jsx - * const useCompositeStore = useCompositeStore(); * const store = useCompositeStore(); * * Item 1 @@ -113,7 +108,6 @@ export const Composite = Object.assign( Ariakit.Composite, { * @see https://ariakit.org/reference/composite-row * @example * ```jsx - * const useCompositeStore = useCompositeStore(); * const store = useCompositeStore(); * * From f8d6d18ddcb178eee620b58c2c1043a1b7480fec Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 11:03:31 +0200 Subject: [PATCH 27/39] Remove unnecessary display name --- packages/components/src/composite/legacy/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/src/composite/legacy/index.tsx b/packages/components/src/composite/legacy/index.tsx index d802d5eae377da..dffdc1a2066d47 100644 --- a/packages/components/src/composite/legacy/index.tsx +++ b/packages/components/src/composite/legacy/index.tsx @@ -155,7 +155,6 @@ const unproxiedCompositeGroup = forwardRef< const Component = role === 'row' ? Current.Row : Current.Group; return ; } ); -unproxiedCompositeGroup.displayName = 'CompositeGroup'; export const Composite = proxyComposite( Current, { baseId: 'id' } ); export const CompositeGroup = proxyComposite( unproxiedCompositeGroup ); From 70bb89cd6d5417fbea52df5c14fc022c4adf5e68 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 11:03:52 +0200 Subject: [PATCH 28/39] Assign display names via Object.assign to comply with TS and get correct results in Storybook --- packages/components/src/composite/index.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts index a3999e7f4790a3..a9a2ebceb88f92 100644 --- a/packages/components/src/composite/index.ts +++ b/packages/components/src/composite/index.ts @@ -28,17 +28,21 @@ import * as Ariakit from '@ariakit/react'; */ export const useCompositeStore = Ariakit.useCompositeStore; -const Group = Ariakit.CompositeGroup; -Group.displayName = 'Composite.Group'; +const Group = Object.assign( Ariakit.CompositeGroup, { + displayName: 'Composite.Group', +} ); -export const GroupLabel = Ariakit.CompositeGroupLabel; -GroupLabel.displayName = 'Composite.GroupLabel'; +export const GroupLabel = Object.assign( Ariakit.CompositeGroupLabel, { + displayName: 'Composite.GroupLabel', +} ); -export const Item = Ariakit.CompositeItem; -Item.displayName = 'Composite.Item'; +export const Item = Object.assign( Ariakit.CompositeItem, { + displayName: 'Composite.Item', +} ); -export const Row = Ariakit.CompositeRow; -Row.displayName = 'Composite.Row'; +export const Row = Object.assign( Ariakit.CompositeRow, { + displayName: 'Composite.Row', +} ); /** * Renders a composite widget. @@ -53,6 +57,7 @@ Row.displayName = 'Composite.Row'; * ``` */ export const Composite = Object.assign( Ariakit.Composite, { + displayName: 'Composite', /** * Renders a group element for composite items. * @see https://ariakit.org/reference/composite-group From d91a679a79418af2bbb1c1573b55da3159642532 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 11:15:59 +0200 Subject: [PATCH 29/39] Update subcomponent TS ignore comment to align with other components --- .../components/src/composite/stories/index.story.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/src/composite/stories/index.story.tsx b/packages/components/src/composite/stories/index.story.tsx index 0958f650cb2f76..5b8b461ba63736 100644 --- a/packages/components/src/composite/stories/index.story.tsx +++ b/packages/components/src/composite/stories/index.story.tsx @@ -18,15 +18,15 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { title: 'Components/Composite', component: UseCompositeStorePlaceholder, subcomponents: { - // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 Composite, - // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 'Composite.Group': Composite.Group, - // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 'Composite.GroupLabel': Composite.GroupLabel, - // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 'Composite.Row': Composite.Row, - // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents + // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 'Composite.Item': Composite.Item, }, parameters: { From 68650df4b22dbe506bbcc2e0d365c9d4d7195f3d Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 19:14:51 +0200 Subject: [PATCH 30/39] Remove unnecessary store prop in circular option picker Composite.Item should pick up the store from context without explicit prop --- .../src/circular-option-picker/circular-option-picker-option.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx index cb4d5ae6472668..35a2f427134f40 100644 --- a/packages/components/src/circular-option-picker/circular-option-picker-option.tsx +++ b/packages/components/src/circular-option-picker/circular-option-picker-option.tsx @@ -68,7 +68,6 @@ function UnforwardedOptionAsOption( ref={ forwardedRef } /> } - store={ compositeStore } id={ id } /> ); From 0b4cb3e3e11d822f92aef8f2b150f41e4c0836ba Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 19:16:04 +0200 Subject: [PATCH 31/39] Add first-party types, rewrite components with one unique forwardRef call --- packages/components/src/composite/index.ts | 132 --------------- packages/components/src/composite/index.tsx | 177 ++++++++++++++++++++ packages/components/src/composite/types.ts | 47 ++++++ 3 files changed, 224 insertions(+), 132 deletions(-) delete mode 100644 packages/components/src/composite/index.ts create mode 100644 packages/components/src/composite/index.tsx create mode 100644 packages/components/src/composite/types.ts diff --git a/packages/components/src/composite/index.ts b/packages/components/src/composite/index.ts deleted file mode 100644 index a9a2ebceb88f92..00000000000000 --- a/packages/components/src/composite/index.ts +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Composite is a component that may contain navigable items represented by - * Composite.Item. It's inspired by the WAI-ARIA Composite Role and implements - * all the keyboard navigation mechanisms to ensure that there's only one - * tab stop for the whole Composite element. This means that it can behave as - * a roving tabindex or aria-activedescendant container. - * - * @see https://ariakit.org/components/composite - */ - -/** - * External dependencies - */ -import * as Ariakit from '@ariakit/react'; - -/** - * Creates a composite store. - * @see https://ariakit.org/reference/use-composite-store - * @example - * ```jsx - * const store = useCompositeStore(); - * - * Item - * Item - * Item - * - * ``` - */ -export const useCompositeStore = Ariakit.useCompositeStore; - -const Group = Object.assign( Ariakit.CompositeGroup, { - displayName: 'Composite.Group', -} ); - -export const GroupLabel = Object.assign( Ariakit.CompositeGroupLabel, { - displayName: 'Composite.GroupLabel', -} ); - -export const Item = Object.assign( Ariakit.CompositeItem, { - displayName: 'Composite.Item', -} ); - -export const Row = Object.assign( Ariakit.CompositeRow, { - displayName: 'Composite.Row', -} ); - -/** - * Renders a composite widget. - * @see https://ariakit.org/reference/composite - * @example - * ```jsx - * const store = useCompositeStore(); - * - * Item 1 - * Item 2 - * - * ``` - */ -export const Composite = Object.assign( Ariakit.Composite, { - displayName: 'Composite', - /** - * Renders a group element for composite items. - * @see https://ariakit.org/reference/composite-group - * @example - * ```jsx - * const store = useCompositeStore(); - * - * - * Label - * Item 1 - * Item 2 - * - * - * ``` - */ - Group, - /** - * Renders a label in a composite group. This component must be wrapped with - * `Composite.Group` so the `aria-labelledby` prop is properly set on the - * composite group element. - * @see https://ariakit.org/reference/composite-group-label - * @example - * ```jsx - * const store = useCompositeStore(); - * - * - * Label - * Item 1 - * Item 2 - * - * - * ``` - */ - GroupLabel, - /** - * Renders a composite item. - * @see https://ariakit.org/reference/composite-item - * @example - * ```jsx - * const store = useCompositeStore(); - * - * Item 1 - * Item 2 - * Item 3 - * - * ``` - */ - Item, - /** - * Renders a composite row. Wrapping `Composite.Item` elements within - * `Composite.Row` will create a two-dimensional composite widget, such as a - * grid. - * @see https://ariakit.org/reference/composite-row - * @example - * ```jsx - * const store = useCompositeStore(); - * - * - * Item 1.1 - * Item 1.2 - * Item 1.3 - * - * - * Item 2.1 - * Item 2.2 - * Item 2.3 - * - * - * ``` - */ - Row, -} ); diff --git a/packages/components/src/composite/index.tsx b/packages/components/src/composite/index.tsx new file mode 100644 index 00000000000000..9496bdb9e98664 --- /dev/null +++ b/packages/components/src/composite/index.tsx @@ -0,0 +1,177 @@ +/** + * Composite is a component that may contain navigable items represented by + * Composite.Item. It's inspired by the WAI-ARIA Composite Role and implements + * all the keyboard navigation mechanisms to ensure that there's only one + * tab stop for the whole Composite element. This means that it can behave as + * a roving tabindex or aria-activedescendant container. + * + * @see https://ariakit.org/components/composite + */ + +/** + * External dependencies + */ +import * as Ariakit from '@ariakit/react'; + +/** + * WordPress dependencies + */ +import { forwardRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import type { WordPressComponentProps } from '../context'; +import type { + CompositeStoreProps, + CompositeProps, + CompositeGroupProps, + CompositeGroupLabelProps, + CompositeItemProps, + CompositeRowProps, +} from './types'; + +/** + * Creates a composite store. + * @param props + * @see https://ariakit.org/reference/use-composite-store + * @example + * ```jsx + * const store = useCompositeStore(); + * + * Item + * Item + * Item + * + * ``` + */ +export function useCompositeStore( props: CompositeStoreProps ) { + return Ariakit.useCompositeStore( props ); +} + +const Group = forwardRef< + HTMLDivElement, + WordPressComponentProps< CompositeGroupProps, 'div', false > +>( function CompositeGroup( props, ref ) { + return ; +} ); +Group.displayName = 'Composite.Group'; + +const GroupLabel = forwardRef< + HTMLDivElement, + WordPressComponentProps< CompositeGroupLabelProps, 'div', false > +>( function CompositeGroupLabel( props, ref ) { + return ; +} ); +GroupLabel.displayName = 'Composite.GroupLabel'; + +const Item = forwardRef< + HTMLButtonElement, + WordPressComponentProps< CompositeItemProps, 'button', false > +>( function CompositeItem( props, ref ) { + return ; +} ); +Item.displayName = 'Composite.Item'; + +const Row = forwardRef< + HTMLDivElement, + WordPressComponentProps< CompositeRowProps, 'div', false > +>( function CompositeRow( props, ref ) { + return ; +} ); +Row.displayName = 'Composite.Row'; + +/** + * Renders a composite widget. + * @see https://ariakit.org/reference/composite + * @example + * ```jsx + * const store = useCompositeStore(); + * + * Item 1 + * Item 2 + * + * ``` + */ +export const Composite = Object.assign( + forwardRef< + HTMLDivElement, + WordPressComponentProps< CompositeProps, 'div', false > + >( function CompositeRow( props, ref ) { + return ; + } ), + { + displayName: 'Composite', + /** + * Renders a group element for composite items. + * @see https://ariakit.org/reference/composite-group + * @example + * ```jsx + * const store = useCompositeStore(); + * + * + * Label + * Item 1 + * Item 2 + * + * + * ``` + */ + Group, + /** + * Renders a label in a composite group. This component must be wrapped with + * `Composite.Group` so the `aria-labelledby` prop is properly set on the + * composite group element. + * @see https://ariakit.org/reference/composite-group-label + * @example + * ```jsx + * const store = useCompositeStore(); + * + * + * Label + * Item 1 + * Item 2 + * + * + * ``` + */ + GroupLabel, + /** + * Renders a composite item. + * @see https://ariakit.org/reference/composite-item + * @example + * ```jsx + * const store = useCompositeStore(); + * + * Item 1 + * Item 2 + * Item 3 + * + * ``` + */ + Item, + /** + * Renders a composite row. Wrapping `Composite.Item` elements within + * `Composite.Row` will create a two-dimensional composite widget, such as a + * grid. + * @see https://ariakit.org/reference/composite-row + * @example + * ```jsx + * const store = useCompositeStore(); + * + * + * Item 1.1 + * Item 1.2 + * Item 1.3 + * + * + * Item 2.1 + * Item 2.2 + * Item 2.3 + * + * + * ``` + */ + Row, + } +); diff --git a/packages/components/src/composite/types.ts b/packages/components/src/composite/types.ts new file mode 100644 index 00000000000000..b544b048f8d051 --- /dev/null +++ b/packages/components/src/composite/types.ts @@ -0,0 +1,47 @@ +/** + * External dependencies + */ +import type * as Ariakit from '@ariakit/react'; + +export type CompositeStoreProps = Pick< + Ariakit.CompositeStoreProps, + | 'activeId' + | 'defaultActiveId' + | 'setActiveId' + | 'focusLoop' + | 'focusShift' + | 'focusWrap' + | 'virtualFocus' + | 'orientation' + | 'rtl' +>; + +export type CompositeProps = Pick< + Ariakit.CompositeProps, + 'render' | 'children' +> & { + /** + * Object returned by the `useCompositeStore` hook + */ + store?: Ariakit.CompositeProps[ 'store' ]; +}; + +export type CompositeGroupProps = Pick< + Ariakit.CompositeGroupProps, + 'render' | 'children' +>; + +export type CompositeGroupLabelProps = Pick< + Ariakit.CompositeGroupLabelProps, + 'render' | 'children' +>; + +export type CompositeItemProps = Pick< + Ariakit.CompositeItemProps, + 'render' | 'children' +>; + +export type CompositeRowProps = Pick< + Ariakit.CompositeRowProps, + 'render' | 'children' +>; From 9bafd47f89b20acdf6f956c1c6b476ea4d51cfef Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 19:16:24 +0200 Subject: [PATCH 32/39] Use the newly added types instead of using the Parameters<> util --- packages/components/src/composite/stories/utils.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/components/src/composite/stories/utils.tsx b/packages/components/src/composite/stories/utils.tsx index e71aa10a72a241..425fb9a905bcff 100644 --- a/packages/components/src/composite/stories/utils.tsx +++ b/packages/components/src/composite/stories/utils.tsx @@ -6,7 +6,7 @@ import type { StoryContext } from '@storybook/react'; /** * Internal dependencies */ -import type { useCompositeStore } from '..'; +import type { CompositeStoreProps } from '../types'; /** * Renders a composite widget. @@ -19,9 +19,7 @@ import type { useCompositeStore } from '..'; * * ``` */ -export function UseCompositeStorePlaceholder( - props: Parameters< typeof useCompositeStore > -) { +export function UseCompositeStorePlaceholder( props: CompositeStoreProps ) { return (
{ Object.entries( props ).map( ( [ name, value ] ) => ( From f511dc3f71e8760de24e8da97eee76fb5246abae Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 19:17:10 +0200 Subject: [PATCH 33/39] Fix Storybook story type --- packages/components/src/composite/stories/index.story.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/components/src/composite/stories/index.story.tsx b/packages/components/src/composite/stories/index.story.tsx index 5b8b461ba63736..ff7fd687665430 100644 --- a/packages/components/src/composite/stories/index.story.tsx +++ b/packages/components/src/composite/stories/index.story.tsx @@ -55,9 +55,11 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { }; export default meta; -export const Default: StoryFn< typeof Composite > = ( { ...initialState } ) => { +export const Default: StoryFn< typeof UseCompositeStorePlaceholder > = ( + storeProps +) => { const rtl = isRTL(); - const store = useCompositeStore( { rtl, ...initialState } ); + const store = useCompositeStore( { rtl, ...storeProps } ); return ( From 09c07afe4e35a0adf950c2b496f1a59b4c094b65 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 19:17:31 +0200 Subject: [PATCH 34/39] Remove unnecessary ts-expect-error --- packages/components/src/composite/legacy/stories/index.story.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/src/composite/legacy/stories/index.story.tsx b/packages/components/src/composite/legacy/stories/index.story.tsx index d3d3205afe714f..1b8e07e9bbf560 100644 --- a/packages/components/src/composite/legacy/stories/index.story.tsx +++ b/packages/components/src/composite/legacy/stories/index.story.tsx @@ -19,7 +19,6 @@ const meta: Meta< typeof UseCompositeStatePlaceholder > = { id: 'components-composite-unstable', component: UseCompositeStatePlaceholder, subcomponents: { - // @ts-expect-error Storybook doesn't like overloaded exports as subcomponents Composite, CompositeGroup, CompositeItem, From db9d27d3234f727bad23e88b2ec67bce32a44c5e Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 20:01:05 +0200 Subject: [PATCH 35/39] Use `CompositeStore` type directly --- packages/components/src/composite/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/src/composite/types.ts b/packages/components/src/composite/types.ts index b544b048f8d051..04c15e67688123 100644 --- a/packages/components/src/composite/types.ts +++ b/packages/components/src/composite/types.ts @@ -21,9 +21,9 @@ export type CompositeProps = Pick< 'render' | 'children' > & { /** - * Object returned by the `useCompositeStore` hook + * Object returned by the `useCompositeStore` hook. */ - store?: Ariakit.CompositeProps[ 'store' ]; + store?: Ariakit.CompositeStore; }; export type CompositeGroupProps = Pick< From 918ae6a5b2c8d6fd4e2b15ead318d2ed22c4f225 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Thu, 8 Aug 2024 20:01:16 +0200 Subject: [PATCH 36/39] Manual Storybook args table --- .../src/composite/stories/index.story.tsx | 161 ++++++++++++++++-- 1 file changed, 148 insertions(+), 13 deletions(-) diff --git a/packages/components/src/composite/stories/index.story.tsx b/packages/components/src/composite/stories/index.story.tsx index ff7fd687665430..ba9d3407812941 100644 --- a/packages/components/src/composite/stories/index.story.tsx +++ b/packages/components/src/composite/stories/index.story.tsx @@ -34,21 +34,156 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { canvas: { sourceState: 'shown' }, source: { transform }, extractArgTypes: ( component: React.FunctionComponent ) => { - const name = component.displayName; - const path = name - ?.replace( - /([a-z])([A-Z])/g, - ( _, a, b ) => `${ a }-${ b.toLowerCase() }` - ) - .toLowerCase(); - const url = `https://ariakit.org/reference/${ path }`; - return { - props: { - name: 'Props', - description: `See Ariakit docs for ${ name }`, - table: { type: { summary: undefined } }, + const commonArgTypes = { + render: { + name: 'render', + description: + 'Allows the component to be rendered as a different HTML element or React component. The value can be a React element or a function that takes in the original component props and gives back a React element with the props merged.', + table: { + type: { + summary: + 'RenderProp & { ref?: React.Ref | undefined; }> | React.ReactElement>', + }, + }, + // type: { required: true }, }, + children: { + name: 'children', + description: 'The contents of the component.', + table: { type: { summary: 'React.ReactNode' } }, + }, + }; + const argTypes = { + useCompositeStore: { + activeId: { + name: 'activeId', + description: + 'The current active item id. The active item is the element within the composite widget that has either DOM or virtual focus.', + table: { type: { summary: 'string | null' } }, + }, + defaultActiveId: { + name: 'defaultActiveId', + description: + 'The composite item id that should be active by default when the composite widget is rendered. If `null`, the composite element itself will have focus and users will be able to navigate to it using arrow keys. If `undefined`, the first enabled item will be focused.', + table: { type: { summary: 'string | null' } }, + }, + setActiveId: { + name: 'setActiveId', + description: + 'A callback that gets called when the activeId state changes.', + table: { + type: { + summary: + '((activeId: string | null | undefined) => void)', + }, + }, + }, + focusLoop: { + name: 'focusLoop', + description: + 'Determines how the focus behaves when the user reaches the end of the composite widget.', + table: { + defaultValue: { + summary: 'false', + }, + type: { + summary: + "boolean | 'horizontal' | 'vertical' | 'both'", + }, + }, + }, + focusShift: { + name: 'focusShift', + description: + "Works only on two-dimensional composite widgets. If enabled, moving up or down when there's no next item or when the next item is disabled will shift to the item right before it.", + table: { + defaultValue: { + summary: 'false', + }, + type: { + summary: 'boolean', + }, + }, + }, + focusWrap: { + name: 'focusWrap', + description: + 'Works only on two-dimensional composite widgets. If enabled, moving to the next item from the last one in a row or column will focus on the first item in the next row or column and vice-versa.', + table: { + defaultValue: { + summary: 'false', + }, + type: { + summary: 'boolean', + }, + }, + }, + virtualFocus: { + name: 'virtualFocus', + description: + 'If enabled, the composite element will act as an aria-activedescendant⁠ container instead of roving tabindex⁠. DOM focus will remain on the composite element while its items receive virtual focus. In both scenarios, the item in focus will carry the data-active-item attribute.', + table: { + defaultValue: { + summary: 'false', + }, + type: { + summary: 'boolean', + }, + }, + }, + orientation: { + name: 'orientation', + description: + "Defines the orientation of the composite widget. If the composite has a single row or column (one-dimensional), the orientation value determines which arrow keys can be used to move focus. It doesn't have any effect on two-dimensional composites.", + table: { + defaultValue: { + summary: "'both'", + }, + type: { + summary: + "'horizontal' | 'vertical' | 'both'", + }, + }, + }, + rtl: { + name: 'rtl', + description: + 'Determines how the next and previous functions will behave. If rtl is set to true, they will be inverted. This only affects the composite widget behavior. You still need to set dir="rtl" on HTML/CSS.', + table: { + defaultValue: { + summary: 'false', + }, + type: { + summary: 'boolean', + }, + }, + }, + }, + Composite: { + ...commonArgTypes, + store: { + name: 'store', + description: + 'Object returned by the `useCompositeStore` hook.', + table: { + type: { + summary: + 'CompositeStore', + }, + }, + }, + }, + 'Composite.Group': commonArgTypes, + 'Composite.GroupLabel': commonArgTypes, + 'Composite.Row': commonArgTypes, + 'Composite.Item': commonArgTypes, }; + + const name = component.displayName ?? 'useCompositeStore'; + + return name in argTypes + ? argTypes[ name as keyof typeof argTypes ] + : {}; }, }, }, From 7586d5445abd751b7551d1da00ec956be8794dd7 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 9 Aug 2024 11:29:12 +0200 Subject: [PATCH 37/39] Tweak display name fallback --- packages/components/src/composite/stories/index.story.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/composite/stories/index.story.tsx b/packages/components/src/composite/stories/index.story.tsx index ba9d3407812941..3fe84f2e315359 100644 --- a/packages/components/src/composite/stories/index.story.tsx +++ b/packages/components/src/composite/stories/index.story.tsx @@ -179,7 +179,7 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { 'Composite.Item': commonArgTypes, }; - const name = component.displayName ?? 'useCompositeStore'; + const name = component.displayName ?? ''; return name in argTypes ? argTypes[ name as keyof typeof argTypes ] From 176314ad019b88ec6e078caab6ed9e04f0f9f332 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 9 Aug 2024 11:29:17 +0200 Subject: [PATCH 38/39] README --- packages/components/src/composite/README.md | 136 +++++++++++++++++++- 1 file changed, 131 insertions(+), 5 deletions(-) diff --git a/packages/components/src/composite/README.md b/packages/components/src/composite/README.md index 31631281df3208..03c7e2fca7772a 100644 --- a/packages/components/src/composite/README.md +++ b/packages/components/src/composite/README.md @@ -17,34 +17,160 @@ const store = useCompositeStore(); ``` +## Hooks + +### `useCompositeStore` + +Creates a composite store. + +#### Props + +##### `activeId`: `string | null` + +The current active item id. The active item is the element within the composite widget that has either DOM or virtual focus. + +- Required: no + +##### `defaultActiveId`: `string | null` + +The composite item id that should be active by default when the composite widget is rendered. If `null`, the composite element itself will have focus and users will be able to navigate to it using arrow keys. If `undefined`, the first enabled item will be focused. + +- Required: no + +##### `setActiveId`: `((activeId: string | null | undefined) => void)` + +A callback that gets called when the activeId state changes. + +- Required: no + +##### `focusLoop`: `boolean | 'horizontal' | 'vertical' | 'both'` + +Determines how the focus behaves when the user reaches the end of the composite widget. + +- Required: no +- Default: `false` + +##### `focusShift`: `boolean` + +Works only on two-dimensional composite widgets. If enabled, moving up or down when there's no next item or when the next item is disabled will shift to the item right before it. + +- Required: no +- Default: `false` + +##### `focusWrap`: `boolean` + +Works only on two-dimensional composite widgets. If enabled, moving to the next item from the last one in a row or column will focus on the first item in the next row or column and vice-versa. + +- Required: no +- Default: `false` + +##### `virtualFocus`: `boolean` + +If enabled, the composite element will act as an aria-activedescendant⁠ container instead of roving tabindex⁠. DOM focus will remain on the composite element while its items receive virtual focus. In both scenarios, the item in focus will carry the data-active-item attribute. + +- Required: no +- Default: `false` + +##### `orientation`: `'horizontal' | 'vertical' | 'both'` + +Defines the orientation of the composite widget. If the composite has a single row or column (one-dimensional), the orientation value determines which arrow keys can be used to move focus. It doesn't have any effect on two-dimensional composites. + +- Required: no +- Default: `'both'` + +##### `rtl`: `boolean` + +Determines how the next and previous functions will behave. If rtl is set to true, they will be inverted. This only affects the composite widget behavior. You still need to set dir=`rtl` on HTML/CSS. + +- Required: no +- Default: `false` + ## Components ### `Composite` Renders a composite widget. -See the [Ariakit docs for the `Composite` component](https://ariakit.org/reference/composite). +#### Props + +##### `render`: `RenderProp & { ref?: React.Ref | undefined; }> | React.ReactElement>` + +Allows the component to be rendered as a different HTML element or React component. The value can be a React element or a function that takes in the original component props and gives back a React element with the props merged. + +- Required: no + +##### `children`: `React.ReactNode` + +The contents of the component. + +- Required: no + +##### `store`: `CompositeStore` + +Object returned by the `useCompositeStore` hook. + +- Required: no ### `Composite.Group` Renders a group element for composite items. -See the [Ariakit docs for the `CompositeGroup` component](https://ariakit.org/reference/composite-group). +##### `render`: `RenderProp & { ref?: React.Ref | undefined; }> | React.ReactElement>` + +Allows the component to be rendered as a different HTML element or React component. The value can be a React element or a function that takes in the original component props and gives back a React element with the props merged. + +- Required: no + +##### `children`: `React.ReactNode` + +The contents of the component. + +- Required: no ### `Composite.GroupLabel` Renders a label in a composite group. This component must be wrapped with `Composite.Group` so the `aria-labelledby` prop is properly set on the composite group element. -See the [Ariakit docs for the `CompositeGroupLabel` component](https://ariakit.org/reference/composite-group-label). +##### `render`: `RenderProp & { ref?: React.Ref | undefined; }> | React.ReactElement>` + +Allows the component to be rendered as a different HTML element or React component. The value can be a React element or a function that takes in the original component props and gives back a React element with the props merged. + +- Required: no + +##### `children`: `React.ReactNode` + +The contents of the component. + +- Required: no ### `Composite.Item` Renders a composite item. -See the [Ariakit docs for the `CompositeItem` component](https://ariakit.org/reference/composite-item). +##### `render`: `RenderProp & { ref?: React.Ref | undefined; }> | React.ReactElement>` + +Allows the component to be rendered as a different HTML element or React component. The value can be a React element or a function that takes in the original component props and gives back a React element with the props merged. + +- Required: no + +##### `children`: `React.ReactNode` + +The contents of the component. + +- Required: no ### `Composite.Row` Renders a composite row. Wrapping `Composite.Item` elements within `Composite.Row` will create a two-dimensional composite widget, such as a grid. -See the [Ariakit docs for the `CompositeItem` component](https://ariakit.org/reference/composite-row). +##### `render`: `RenderProp & { ref?: React.Ref | undefined; }> | React.ReactElement>` + +Allows the component to be rendered as a different HTML element or React component. The value can be a React element or a function that takes in the original component props and gives back a React element with the props merged. + +- Required: no + +##### `children`: `React.ReactNode` + +The contents of the component. + +- Required: no From c41ff65030050111e9ab65288ce6793fa515fa0a Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 9 Aug 2024 11:39:25 +0200 Subject: [PATCH 39/39] Mark `store` prop on `Composite` as required --- packages/components/src/composite/README.md | 12 ++++++------ .../components/src/composite/stories/index.story.tsx | 2 +- packages/components/src/composite/types.ts | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/components/src/composite/README.md b/packages/components/src/composite/README.md index 03c7e2fca7772a..59953f1273a054 100644 --- a/packages/components/src/composite/README.md +++ b/packages/components/src/composite/README.md @@ -93,6 +93,12 @@ Renders a composite widget. #### Props +##### `store`: `CompositeStore` + +Object returned by the `useCompositeStore` hook. + +- Required: yes + ##### `render`: `RenderProp & { ref?: React.Ref | undefined; }> | React.ReactElement>` Allows the component to be rendered as a different HTML element or React component. The value can be a React element or a function that takes in the original component props and gives back a React element with the props merged. @@ -105,12 +111,6 @@ The contents of the component. - Required: no -##### `store`: `CompositeStore` - -Object returned by the `useCompositeStore` hook. - -- Required: no - ### `Composite.Group` Renders a group element for composite items. diff --git a/packages/components/src/composite/stories/index.story.tsx b/packages/components/src/composite/stories/index.story.tsx index 3fe84f2e315359..b143c1f7db05f7 100644 --- a/packages/components/src/composite/stories/index.story.tsx +++ b/packages/components/src/composite/stories/index.story.tsx @@ -45,7 +45,6 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { 'RenderProp & { ref?: React.Ref | undefined; }> | React.ReactElement>', }, }, - // type: { required: true }, }, children: { name: 'children', @@ -171,6 +170,7 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = { 'CompositeStore', }, }, + type: { required: true }, }, }, 'Composite.Group': commonArgTypes, diff --git a/packages/components/src/composite/types.ts b/packages/components/src/composite/types.ts index 04c15e67688123..438d1caaa94f8a 100644 --- a/packages/components/src/composite/types.ts +++ b/packages/components/src/composite/types.ts @@ -23,7 +23,7 @@ export type CompositeProps = Pick< /** * Object returned by the `useCompositeStore` hook. */ - store?: Ariakit.CompositeStore; + store: Ariakit.CompositeStore; }; export type CompositeGroupProps = Pick<