Skip to content

Commit

Permalink
useCompositeStore: update prop docs by using first-party docs
Browse files Browse the repository at this point in the history
Instead of using Ariakit's definitions and descriptions, we use our own
version, which a copy or Ariakit's without any references to Ariakit, its
examples, or any other props that we don't expose.
  • Loading branch information
ciampo committed Aug 9, 2024
1 parent 8709749 commit 929fb4c
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 35 deletions.
58 changes: 50 additions & 8 deletions packages/components/src/composite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ Creates a composite store.

##### `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. `null` represents the base composite element (the one with a composite role). Users will be able to navigate out of it using arrow keys.
The current active item `id`. The active item is the element within the composite widget that has either DOM or virtual focus (in case the `virtualFocus` prop is enabled).

- `null` represents the base composite element (the one with a [composite role](https://w3c.github.io/aria/#composite)). Users will be able to navigate out of it using arrow keys.
- If `activeId` is initially set to `null`, the base composite element itself will have focus and users will be able to navigate to it using arrow keys.

- Required: no

Expand All @@ -39,48 +42,87 @@ The composite item id that should be active by default when the composite widget

##### `setActiveId`: `((activeId: string | null | undefined) => void)`

A callback that gets called when the activeId state changes.
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.

On one-dimensional composite widgets:

- `true` loops from the last item to the first item and vice-versa.
- `horizontal` loops only if `orientation` is `horizontal` or not set.
- `vertical` loops only if `orientation` is `vertical` or not set.
- If `activeId` is initially set to `null`, the composite element will be focused in between the last and first items.

On two-dimensional composite widgets (ie. when using `CompositeRow`):

- `true` loops from the last row/column item to the first item in the same row/column and vice-versa. If it's the last item in the last row, it moves to the first item in the first row and vice-versa.
- `horizontal` loops only from the last row item to the first item in the same row.
- `vertical` loops only from the last column item to the first item in the column row.
- If `activeId` is initially set to `null`, vertical loop will have no effect as moving down from the last row or up from the first row will focus on the composite element.
- If `focusWrap` matches the value of `focusLoop`, it'll wrap between the last item in the last row or column and the first item in the first row or column and vice-versa.

- 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.
**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.
**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.

- `true` wraps between rows and columns.
- `horizontal` wraps only between rows.
- `vertical` wraps only between columns.
- If `focusLoop` matches the value of `focusWrap`, it'll wrap between the
last item in the last row or column and the first item in the first 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.
If enabled, the composite element will act as an [`aria-activedescendant`](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_focus_activedescendant)
container instead of [roving tabindex](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_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.
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:

- `both`: all arrow keys work.
- `horizontal`: only left and right arrow keys work.
- `vertical`: only up and down arrow keys work.

It doesn't have any effect on two-dimensional composites.

- Required: no
- Default: `'both'`
- 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.
Determines how the `store`'s `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`
Expand Down
62 changes: 47 additions & 15 deletions packages/components/src/composite/stories/index.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = {
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. `null` represents the base composite element (the one with a composite role). Users will be able to navigate out of it using arrow keys.',
description: `The current active item \`id\`. The active item is the element within the composite widget that has either DOM or virtual focus (in case the \`virtualFocus\` prop is enabled).
- \`null\` represents the base composite element (the one with a [composite role](https://w3c.github.io/aria/#composite)). Users will be able to navigate out of it using arrow keys.
- If \`activeId\` is initially set to \`null\`, the base composite element itself will have focus and users will be able to navigate to it using arrow keys.`,
table: { type: { summary: 'string | null' } },
},
defaultActiveId: {
Expand All @@ -87,7 +88,7 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = {
setActiveId: {
name: 'setActiveId',
description:
'A callback that gets called when the activeId state changes.',
'A callback that gets called when the `activeId` state changes.',
table: {
type: {
summary:
Expand All @@ -97,8 +98,20 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = {
},
focusLoop: {
name: 'focusLoop',
description:
'Determines how the focus behaves when the user reaches the end of the composite widget.',
description: `On one-dimensional composite widgets:
- \`true\` loops from the last item to the first item and vice-versa.
- \`horizontal\` loops only if \`orientation\` is \`horizontal\` or not set.
- \`vertical\` loops only if \`orientation\` is \`vertical\` or not set.
- If \`activeId\` is initially set to \`null\`, the composite element will be focused in between the last and first items.
On two-dimensional composite widgets (ie. when using \`CompositeRow\`):
- \`true\` loops from the last row/column item to the first item in the same row/column and vice-versa. If it's the last item in the last row, it moves to the first item in the first row and vice-versa.
- \`horizontal\` loops only from the last row item to the first item in the same row.
- \`vertical\` loops only from the last column item to the first item in the column row.
- If \`activeId\` is initially set to \`null\`, vertical loop will have no effect as moving down from the last row or up from the first row will focus on the composite element.
- If \`focusWrap\` matches the value of \`focusLoop\`, it'll wrap between the last item in the last row or column and the first item in the first row or column and vice-versa.`,
table: {
defaultValue: {
summary: 'false',
Expand All @@ -111,8 +124,9 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = {
},
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.",
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',
Expand All @@ -124,8 +138,17 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = {
},
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.',
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.
- \`true\` wraps between rows and columns.
- \`horizontal\` wraps only between rows.
- \`vertical\` wraps only between columns.
- If \`focusLoop\` matches the value of \`focusWrap\`, it'll wrap between the
last item in the last row or column and the first item in the first row or
column and vice-versa.`,
table: {
defaultValue: {
summary: 'false',
Expand All @@ -137,8 +160,11 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = {
},
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.',
description: `If enabled, the composite element will act as an [\`aria-activedescendant\`](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_focus_activedescendant)
container instead of [roving tabindex](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_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',
Expand All @@ -150,8 +176,13 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = {
},
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.",
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:
- \`both\`: all arrow keys work.
- \`horizontal\`: only left and right arrow keys work.
- \`vertical\`: only up and down arrow keys work.
It doesn't have any effect on two-dimensional composites.`,
table: {
defaultValue: {
summary: "'both'",
Expand All @@ -164,8 +195,9 @@ const meta: Meta< typeof UseCompositeStorePlaceholder > = {
},
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.',
description: `Determines how the \`store\`'s \`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',
Expand Down
128 changes: 116 additions & 12 deletions packages/components/src/composite/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,122 @@
*/
import type * as Ariakit from '@ariakit/react';

export type CompositeStoreProps = Pick<
Ariakit.CompositeStoreProps,
| 'activeId'
| 'defaultActiveId'
| 'setActiveId'
| 'focusLoop'
| 'focusShift'
| 'focusWrap'
| 'virtualFocus'
| 'orientation'
| 'rtl'
>;
export type CompositeStoreProps = {
/**
* The current active item `id`. The active item is the element within the
* composite widget that has either DOM or virtual focus (in case
* the `virtualFocus` prop is enabled).
* - `null` represents the base composite element (the one with a [composite
* role](https://w3c.github.io/aria/#composite)). Users will be able to
* navigate out of it using arrow keys.
* - If `activeId` is initially set to `null`, the base composite element
* itself will have focus and users will be able to navigate to it using
* arrow keys.
*/
activeId?: Ariakit.CompositeStoreProps[ 'activeId' ];
/**
* 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.
*/
defaultActiveId?: Ariakit.CompositeStoreProps[ 'defaultActiveId' ];
/**
* A callback that gets called when the `activeId` state changes.
*/
setActiveId?: Ariakit.CompositeStoreProps[ 'setActiveId' ];
/**
* Determines how the focus behaves when the user reaches the end of the
* composite widget.
*
* On one-dimensional composite widgets:
* - `true` loops from the last item to the first item and vice-versa.
* - `horizontal` loops only if `orientation` is `horizontal` or not set.
* - `vertical` loops only if `orientation` is `vertical` or not set.
* - If `activeId` is initially set to `null`, the composite element will
* be focused in between the last and first items.
*
* On two-dimensional composite widgets (ie. when using `CompositeRow`):
* - `true` loops from the last row/column item to the first item in the same
* row/column and vice-versa. If it's the last item in the last row, it
* moves to the first item in the first row and vice-versa.
* - `horizontal` loops only from the last row item to the first item in the
* same row.
* - `vertical` loops only from the last column item to the first item in the
* column row.
* - If `activeId` is initially set to `null`, vertical loop will have no
* effect as moving down from the last row or up from the first row will
* focus on the composite element.
* - If `focusWrap` matches the value of `focusLoop`, it'll wrap between the
* last item in the last row or column and the first item in the first row or
* column and vice-versa.
*
* @default false
*/
focusLoop?: Ariakit.CompositeStoreProps[ 'focusLoop' ];
/**
* **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.
* - `true` wraps between rows and columns.
* - `horizontal` wraps only between rows.
* - `vertical` wraps only between columns.
* - If `focusLoop` matches the value of `focusWrap`, it'll wrap between the
* last item in the last row or column and the first item in the first row or
* column and vice-versa.
*
* @default false
*/
focusWrap?: Ariakit.CompositeStoreProps[ 'focusWrap' ];
/**
* **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.
*
* @default false
*/
focusShift?: Ariakit.CompositeStoreProps[ 'focusShift' ];

/**
* If enabled, the composite element will act as an
* [`aria-activedescendant`](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_focus_activedescendant)
* container instead of [roving
* tabindex](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_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.
*
* @default false
*/
virtualFocus?: Ariakit.CompositeStoreProps[ 'virtualFocus' ];
/**
* 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:
* - `both`: all arrow keys work.
* - `horizontal`: only left and right arrow keys work.
* - `vertical`: only up and down arrow keys work.
*
* It doesn't have any effect on two-dimensional composites.
*
* @default "both"
*/
orientation?: Ariakit.CompositeStoreProps[ 'orientation' ];
/**
* Determines how the `store`'s `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.
*
* @default false
*/
rtl?: Ariakit.CompositeStoreProps[ 'rtl' ];
};

export type CompositeProps = Pick<
Ariakit.CompositeProps,
Expand Down

0 comments on commit 929fb4c

Please sign in to comment.