@commercetools/nimbus 0.0.1 → 0.0.3-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1412 -0
- package/dist/index.js +22451 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +27 -0
- package/dist/index.umd.cjs.map +1 -0
- package/package.json +74 -40
- package/.storybook/apca-check/index.ts +0 -150
- package/.storybook/main.ts +0 -64
- package/.storybook/preview.tsx +0 -92
- package/.storybook/vitest.setup.ts +0 -13
- package/docs/architecture-decisions/adr-0001-consumer-component-apis.md +0 -177
- package/docs/architecture-decisions/adr-0002-compound-component-extraction.md +0 -82
- package/src/components/accordion/accordion-context.tsx +0 -17
- package/src/components/accordion/accordion.mdx +0 -172
- package/src/components/accordion/accordion.recipe.tsx +0 -98
- package/src/components/accordion/accordion.slots.tsx +0 -39
- package/src/components/accordion/accordion.stories.tsx +0 -188
- package/src/components/accordion/accordion.tsx +0 -16
- package/src/components/accordion/accordion.types.tsx +0 -54
- package/src/components/accordion/components/accordion-content.tsx +0 -28
- package/src/components/accordion/components/accordion-group.tsx +0 -27
- package/src/components/accordion/components/accordion-header.tsx +0 -63
- package/src/components/accordion/components/accordion-item.tsx +0 -87
- package/src/components/accordion/index.ts +0 -2
- package/src/components/alert/alert.mdx +0 -92
- package/src/components/alert/alert.recipe.tsx +0 -65
- package/src/components/alert/alert.slots.tsx +0 -46
- package/src/components/alert/alert.stories.tsx +0 -308
- package/src/components/alert/alert.tsx +0 -18
- package/src/components/alert/alert.types.tsx +0 -70
- package/src/components/alert/components/alert.actions.tsx +0 -27
- package/src/components/alert/components/alert.description.tsx +0 -27
- package/src/components/alert/components/alert.dismiss-button.tsx +0 -41
- package/src/components/alert/components/alert.root.tsx +0 -92
- package/src/components/alert/components/alert.title.tsx +0 -29
- package/src/components/alert/index.ts +0 -2
- package/src/components/avatar/avatar.mdx +0 -80
- package/src/components/avatar/avatar.recipe.tsx +0 -36
- package/src/components/avatar/avatar.slots.tsx +0 -16
- package/src/components/avatar/avatar.stories.tsx +0 -136
- package/src/components/avatar/avatar.tsx +0 -34
- package/src/components/avatar/avatar.types.ts +0 -33
- package/src/components/avatar/index.ts +0 -2
- package/src/components/badge/badge.mdx +0 -91
- package/src/components/badge/badge.recipe.tsx +0 -72
- package/src/components/badge/badge.slots.tsx +0 -8
- package/src/components/badge/badge.stories.tsx +0 -124
- package/src/components/badge/badge.tsx +0 -35
- package/src/components/badge/badge.types.tsx +0 -40
- package/src/components/badge/index.ts +0 -2
- package/src/components/bleed/bleed.tsx +0 -1
- package/src/components/bleed/index.ts +0 -1
- package/src/components/box/box.mdx +0 -115
- package/src/components/box/box.stories.tsx +0 -71
- package/src/components/box/box.tsx +0 -11
- package/src/components/box/index.ts +0 -1
- package/src/components/button/button.mdx +0 -169
- package/src/components/button/button.recipe.ts +0 -185
- package/src/components/button/button.slots.tsx +0 -45
- package/src/components/button/button.stories.tsx +0 -369
- package/src/components/button/button.tsx +0 -37
- package/src/components/button/button.types.ts +0 -14
- package/src/components/button/index.ts +0 -2
- package/src/components/card/card.mdx +0 -92
- package/src/components/card/card.recipe.tsx +0 -71
- package/src/components/card/card.slots.tsx +0 -50
- package/src/components/card/card.stories.tsx +0 -175
- package/src/components/card/card.tsx +0 -9
- package/src/components/card/card.types.ts +0 -22
- package/src/components/card/components/card.content.tsx +0 -29
- package/src/components/card/components/card.header.tsx +0 -28
- package/src/components/card/components/card.root.tsx +0 -62
- package/src/components/card/index.ts +0 -2
- package/src/components/checkbox/checkbox.mdx +0 -78
- package/src/components/checkbox/checkbox.recipe.tsx +0 -116
- package/src/components/checkbox/checkbox.slots.tsx +0 -33
- package/src/components/checkbox/checkbox.stories.tsx +0 -200
- package/src/components/checkbox/checkbox.tsx +0 -77
- package/src/components/checkbox/checkbox.types.tsx +0 -22
- package/src/components/checkbox/index.ts +0 -2
- package/src/components/code/code.mdx +0 -17
- package/src/components/code/code.recipe.ts +0 -63
- package/src/components/code/code.tsx +0 -1
- package/src/components/code/index.ts +0 -1
- package/src/components/dialog/dialog.mdx +0 -20
- package/src/components/dialog/dialog.recipe.ts +0 -254
- package/src/components/dialog/dialog.tsx +0 -61
- package/src/components/dialog/index.ts +0 -1
- package/src/components/em/em.mdx +0 -17
- package/src/components/em/em.tsx +0 -1
- package/src/components/em/index.ts +0 -1
- package/src/components/flex/flex.mdx +0 -41
- package/src/components/flex/flex.tsx +0 -1
- package/src/components/flex/index.ts +0 -1
- package/src/components/grid/grid.mdx +0 -156
- package/src/components/grid/grid.stories.tsx +0 -151
- package/src/components/grid/grid.tsx +0 -29
- package/src/components/grid/index.ts +0 -1
- package/src/components/heading/heading.mdx +0 -23
- package/src/components/heading/heading.recipe.ts +0 -49
- package/src/components/heading/heading.tsx +0 -1
- package/src/components/heading/index.ts +0 -1
- package/src/components/highlight/highlight.mdx +0 -18
- package/src/components/highlight/highlight.tsx +0 -1
- package/src/components/highlight/index.ts +0 -1
- package/src/components/icon-button/icon-button.mdx +0 -98
- package/src/components/icon-button/icon-button.stories.tsx +0 -188
- package/src/components/icon-button/icon-button.tsx +0 -21
- package/src/components/icon-button/icon-button.types.tsx +0 -10
- package/src/components/icon-button/index.ts +0 -2
- package/src/components/index.ts +0 -33
- package/src/components/input/index.ts +0 -1
- package/src/components/input/input.mdx +0 -20
- package/src/components/input/input.recipe.ts +0 -95
- package/src/components/input/input.tsx +0 -1
- package/src/components/input-group/index.ts +0 -1
- package/src/components/input-group/input-group.mdx +0 -20
- package/src/components/input-group/input-group.tsx +0 -44
- package/src/components/kbd/index.ts +0 -1
- package/src/components/kbd/kbd.mdx +0 -18
- package/src/components/kbd/kbd.recipe.ts +0 -57
- package/src/components/kbd/kbd.tsx +0 -1
- package/src/components/link/index.ts +0 -2
- package/src/components/link/link.mdx +0 -77
- package/src/components/link/link.recipe.ts +0 -52
- package/src/components/link/link.slots.tsx +0 -29
- package/src/components/link/link.stories.tsx +0 -204
- package/src/components/link/link.tsx +0 -38
- package/src/components/link/link.types.tsx +0 -26
- package/src/components/list/index.ts +0 -1
- package/src/components/list/list.mdx +0 -18
- package/src/components/list/list.recipe.ts +0 -68
- package/src/components/list/list.tsx +0 -9
- package/src/components/loading-spinner/index.ts +0 -2
- package/src/components/loading-spinner/loading-spinner.mdx +0 -92
- package/src/components/loading-spinner/loading-spinner.recipe.tsx +0 -70
- package/src/components/loading-spinner/loading-spinner.slots.tsx +0 -38
- package/src/components/loading-spinner/loading-spinner.stories.tsx +0 -97
- package/src/components/loading-spinner/loading-spinner.tsx +0 -50
- package/src/components/loading-spinner/loading-spinner.types.tsx +0 -21
- package/src/components/nimbus-provider/color-mode.tsx +0 -32
- package/src/components/nimbus-provider/index.ts +0 -2
- package/src/components/nimbus-provider/nimbus-provider.mdx +0 -21
- package/src/components/nimbus-provider/nimbus-provider.tsx +0 -51
- package/src/components/select/components/select.clear-button.tsx +0 -31
- package/src/components/select/components/select.option-group.tsx +0 -48
- package/src/components/select/components/select.option.tsx +0 -21
- package/src/components/select/components/select.options.tsx +0 -23
- package/src/components/select/components/select.root.tsx +0 -81
- package/src/components/select/index.ts +0 -2
- package/src/components/select/select.mdx +0 -170
- package/src/components/select/select.recipe.tsx +0 -216
- package/src/components/select/select.slots.tsx +0 -58
- package/src/components/select/select.stories.tsx +0 -841
- package/src/components/select/select.tsx +0 -18
- package/src/components/select/select.types.tsx +0 -37
- package/src/components/simple-grid/index.ts +0 -1
- package/src/components/simple-grid/simple-grid.mdx +0 -133
- package/src/components/simple-grid/simple-grid.stories.tsx +0 -143
- package/src/components/simple-grid/simple-grid.tsx +0 -31
- package/src/components/stack/index.ts +0 -1
- package/src/components/stack/stack.mdx +0 -88
- package/src/components/stack/stack.stories.tsx +0 -82
- package/src/components/stack/stack.tsx +0 -15
- package/src/components/table/index.ts +0 -1
- package/src/components/table/table.mdx +0 -23
- package/src/components/table/table.recipe.ts +0 -170
- package/src/components/table/table.tsx +0 -43
- package/src/components/text/index.ts +0 -1
- package/src/components/text/text.mdx +0 -244
- package/src/components/text/text.tsx +0 -23
- package/src/components/text-input/index.ts +0 -2
- package/src/components/text-input/text-input.mdx +0 -118
- package/src/components/text-input/text-input.recipe.tsx +0 -68
- package/src/components/text-input/text-input.slots.tsx +0 -24
- package/src/components/text-input/text-input.stories.tsx +0 -282
- package/src/components/text-input/text-input.tsx +0 -39
- package/src/components/text-input/text-input.types.ts +0 -7
- package/src/components/toggle-button-group/components/toggle-button-group.button.tsx +0 -14
- package/src/components/toggle-button-group/components/toggle-button-group.root.tsx +0 -15
- package/src/components/toggle-button-group/index.ts +0 -2
- package/src/components/toggle-button-group/toggle-button-group.mdx +0 -94
- package/src/components/toggle-button-group/toggle-button-group.recipe.tsx +0 -64
- package/src/components/toggle-button-group/toggle-button-group.slots.tsx +0 -26
- package/src/components/toggle-button-group/toggle-button-group.stories.tsx +0 -311
- package/src/components/toggle-button-group/toggle-button-group.tsx +0 -12
- package/src/components/toggle-button-group/toggle-button-group.types.tsx +0 -62
- package/src/components/tooltip/index.ts +0 -4
- package/src/components/tooltip/make-element-focusable.stories.tsx +0 -56
- package/src/components/tooltip/make-element-focusable.tsx +0 -57
- package/src/components/tooltip/tooltip-trigger.stories.tsx +0 -157
- package/src/components/tooltip/tooltip-trigger.tsx +0 -15
- package/src/components/tooltip/tooltip.mdx +0 -48
- package/src/components/tooltip/tooltip.recipe.ts +0 -26
- package/src/components/tooltip/tooltip.slots.ts +0 -35
- package/src/components/tooltip/tooltip.stories.tsx +0 -139
- package/src/components/tooltip/tooltip.tsx +0 -31
- package/src/components/tooltip/tooltip.types.ts +0 -44
- package/src/components/visually-hidden/index.ts +0 -1
- package/src/components/visually-hidden/visually-hidden.mdx +0 -61
- package/src/components/visually-hidden/visually-hidden.stories.tsx +0 -124
- package/src/components/visually-hidden/visually-hidden.tsx +0 -18
- package/src/docs/accessibility.mdx +0 -21
- package/src/docs/background.mdx +0 -154
- package/src/docs/border.mdx +0 -226
- package/src/docs/changelog.mdx +0 -17
- package/src/docs/components-layout.mdx +0 -22
- package/src/docs/components.mdx +0 -17
- package/src/docs/data-display.mdx +0 -23
- package/src/docs/display.mdx +0 -55
- package/src/docs/effects.mdx +0 -73
- package/src/docs/feedback.mdx +0 -22
- package/src/docs/filters.mdx +0 -268
- package/src/docs/flex-and-grid.mdx +0 -445
- package/src/docs/forms.mdx +0 -22
- package/src/docs/generated/index.mdx +0 -16
- package/src/docs/getting-started.mdx +0 -17
- package/src/docs/home.mdx +0 -56
- package/src/docs/hooks.mdx +0 -16
- package/src/docs/inputs.mdx +0 -21
- package/src/docs/installation.mdx +0 -60
- package/src/docs/interactivity.mdx +0 -278
- package/src/docs/known-issues.mdx +0 -19
- package/src/docs/layout.mdx +0 -301
- package/src/docs/list.mdx +0 -82
- package/src/docs/markdown.mdx +0 -234
- package/src/docs/media.mdx +0 -22
- package/src/docs/naivgation.mdx +0 -22
- package/src/docs/playground.mdx +0 -16
- package/src/docs/rfcs-component-structure-rfcs.mdx +0 -17
- package/src/docs/rfcs-component-structure.mdx +0 -74
- package/src/docs/rfcs-hook-structure.mdx +0 -59
- package/src/docs/sizing.mdx +0 -210
- package/src/docs/spacing.mdx +0 -193
- package/src/docs/style-props-typography.mdx +0 -373
- package/src/docs/style-props.mdx +0 -15
- package/src/docs/svg.mdx +0 -58
- package/src/docs/tables.mdx +0 -95
- package/src/docs/toc.mdx +0 -39
- package/src/docs/tokens/animations.mdx +0 -68
- package/src/docs/tokens/aspect-ratios.mdx +0 -21
- package/src/docs/tokens/blurs.mdx +0 -20
- package/src/docs/tokens/borders.mdx +0 -25
- package/src/docs/tokens/breakpoints.mdx +0 -35
- package/src/docs/tokens/colors.mdx +0 -86
- package/src/docs/tokens/cursors.mdx +0 -21
- package/src/docs/tokens/radii.mdx +0 -23
- package/src/docs/tokens/shadows.mdx +0 -21
- package/src/docs/tokens/sizes.mdx +0 -54
- package/src/docs/tokens/spacing.mdx +0 -35
- package/src/docs/tokens/typography.mdx +0 -61
- package/src/docs/tokens/z-indices.mdx +0 -23
- package/src/docs/tokens-other.mdx +0 -17
- package/src/docs/tokens.mdx +0 -16
- package/src/docs/transforms.mdx +0 -150
- package/src/docs/transitions.mdx +0 -164
- package/src/docs/typography.mdx +0 -17
- package/src/docs/utilities.mdx +0 -17
- package/src/hooks/index.ts +0 -2
- package/src/hooks/use-copy-to-clipboard/use-copy-to-clipboard.mdx +0 -54
- package/src/hooks/use-copy-to-clipboard/use-copy-to-clipboard.ts +0 -1
- package/src/hooks/use-hotkeys/use-hotkeys.mdx +0 -48
- package/src/hooks/use-hotkeys/use-hotkeys.stories.tsx +0 -69
- package/src/hooks/use-hotkeys/use-hotkeys.ts +0 -1
- package/src/index.ts +0 -3
- package/src/test/utils.tsx +0 -20
- package/src/theme/animation-styles.ts +0 -52
- package/src/theme/breakpoints.ts +0 -32
- package/src/theme/global-css.ts +0 -53
- package/src/theme/index.ts +0 -35
- package/src/theme/keyframes.ts +0 -192
- package/src/theme/layer-styles.ts +0 -12
- package/src/theme/recipes/index.ts +0 -21
- package/src/theme/semantic-tokens/colors.ts +0 -55
- package/src/theme/semantic-tokens/index.ts +0 -9
- package/src/theme/semantic-tokens/radii.ts +0 -3
- package/src/theme/semantic-tokens/shadows.ts +0 -4
- package/src/theme/slot-recipes/index.ts +0 -15
- package/src/theme/text-styles.ts +0 -8
- package/src/theme/tokens/animations.ts +0 -4
- package/src/theme/tokens/aspect-ratios.ts +0 -5
- package/src/theme/tokens/blurs.ts +0 -5
- package/src/theme/tokens/borders.ts +0 -4
- package/src/theme/tokens/colors.ts +0 -8
- package/src/theme/tokens/cursor.ts +0 -4
- package/src/theme/tokens/durations.ts +0 -4
- package/src/theme/tokens/easings.ts +0 -4
- package/src/theme/tokens/font-sizes.ts +0 -4
- package/src/theme/tokens/font-weights.ts +0 -4
- package/src/theme/tokens/fonts.ts +0 -4
- package/src/theme/tokens/index.ts +0 -57
- package/src/theme/tokens/letter-spacings.ts +0 -24
- package/src/theme/tokens/line-heights.ts +0 -4
- package/src/theme/tokens/radii.ts +0 -4
- package/src/theme/tokens/sizes.ts +0 -120
- package/src/theme/tokens/spacing.ts +0 -4
- package/src/theme/tokens/z-index.ts +0 -4
- package/src/utils/extractStyleProps.ts +0 -26
- package/src/utils/fixedForwardRef.ts +0 -17
- package/tsconfig.json +0 -38
- package/vite.config.ts +0 -54
- package/vitest.config.ts +0 -50
|
@@ -1,841 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
-
import { Select } from "./select";
|
|
3
|
-
import { Text, Stack, Box } from "@/components";
|
|
4
|
-
import type { Key } from "react-aria";
|
|
5
|
-
import { useState } from "react";
|
|
6
|
-
import { type SelectRootProps } from "./select.types";
|
|
7
|
-
import { userEvent, within, expect, fn } from "@storybook/test";
|
|
8
|
-
|
|
9
|
-
import { useAsyncList } from "react-stately";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Storybook metadata configuration
|
|
13
|
-
*/
|
|
14
|
-
const meta: Meta<typeof Select.Root> = {
|
|
15
|
-
title: "components/Select",
|
|
16
|
-
component: Select.Root,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default meta;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Story type for TypeScript support
|
|
23
|
-
* StoryObj provides type checking for our story configurations
|
|
24
|
-
*/
|
|
25
|
-
type Story = StoryObj<typeof Select.Root>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Test data
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
const selectSizes: SelectRootProps["size"][] = ["sm", "md"];
|
|
32
|
-
const selectVariants: SelectRootProps["variant"][] = ["outline", "ghost"];
|
|
33
|
-
|
|
34
|
-
const optionGroupOptions = [
|
|
35
|
-
{
|
|
36
|
-
id: "a",
|
|
37
|
-
name: "Fruit",
|
|
38
|
-
children: [
|
|
39
|
-
{ id: 1, name: "Apple" },
|
|
40
|
-
{ id: 2, name: "Banana" },
|
|
41
|
-
{ id: 3, name: "Orange" },
|
|
42
|
-
{ id: 4, name: "Honeydew" },
|
|
43
|
-
{ id: 5, name: "Grapes" },
|
|
44
|
-
{ id: 6, name: "Watermelon" },
|
|
45
|
-
{ id: 7, name: "Cantaloupe" },
|
|
46
|
-
{ id: 8, name: "Pear" },
|
|
47
|
-
],
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "b",
|
|
51
|
-
name: "Vegetable",
|
|
52
|
-
children: [
|
|
53
|
-
{ id: 9, name: "Cabbage" },
|
|
54
|
-
{ id: 10, name: "Broccoli" },
|
|
55
|
-
{ id: 11, name: "Carrots" },
|
|
56
|
-
{ id: 12, name: "Lettuce" },
|
|
57
|
-
{ id: 13, name: "Spinach" },
|
|
58
|
-
{ id: 14, name: "Bok Choy" },
|
|
59
|
-
{ id: 15, name: "Cauliflower" },
|
|
60
|
-
{ id: 16, name: "Potatoes" },
|
|
61
|
-
],
|
|
62
|
-
},
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Base story
|
|
67
|
-
* Demonstrates the most basic implementation, an uncontrolled
|
|
68
|
-
* select with a few options.
|
|
69
|
-
*/
|
|
70
|
-
export const Base: Story = {
|
|
71
|
-
render: () => {
|
|
72
|
-
return (
|
|
73
|
-
<Select.Root aria-label="Select a fruit" data-testid="select">
|
|
74
|
-
<Select.Options>
|
|
75
|
-
<Select.Option>Apples</Select.Option>
|
|
76
|
-
<Select.Option>Bananas</Select.Option>
|
|
77
|
-
<Select.Option>Oranges</Select.Option>
|
|
78
|
-
<Select.Option>Cherries</Select.Option>
|
|
79
|
-
</Select.Options>
|
|
80
|
-
</Select.Root>
|
|
81
|
-
);
|
|
82
|
-
},
|
|
83
|
-
play: async ({ canvasElement, step }) => {
|
|
84
|
-
const canvas = within(canvasElement);
|
|
85
|
-
const select = canvas.getByTestId("select");
|
|
86
|
-
const button = select.querySelector("button");
|
|
87
|
-
|
|
88
|
-
await step("Select is rendered with button", async () => {
|
|
89
|
-
await expect(button).toBeInTheDocument();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
await step("Select button can be focused with keyboard", async () => {
|
|
93
|
-
await userEvent.tab();
|
|
94
|
-
await expect(button).toHaveFocus();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
await step("Select opens on click", async () => {
|
|
98
|
-
await userEvent.click(button!);
|
|
99
|
-
// the popover is rendered via a react portal outside of the select root
|
|
100
|
-
// and can only be found by querying the document directly
|
|
101
|
-
const listbox = document.querySelector('[role="listbox"]');
|
|
102
|
-
await expect(listbox).toBeInTheDocument();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
await step("Options are displayed when open", async () => {
|
|
106
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
107
|
-
await expect(options.length).toBe(4);
|
|
108
|
-
await expect(options[0]).toHaveTextContent("Apples");
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
await step("Can select an option with click", async () => {
|
|
112
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
113
|
-
await userEvent.click(options[1]);
|
|
114
|
-
await expect(button).toHaveTextContent("Bananas");
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
await step("Value can be cleared with keyboard", async () => {
|
|
118
|
-
const clearButton = select.querySelectorAll("button")[1];
|
|
119
|
-
await userEvent.click(clearButton);
|
|
120
|
-
await expect(button).toHaveTextContent("Select an item");
|
|
121
|
-
});
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Controlled State
|
|
127
|
-
* The state of the select is controlled from the oustide.
|
|
128
|
-
* @see https://react-spectrum.adobe.com/react-aria/Select.html#selection
|
|
129
|
-
*/
|
|
130
|
-
const mockFn = fn();
|
|
131
|
-
export const ControlledState: Story = {
|
|
132
|
-
render: () => {
|
|
133
|
-
const options = [
|
|
134
|
-
{ id: 1, name: "Koala" },
|
|
135
|
-
{ id: 2, name: "Kangaroo" },
|
|
136
|
-
{ id: 3, name: "Platypus" },
|
|
137
|
-
{ id: 4, name: "Bald Eagle" },
|
|
138
|
-
{ id: 5, name: "Bison" },
|
|
139
|
-
{ id: 6, name: "Skunk" },
|
|
140
|
-
];
|
|
141
|
-
const [animal, setAnimal] = useState<Key>("Bison");
|
|
142
|
-
|
|
143
|
-
const onChangeRequest = (key: Key) => {
|
|
144
|
-
setAnimal(key);
|
|
145
|
-
mockFn();
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
return (
|
|
149
|
-
<Box>
|
|
150
|
-
<Box bg="blueAlpha.2" p="400" my="400" data-testid="value-display">
|
|
151
|
-
I'm a Box and not related to Select, but I know it's current value,
|
|
152
|
-
it's <mark>{animal ?? "not set"}</mark>.
|
|
153
|
-
</Box>
|
|
154
|
-
<Select.Root
|
|
155
|
-
defaultSelectedKey={animal}
|
|
156
|
-
selectedKey={animal}
|
|
157
|
-
onSelectionChange={onChangeRequest}
|
|
158
|
-
aria-label="Select your new pet"
|
|
159
|
-
data-testid="select"
|
|
160
|
-
>
|
|
161
|
-
<Select.Options items={options}>
|
|
162
|
-
{(item: { name: string }) => (
|
|
163
|
-
<Select.Option id={item.name}>{item.name}</Select.Option>
|
|
164
|
-
)}
|
|
165
|
-
</Select.Options>
|
|
166
|
-
</Select.Root>
|
|
167
|
-
</Box>
|
|
168
|
-
);
|
|
169
|
-
},
|
|
170
|
-
play: async ({ canvasElement, step }) => {
|
|
171
|
-
const canvas = within(canvasElement);
|
|
172
|
-
const select = canvas.getByTestId("select");
|
|
173
|
-
const valueDisplay = canvas.getByTestId("value-display");
|
|
174
|
-
const button = select.querySelector("button");
|
|
175
|
-
|
|
176
|
-
await step("Select displays the default value", async () => {
|
|
177
|
-
await expect(button).toHaveTextContent("Bison");
|
|
178
|
-
await expect(valueDisplay).toHaveTextContent("Bison");
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
await step(
|
|
182
|
-
"Selecting a different option updates external state",
|
|
183
|
-
async () => {
|
|
184
|
-
await userEvent.click(button!);
|
|
185
|
-
const listbox = document.querySelector('[role="listbox"]');
|
|
186
|
-
await expect(listbox).toBeInTheDocument();
|
|
187
|
-
|
|
188
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
189
|
-
await userEvent.click(options[0]); // Select Koala
|
|
190
|
-
|
|
191
|
-
await expect(button).toHaveTextContent("Koala");
|
|
192
|
-
await expect(valueDisplay).toHaveTextContent("Koala");
|
|
193
|
-
|
|
194
|
-
await expect(mockFn).toHaveBeenCalled();
|
|
195
|
-
}
|
|
196
|
-
);
|
|
197
|
-
},
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Async Loading
|
|
202
|
-
* @see https://react-spectrum.adobe.com/react-aria/Select.html#asynchronous-loading
|
|
203
|
-
*/
|
|
204
|
-
export const AsyncLoading: Story = {
|
|
205
|
-
render: () => {
|
|
206
|
-
const list = useAsyncList<{ id: number; name: string }>({
|
|
207
|
-
load: async () => {
|
|
208
|
-
// Simulate a network request
|
|
209
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
210
|
-
|
|
211
|
-
return {
|
|
212
|
-
items: [
|
|
213
|
-
{ id: 1, name: "Koala" },
|
|
214
|
-
{ id: 2, name: "Kangaroo" },
|
|
215
|
-
{ id: 3, name: "Platypus" },
|
|
216
|
-
{ id: 4, name: "Bald Eagle" },
|
|
217
|
-
{ id: 5, name: "Bison" },
|
|
218
|
-
{ id: 6, name: "Skunk" },
|
|
219
|
-
],
|
|
220
|
-
};
|
|
221
|
-
},
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
const [animal, setAnimal] = useState<Key>();
|
|
225
|
-
|
|
226
|
-
const isLoading = list.loadingState === "loading";
|
|
227
|
-
|
|
228
|
-
return (
|
|
229
|
-
<Box>
|
|
230
|
-
<Box bg="blueAlpha.2" p="400" my="400">
|
|
231
|
-
Here, an async list is being loaded. And while it is loading, Select
|
|
232
|
-
should go into an <mark>isLoading</mark> state (disabled and with a
|
|
233
|
-
spinner).
|
|
234
|
-
</Box>
|
|
235
|
-
<Select.Root
|
|
236
|
-
isLoading={isLoading}
|
|
237
|
-
selectedKey={animal}
|
|
238
|
-
onSelectionChange={setAnimal}
|
|
239
|
-
aria-label="Select your new pet"
|
|
240
|
-
data-testid="select"
|
|
241
|
-
>
|
|
242
|
-
<Select.Options items={list.items}>
|
|
243
|
-
{(item) => (
|
|
244
|
-
<Select.Option key={item.id} id={item.name}>
|
|
245
|
-
{item.name}
|
|
246
|
-
</Select.Option>
|
|
247
|
-
)}
|
|
248
|
-
</Select.Options>
|
|
249
|
-
</Select.Root>
|
|
250
|
-
</Box>
|
|
251
|
-
);
|
|
252
|
-
},
|
|
253
|
-
play: async ({ canvasElement, step }) => {
|
|
254
|
-
const canvas = within(canvasElement);
|
|
255
|
-
const select = canvas.getByTestId("select");
|
|
256
|
-
const button = select.querySelector("button");
|
|
257
|
-
|
|
258
|
-
await step("Select is rendered with button", async () => {
|
|
259
|
-
await expect(button).toBeInTheDocument();
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
await step("Select button can not be focused while loading", async () => {
|
|
263
|
-
await userEvent.tab();
|
|
264
|
-
await expect(button).not.toHaveFocus();
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
await step("Select can be focused when data is loaded", async () => {
|
|
268
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
269
|
-
await userEvent.tab();
|
|
270
|
-
await expect(button).toHaveFocus();
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
await step("Select opens on click", async () => {
|
|
274
|
-
await userEvent.click(button!);
|
|
275
|
-
// the popover is rendered via a react portal outside of the select root
|
|
276
|
-
// and can only be found by querying the document directly
|
|
277
|
-
const listbox = document.querySelector('[role="listbox"]');
|
|
278
|
-
await expect(listbox).toBeInTheDocument();
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
await step("Options are displayed when open", async () => {
|
|
282
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
283
|
-
await expect(options.length).toBe(6);
|
|
284
|
-
await expect(options[0]).toHaveTextContent("Koala");
|
|
285
|
-
});
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Disabled
|
|
291
|
-
* @see https://react-spectrum.adobe.com/react-aria/Select.html#disabled
|
|
292
|
-
*/
|
|
293
|
-
export const Disabled: Story = {
|
|
294
|
-
render: () => {
|
|
295
|
-
return (
|
|
296
|
-
<Select.Root
|
|
297
|
-
isDisabled
|
|
298
|
-
aria-label="Select some fruit(s)"
|
|
299
|
-
data-testid="select"
|
|
300
|
-
>
|
|
301
|
-
<Select.Options>
|
|
302
|
-
<Select.Option>Apples</Select.Option>
|
|
303
|
-
<Select.Option>Bananas</Select.Option>
|
|
304
|
-
<Select.Option>Oranges</Select.Option>
|
|
305
|
-
</Select.Options>
|
|
306
|
-
</Select.Root>
|
|
307
|
-
);
|
|
308
|
-
},
|
|
309
|
-
play: async ({ canvasElement, step }) => {
|
|
310
|
-
const canvas = within(canvasElement);
|
|
311
|
-
const select = canvas.getByTestId("select");
|
|
312
|
-
const button = select.querySelector("button");
|
|
313
|
-
|
|
314
|
-
await step("Disabled select has disabled attribute", async () => {
|
|
315
|
-
await expect(button).toHaveAttribute("disabled");
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
await step("Disabled select cannot be focused with keyboard", async () => {
|
|
319
|
-
await userEvent.tab();
|
|
320
|
-
await expect(button).not.toHaveFocus();
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
await step("Disabled select cannot be clicked to open", async () => {
|
|
324
|
-
await expect(button).toHaveStyle({ pointerEvents: "none" });
|
|
325
|
-
});
|
|
326
|
-
},
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
export const DisabledOptions: Story = {
|
|
330
|
-
render: () => {
|
|
331
|
-
return (
|
|
332
|
-
<Select.Root
|
|
333
|
-
disabledKeys={["2"]}
|
|
334
|
-
aria-label="Select some fruit(s)"
|
|
335
|
-
data-testid="select"
|
|
336
|
-
>
|
|
337
|
-
<Select.Options>
|
|
338
|
-
<Select.Option id="1">Apples</Select.Option>
|
|
339
|
-
<Select.Option id="2">Bananas</Select.Option>
|
|
340
|
-
<Select.Option id="3">Oranges</Select.Option>
|
|
341
|
-
</Select.Options>
|
|
342
|
-
</Select.Root>
|
|
343
|
-
);
|
|
344
|
-
},
|
|
345
|
-
play: async ({ canvasElement, step }) => {
|
|
346
|
-
const canvas = within(canvasElement);
|
|
347
|
-
const select = canvas.getByTestId("select");
|
|
348
|
-
const button = select.querySelector("button");
|
|
349
|
-
|
|
350
|
-
await step("Select can be opened", async () => {
|
|
351
|
-
await userEvent.click(button!);
|
|
352
|
-
const listbox = document.querySelector('[role="listbox"]');
|
|
353
|
-
await expect(listbox).toBeInTheDocument();
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
await step("Disabled option has aria-disabled attribute", async () => {
|
|
357
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
358
|
-
await expect(options[1]).toHaveAttribute("aria-disabled", "true");
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
await step("Enabled options can be selected", async () => {
|
|
362
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
363
|
-
await userEvent.click(options[0]); // Select Apples
|
|
364
|
-
await expect(button).toHaveTextContent("Apples");
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
await step("Disabled option cannot be selected", async () => {
|
|
368
|
-
await userEvent.click(button!); // Open select again
|
|
369
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
370
|
-
await userEvent.click(options[1]); // Try to select Bananas (disabled)
|
|
371
|
-
// Select should remain on previously selected option
|
|
372
|
-
await expect(button).toHaveTextContent("Apples");
|
|
373
|
-
});
|
|
374
|
-
},
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Invalid State
|
|
379
|
-
* @see https://react-spectrum.adobe.com/react-aria/Select.html#validation
|
|
380
|
-
*/
|
|
381
|
-
export const Invalid: Story = {
|
|
382
|
-
render: () => {
|
|
383
|
-
return (
|
|
384
|
-
<Select.Root
|
|
385
|
-
isInvalid
|
|
386
|
-
aria-label="Select some fruit(s)"
|
|
387
|
-
data-testid="select"
|
|
388
|
-
>
|
|
389
|
-
<Select.Options>
|
|
390
|
-
<Select.Option id="1">Apples</Select.Option>
|
|
391
|
-
<Select.Option id="2">Bananas</Select.Option>
|
|
392
|
-
<Select.Option id="3">Oranges</Select.Option>
|
|
393
|
-
</Select.Options>
|
|
394
|
-
</Select.Root>
|
|
395
|
-
);
|
|
396
|
-
},
|
|
397
|
-
play: async ({ canvasElement, step }) => {
|
|
398
|
-
const canvas = within(canvasElement);
|
|
399
|
-
const select = canvas.getByTestId("select");
|
|
400
|
-
const button = select.querySelector("button");
|
|
401
|
-
|
|
402
|
-
await step("Invalid select has data-invalid attribute", async () => {
|
|
403
|
-
await expect(select).toHaveAttribute("data-invalid", "true");
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
await step("Invalid select can still be opened and used", async () => {
|
|
407
|
-
await userEvent.click(button!);
|
|
408
|
-
const listbox = document.querySelector('[role="listbox"]');
|
|
409
|
-
await expect(listbox).toBeInTheDocument();
|
|
410
|
-
|
|
411
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
412
|
-
await userEvent.click(options[0]);
|
|
413
|
-
await expect(button).toHaveTextContent("Apples");
|
|
414
|
-
});
|
|
415
|
-
},
|
|
416
|
-
};
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Option Groups (Simple)
|
|
420
|
-
*/
|
|
421
|
-
export const OptionGroups: Story = {
|
|
422
|
-
render: () => {
|
|
423
|
-
return (
|
|
424
|
-
<Box>
|
|
425
|
-
<Select.Root aria-label="Select some fruit(s)" data-testid="select">
|
|
426
|
-
<Select.Options>
|
|
427
|
-
<Select.OptionGroup label="Fruits">
|
|
428
|
-
<Select.Option>Apples</Select.Option>
|
|
429
|
-
<Select.Option>Oranges</Select.Option>
|
|
430
|
-
<Select.Option>Bananas</Select.Option>
|
|
431
|
-
</Select.OptionGroup>
|
|
432
|
-
<Select.OptionGroup label="Vegetables">
|
|
433
|
-
<Select.Option>Carrots</Select.Option>
|
|
434
|
-
<Select.Option>Broccoli</Select.Option>
|
|
435
|
-
<Select.Option>Spinach</Select.Option>
|
|
436
|
-
</Select.OptionGroup>
|
|
437
|
-
</Select.Options>
|
|
438
|
-
</Select.Root>
|
|
439
|
-
</Box>
|
|
440
|
-
);
|
|
441
|
-
},
|
|
442
|
-
play: async ({ canvasElement, step }) => {
|
|
443
|
-
const canvas = within(canvasElement);
|
|
444
|
-
const select = canvas.getByTestId("select");
|
|
445
|
-
const button = select.querySelector("button");
|
|
446
|
-
|
|
447
|
-
await step("Select can be opened", async () => {
|
|
448
|
-
await userEvent.click(button!);
|
|
449
|
-
const listbox = document.querySelector('[role="listbox"]');
|
|
450
|
-
await expect(listbox).toBeInTheDocument();
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
await step("Option groups are rendered with proper roles", async () => {
|
|
454
|
-
const groups = document.querySelectorAll('[role="group"]');
|
|
455
|
-
await expect(groups.length).toBe(2);
|
|
456
|
-
|
|
457
|
-
const groupLabels = document.querySelectorAll('[role="presentation"]');
|
|
458
|
-
await expect(groupLabels[0]).toHaveTextContent("Fruits");
|
|
459
|
-
await expect(groupLabels[1]).toHaveTextContent("Vegetables");
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
await step("Options within groups can be selected", async () => {
|
|
463
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
464
|
-
await userEvent.click(options[1]); // Select Oranges from first group
|
|
465
|
-
await expect(button).toHaveTextContent("Oranges");
|
|
466
|
-
});
|
|
467
|
-
},
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Option Groups (Dynamic)
|
|
472
|
-
*/
|
|
473
|
-
export const OptionGroupsDynamic: Story = {
|
|
474
|
-
render: () => {
|
|
475
|
-
return (
|
|
476
|
-
<Box>
|
|
477
|
-
<Select.Root aria-label="Select something to eat">
|
|
478
|
-
<Select.Options items={optionGroupOptions}>
|
|
479
|
-
{(groupItem) => (
|
|
480
|
-
<Select.OptionGroup
|
|
481
|
-
key={groupItem.id}
|
|
482
|
-
label={groupItem.name}
|
|
483
|
-
items={groupItem.children}
|
|
484
|
-
>
|
|
485
|
-
{(optionItem) => (
|
|
486
|
-
<Select.Option key={optionItem.id}>
|
|
487
|
-
{optionItem.name}
|
|
488
|
-
</Select.Option>
|
|
489
|
-
)}
|
|
490
|
-
</Select.OptionGroup>
|
|
491
|
-
)}
|
|
492
|
-
</Select.Options>
|
|
493
|
-
</Select.Root>
|
|
494
|
-
</Box>
|
|
495
|
-
);
|
|
496
|
-
},
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
/**
|
|
500
|
-
* Label + additional descriptions
|
|
501
|
-
* demonstrates the use of additional option descriptions
|
|
502
|
-
* @see https://react-spectrum.adobe.com/react-aria/Select.html#text-slotss
|
|
503
|
-
*
|
|
504
|
-
* - test for textValue existance, otherwise typeahead won't work
|
|
505
|
-
*/
|
|
506
|
-
export const WithDescriptions: Story = {
|
|
507
|
-
render: () => {
|
|
508
|
-
return (
|
|
509
|
-
<Select.Root aria-label="Select some fruit(s)" data-testid="select">
|
|
510
|
-
<Select.Options>
|
|
511
|
-
{/** Variant A - plain html-tags with slot property */}
|
|
512
|
-
<Select.Option textValue="Apple">
|
|
513
|
-
<p slot="label">Apple</p>
|
|
514
|
-
<p slot="description">A classic and versatile fruit.</p>
|
|
515
|
-
</Select.Option>
|
|
516
|
-
{/** Variant B - text component with slot property */}
|
|
517
|
-
<Select.Option textValue="Banana">
|
|
518
|
-
<Text slot="label">Banana</Text>
|
|
519
|
-
<Text slot="description">A good source of potassium.</Text>
|
|
520
|
-
</Select.Option>
|
|
521
|
-
<Select.Option textValue="Oranges">
|
|
522
|
-
<Text slot="label">Oranges</Text>
|
|
523
|
-
<Text slot="description">Rich in vitamin C.</Text>
|
|
524
|
-
</Select.Option>
|
|
525
|
-
<Select.Option textValue="Strawberries">
|
|
526
|
-
<Text slot="label">Strawberries</Text>
|
|
527
|
-
<Text slot="description">Sweet and full of antioxidants.</Text>
|
|
528
|
-
</Select.Option>
|
|
529
|
-
<Select.Option textValue="Grapes">
|
|
530
|
-
<Text slot="label">Grapes</Text>
|
|
531
|
-
<Text slot="description">
|
|
532
|
-
Available in various colors and flavors.
|
|
533
|
-
</Text>
|
|
534
|
-
</Select.Option>
|
|
535
|
-
</Select.Options>
|
|
536
|
-
</Select.Root>
|
|
537
|
-
);
|
|
538
|
-
},
|
|
539
|
-
play: async ({ canvasElement, step }) => {
|
|
540
|
-
const canvas = within(canvasElement);
|
|
541
|
-
const select = canvas.getByTestId("select");
|
|
542
|
-
const button = select.querySelector("button");
|
|
543
|
-
|
|
544
|
-
await step("Select opens on click", async () => {
|
|
545
|
-
await userEvent.click(button!);
|
|
546
|
-
const listbox = document.querySelector('[role="listbox"]');
|
|
547
|
-
await expect(listbox).toBeInTheDocument();
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
await step("Options display labels and descriptions", async () => {
|
|
551
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
552
|
-
|
|
553
|
-
// Check first option has label and description
|
|
554
|
-
await expect(
|
|
555
|
-
options[0].querySelector('[slot="label"]')
|
|
556
|
-
).toHaveTextContent("Apple");
|
|
557
|
-
await expect(
|
|
558
|
-
options[0].querySelector('[slot="description"]')
|
|
559
|
-
).toHaveTextContent("A classic and versatile fruit.");
|
|
560
|
-
});
|
|
561
|
-
|
|
562
|
-
await step("Typeahead works with textValue", async () => {
|
|
563
|
-
// Type "b" to navigate to Banana
|
|
564
|
-
await userEvent.keyboard("ba");
|
|
565
|
-
const options = document.querySelectorAll('[role="option"]');
|
|
566
|
-
|
|
567
|
-
// Check that Banana option is focused (has aria-selected)
|
|
568
|
-
await expect(options[1]).toHaveAttribute("data-focused", "true");
|
|
569
|
-
});
|
|
570
|
-
},
|
|
571
|
-
};
|
|
572
|
-
|
|
573
|
-
/**
|
|
574
|
-
* Custom Widths
|
|
575
|
-
* custom widths for select-trigger button and popover
|
|
576
|
-
*/
|
|
577
|
-
export const CustomWidths: Story = {
|
|
578
|
-
render: () => {
|
|
579
|
-
return (
|
|
580
|
-
// width for the trigger can be specified on <Select.Root/>,
|
|
581
|
-
// width for popover can be specified on <Select.Options/>
|
|
582
|
-
<Select.Root width="196px" aria-label="Select something to eat">
|
|
583
|
-
<Select.Options width="512px">
|
|
584
|
-
<Select.Option>
|
|
585
|
-
Extraordinary long Menu Label that noone can read Extraordinary long
|
|
586
|
-
Menu Label that noone can read
|
|
587
|
-
</Select.Option>
|
|
588
|
-
<Select.OptionGroup label="Fruits">
|
|
589
|
-
<Select.Option>Apples</Select.Option>
|
|
590
|
-
<Select.Option>Oranges</Select.Option>
|
|
591
|
-
<Select.Option>Bananas</Select.Option>
|
|
592
|
-
</Select.OptionGroup>
|
|
593
|
-
<Select.OptionGroup label="Vegetables">
|
|
594
|
-
<Select.Option>Carrots</Select.Option>
|
|
595
|
-
<Select.Option>Broccoli</Select.Option>
|
|
596
|
-
<Select.Option>Spinach</Select.Option>
|
|
597
|
-
</Select.OptionGroup>
|
|
598
|
-
</Select.Options>
|
|
599
|
-
</Select.Root>
|
|
600
|
-
);
|
|
601
|
-
},
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* Super long and complex example
|
|
606
|
-
* Demonstrates a complex, long list of options in the middle
|
|
607
|
-
* of the screen. Where will the flyout go? We don't know.
|
|
608
|
-
*/
|
|
609
|
-
export const SuperLongAndComplex: Story = {
|
|
610
|
-
render: () => {
|
|
611
|
-
return (
|
|
612
|
-
<Box
|
|
613
|
-
display="flex"
|
|
614
|
-
w="100vw"
|
|
615
|
-
h="100vh"
|
|
616
|
-
alignItems="center"
|
|
617
|
-
justifyContent="center"
|
|
618
|
-
overflow="auto"
|
|
619
|
-
>
|
|
620
|
-
<Select.Root aria-label="Select something">
|
|
621
|
-
<Select.Options>
|
|
622
|
-
<Select.OptionGroup label="Fruits">
|
|
623
|
-
<Select.Option>
|
|
624
|
-
<Text slot="label">Apples</Text>
|
|
625
|
-
<Text slot="description">A crisp and juicy classic fruit.</Text>
|
|
626
|
-
</Select.Option>
|
|
627
|
-
<Select.Option>
|
|
628
|
-
<Text slot="label">Oranges</Text>
|
|
629
|
-
<Text slot="description">A sweet and tangy citrus fruit.</Text>
|
|
630
|
-
</Select.Option>
|
|
631
|
-
<Select.Option>
|
|
632
|
-
<Text slot="label">Bananas</Text>
|
|
633
|
-
<Text slot="description">
|
|
634
|
-
A soft and creamy tropical fruit.
|
|
635
|
-
</Text>
|
|
636
|
-
</Select.Option>
|
|
637
|
-
</Select.OptionGroup>
|
|
638
|
-
<Select.OptionGroup label="Vegetables">
|
|
639
|
-
<Select.Option>
|
|
640
|
-
<Text slot="label">Carrots</Text>
|
|
641
|
-
<Text slot="description">
|
|
642
|
-
A crunchy and nutritious root vegetable.
|
|
643
|
-
</Text>
|
|
644
|
-
</Select.Option>
|
|
645
|
-
<Select.Option>
|
|
646
|
-
<Text slot="label">Broccoli</Text>
|
|
647
|
-
<Text slot="description">
|
|
648
|
-
A green vegetable rich in vitamins.
|
|
649
|
-
</Text>
|
|
650
|
-
</Select.Option>
|
|
651
|
-
<Select.Option>
|
|
652
|
-
<Text slot="label">Spinach</Text>
|
|
653
|
-
<Text slot="description">
|
|
654
|
-
A leafy vegetable packed with iron.
|
|
655
|
-
</Text>
|
|
656
|
-
</Select.Option>
|
|
657
|
-
</Select.OptionGroup>
|
|
658
|
-
<Select.OptionGroup label="Grains">
|
|
659
|
-
<Select.Option>
|
|
660
|
-
<Text slot="label">Rice</Text>
|
|
661
|
-
<Text slot="description">
|
|
662
|
-
A staple grain consumed worldwide.
|
|
663
|
-
</Text>
|
|
664
|
-
</Select.Option>
|
|
665
|
-
<Select.Option>
|
|
666
|
-
<Text slot="label">Wheat</Text>
|
|
667
|
-
<Text slot="description">
|
|
668
|
-
A common grain used in bread and pasta.
|
|
669
|
-
</Text>
|
|
670
|
-
</Select.Option>
|
|
671
|
-
<Select.Option>
|
|
672
|
-
<Text slot="label">Oats</Text>
|
|
673
|
-
<Text slot="description">
|
|
674
|
-
A healthy grain often eaten for breakfast.
|
|
675
|
-
</Text>
|
|
676
|
-
</Select.Option>
|
|
677
|
-
</Select.OptionGroup>
|
|
678
|
-
<Select.OptionGroup label="Proteins">
|
|
679
|
-
<Select.Option>
|
|
680
|
-
<Text slot="label">Chicken</Text>
|
|
681
|
-
<Text slot="description">
|
|
682
|
-
A versatile and lean poultry protein.
|
|
683
|
-
</Text>
|
|
684
|
-
</Select.Option>
|
|
685
|
-
<Select.Option>
|
|
686
|
-
<Text slot="label">Beef</Text>
|
|
687
|
-
<Text slot="description">
|
|
688
|
-
A rich and flavorful red meat protein.
|
|
689
|
-
</Text>
|
|
690
|
-
</Select.Option>
|
|
691
|
-
<Select.Option>
|
|
692
|
-
<Text slot="label">Pork</Text>
|
|
693
|
-
<Text slot="description">
|
|
694
|
-
Another popular and versatile meat protein.
|
|
695
|
-
</Text>
|
|
696
|
-
</Select.Option>
|
|
697
|
-
</Select.OptionGroup>
|
|
698
|
-
</Select.Options>
|
|
699
|
-
</Select.Root>
|
|
700
|
-
</Box>
|
|
701
|
-
);
|
|
702
|
-
},
|
|
703
|
-
};
|
|
704
|
-
|
|
705
|
-
/**
|
|
706
|
-
* Variants and Sizes combined
|
|
707
|
-
*/
|
|
708
|
-
export const VariantsAndSizes: Story = {
|
|
709
|
-
render: () => {
|
|
710
|
-
const [isInvalid, setInvalid] = useState(false);
|
|
711
|
-
return (
|
|
712
|
-
<Stack>
|
|
713
|
-
{[{}, { isDisabled: true }, { isInvalid: true }].map((props) => (
|
|
714
|
-
<Stack
|
|
715
|
-
key={JSON.stringify({ props })}
|
|
716
|
-
bg="neutral.2"
|
|
717
|
-
onClick={() => setInvalid(!isInvalid)}
|
|
718
|
-
>
|
|
719
|
-
{selectVariants.map((variant) => (
|
|
720
|
-
<Stack alignItems="start" key={JSON.stringify({ variant })}>
|
|
721
|
-
<Text my="400" fontWeight="600">
|
|
722
|
-
{JSON.stringify({ variant, ...props })}
|
|
723
|
-
</Text>
|
|
724
|
-
{selectSizes.map((size) => (
|
|
725
|
-
<Select.Root
|
|
726
|
-
size={size}
|
|
727
|
-
variant={variant}
|
|
728
|
-
key={JSON.stringify({ size })}
|
|
729
|
-
{...props}
|
|
730
|
-
aria-label="Select something"
|
|
731
|
-
>
|
|
732
|
-
<Select.Options>
|
|
733
|
-
<Select.Option>
|
|
734
|
-
Extraordinary long Menu Label that noone can read
|
|
735
|
-
Extraordinary long Menu Label that noone can read
|
|
736
|
-
</Select.Option>
|
|
737
|
-
<Select.Option>Groupless Option No 1.</Select.Option>
|
|
738
|
-
<Select.Option>Groupless Option No 2.</Select.Option>
|
|
739
|
-
<Select.Option>
|
|
740
|
-
<Text slot="label">Groupless Option No 3.</Text>
|
|
741
|
-
<Text slot="description">
|
|
742
|
-
At least this one has a description.
|
|
743
|
-
</Text>
|
|
744
|
-
</Select.Option>
|
|
745
|
-
<Select.Option>
|
|
746
|
-
<Text slot="label">Super freaking long</Text>
|
|
747
|
-
<Text slot="description">
|
|
748
|
-
At least this one has a description.
|
|
749
|
-
</Text>
|
|
750
|
-
</Select.Option>
|
|
751
|
-
<Select.OptionGroup label="Fruits">
|
|
752
|
-
<Select.Option>
|
|
753
|
-
<Text slot="label">Apples</Text>
|
|
754
|
-
<Text slot="description">
|
|
755
|
-
A crisp and juicy classic fruit.
|
|
756
|
-
</Text>
|
|
757
|
-
</Select.Option>
|
|
758
|
-
<Select.Option>
|
|
759
|
-
<Text slot="label">Oranges</Text>
|
|
760
|
-
<Text slot="description">
|
|
761
|
-
A sweet and tangy citrus fruit.
|
|
762
|
-
</Text>
|
|
763
|
-
</Select.Option>
|
|
764
|
-
<Select.Option>
|
|
765
|
-
<Text slot="label">Bananas</Text>
|
|
766
|
-
<Text slot="description">
|
|
767
|
-
A soft and creamy tropical fruit.
|
|
768
|
-
</Text>
|
|
769
|
-
</Select.Option>
|
|
770
|
-
</Select.OptionGroup>
|
|
771
|
-
<Select.OptionGroup label="Vegetables">
|
|
772
|
-
<Select.Option>
|
|
773
|
-
<Text slot="label">Carrots</Text>
|
|
774
|
-
<Text slot="description">
|
|
775
|
-
A crunchy and nutritious root vegetable.
|
|
776
|
-
</Text>
|
|
777
|
-
</Select.Option>
|
|
778
|
-
<Select.Option>
|
|
779
|
-
<Text slot="label">Broccoli</Text>
|
|
780
|
-
<Text slot="description">
|
|
781
|
-
A green vegetable rich in vitamins.
|
|
782
|
-
</Text>
|
|
783
|
-
</Select.Option>
|
|
784
|
-
<Select.Option>
|
|
785
|
-
<Text slot="label">Spinach</Text>
|
|
786
|
-
<Text slot="description">
|
|
787
|
-
A leafy vegetable packed with iron.
|
|
788
|
-
</Text>
|
|
789
|
-
</Select.Option>
|
|
790
|
-
</Select.OptionGroup>
|
|
791
|
-
<Select.OptionGroup label="Grains">
|
|
792
|
-
<Select.Option>
|
|
793
|
-
<Text slot="label">Rice</Text>
|
|
794
|
-
<Text slot="description">
|
|
795
|
-
A staple grain consumed worldwide.
|
|
796
|
-
</Text>
|
|
797
|
-
</Select.Option>
|
|
798
|
-
<Select.Option>
|
|
799
|
-
<Text slot="label">Wheat</Text>
|
|
800
|
-
<Text slot="description">
|
|
801
|
-
A common grain used in bread and pasta.
|
|
802
|
-
</Text>
|
|
803
|
-
</Select.Option>
|
|
804
|
-
<Select.Option>
|
|
805
|
-
<Text slot="label">Oats</Text>
|
|
806
|
-
<Text slot="description">
|
|
807
|
-
A healthy grain often eaten for breakfast.
|
|
808
|
-
</Text>
|
|
809
|
-
</Select.Option>
|
|
810
|
-
</Select.OptionGroup>
|
|
811
|
-
<Select.OptionGroup label="Proteins">
|
|
812
|
-
<Select.Option>
|
|
813
|
-
<Text slot="label">Chicken</Text>
|
|
814
|
-
<Text slot="description">
|
|
815
|
-
A versatile and lean poultry protein.
|
|
816
|
-
</Text>
|
|
817
|
-
</Select.Option>
|
|
818
|
-
<Select.Option>
|
|
819
|
-
<Text slot="label">Beef</Text>
|
|
820
|
-
<Text slot="description">
|
|
821
|
-
A rich and flavorful red meat protein.
|
|
822
|
-
</Text>
|
|
823
|
-
</Select.Option>
|
|
824
|
-
<Select.Option>
|
|
825
|
-
<Text slot="label">Pork</Text>
|
|
826
|
-
<Text slot="description">
|
|
827
|
-
Another popular and versatile meat protein.
|
|
828
|
-
</Text>
|
|
829
|
-
</Select.Option>
|
|
830
|
-
</Select.OptionGroup>
|
|
831
|
-
</Select.Options>
|
|
832
|
-
</Select.Root>
|
|
833
|
-
))}
|
|
834
|
-
</Stack>
|
|
835
|
-
))}
|
|
836
|
-
</Stack>
|
|
837
|
-
))}
|
|
838
|
-
</Stack>
|
|
839
|
-
);
|
|
840
|
-
},
|
|
841
|
-
};
|