@wordpress/ui 0.5.1-next.v.0 → 0.6.0
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/CHANGELOG.md +5 -1
- package/build/box/box.cjs +2 -2
- package/build/box/box.cjs.map +2 -2
- package/build/button/button.cjs +18 -303
- package/build/button/button.cjs.map +3 -3
- package/build/form/primitives/constants.cjs +35 -0
- package/build/form/primitives/constants.cjs.map +7 -0
- package/build/form/primitives/field/description.cjs +6 -33
- package/build/form/primitives/field/description.cjs.map +2 -2
- package/build/form/primitives/field/details.cjs +6 -33
- package/build/form/primitives/field/details.cjs.map +2 -2
- package/build/form/primitives/field/label.cjs +6 -33
- package/build/form/primitives/field/label.cjs.map +2 -2
- package/build/form/primitives/field/root.cjs +6 -17
- package/build/form/primitives/field/root.cjs.map +2 -2
- package/build/form/primitives/fieldset/description.cjs +6 -33
- package/build/form/primitives/fieldset/description.cjs.map +2 -2
- package/build/form/primitives/fieldset/details.cjs +6 -33
- package/build/form/primitives/fieldset/details.cjs.map +2 -2
- package/build/form/primitives/fieldset/legend.cjs +6 -33
- package/build/form/primitives/fieldset/legend.cjs.map +2 -2
- package/build/form/primitives/fieldset/root.cjs +6 -16
- package/build/form/primitives/fieldset/root.cjs.map +2 -2
- package/build/form/primitives/index.cjs +8 -2
- package/build/form/primitives/index.cjs.map +2 -2
- package/build/form/primitives/input/index.cjs +31 -0
- package/build/form/primitives/input/index.cjs.map +7 -0
- package/build/form/primitives/input/input.cjs +82 -0
- package/build/form/primitives/input/input.cjs.map +7 -0
- package/build/form/primitives/input/types.cjs +19 -0
- package/build/form/primitives/input/types.cjs.map +7 -0
- package/build/form/primitives/input-layout/input-layout.cjs +12 -111
- package/build/form/primitives/input-layout/input-layout.cjs.map +3 -3
- package/build/form/primitives/input-layout/slot.cjs +6 -94
- package/build/form/primitives/input-layout/slot.cjs.map +2 -2
- package/build/form/primitives/select/index.cjs +40 -0
- package/build/form/primitives/select/index.cjs.map +7 -0
- package/build/form/primitives/select/item.cjs +98 -0
- package/build/form/primitives/select/item.cjs.map +7 -0
- package/build/form/primitives/select/popup.cjs +109 -0
- package/build/form/primitives/select/popup.cjs.map +7 -0
- package/build/form/primitives/select/root.cjs +35 -0
- package/build/form/primitives/select/root.cjs.map +7 -0
- package/build/form/primitives/select/trigger.cjs +116 -0
- package/build/form/primitives/select/trigger.cjs.map +7 -0
- package/build/form/primitives/select/types.cjs +19 -0
- package/build/form/primitives/select/types.cjs.map +7 -0
- package/build/index.cjs +19 -0
- package/build/index.cjs.map +2 -2
- package/build/lock-unlock.cjs +37 -0
- package/build/lock-unlock.cjs.map +7 -0
- package/build/stack/stack.cjs +6 -11
- package/build/stack/stack.cjs.map +2 -2
- package/build/tooltip/index.cjs +40 -0
- package/build/tooltip/index.cjs.map +7 -0
- package/build/tooltip/popup.cjs +100 -0
- package/build/tooltip/popup.cjs.map +7 -0
- package/build/tooltip/provider.cjs +35 -0
- package/build/tooltip/provider.cjs.map +7 -0
- package/build/tooltip/root.cjs +35 -0
- package/build/tooltip/root.cjs.map +7 -0
- package/build/tooltip/trigger.cjs +38 -0
- package/build/tooltip/trigger.cjs.map +7 -0
- package/build/tooltip/types.cjs +19 -0
- package/build/tooltip/types.cjs.map +7 -0
- package/build/utils/types.cjs.map +1 -1
- package/build/visually-hidden/visually-hidden.cjs +6 -19
- package/build/visually-hidden/visually-hidden.cjs.map +2 -2
- package/build-module/box/box.mjs +2 -2
- package/build-module/box/box.mjs.map +2 -2
- package/build-module/button/button.mjs +18 -303
- package/build-module/button/button.mjs.map +3 -3
- package/build-module/form/primitives/constants.mjs +10 -0
- package/build-module/form/primitives/constants.mjs.map +7 -0
- package/build-module/form/primitives/field/description.mjs +6 -33
- package/build-module/form/primitives/field/description.mjs.map +2 -2
- package/build-module/form/primitives/field/details.mjs +6 -33
- package/build-module/form/primitives/field/details.mjs.map +2 -2
- package/build-module/form/primitives/field/label.mjs +6 -33
- package/build-module/form/primitives/field/label.mjs.map +2 -2
- package/build-module/form/primitives/field/root.mjs +6 -17
- package/build-module/form/primitives/field/root.mjs.map +2 -2
- package/build-module/form/primitives/fieldset/description.mjs +6 -33
- package/build-module/form/primitives/fieldset/description.mjs.map +2 -2
- package/build-module/form/primitives/fieldset/details.mjs +6 -33
- package/build-module/form/primitives/fieldset/details.mjs.map +2 -2
- package/build-module/form/primitives/fieldset/legend.mjs +6 -33
- package/build-module/form/primitives/fieldset/legend.mjs.map +2 -2
- package/build-module/form/primitives/fieldset/root.mjs +6 -16
- package/build-module/form/primitives/fieldset/root.mjs.map +2 -2
- package/build-module/form/primitives/index.mjs +5 -1
- package/build-module/form/primitives/index.mjs.map +2 -2
- package/build-module/form/primitives/input/index.mjs +6 -0
- package/build-module/form/primitives/input/index.mjs.map +7 -0
- package/build-module/form/primitives/input/input.mjs +47 -0
- package/build-module/form/primitives/input/input.mjs.map +7 -0
- package/build-module/form/primitives/input/types.mjs +1 -0
- package/build-module/form/primitives/input/types.mjs.map +7 -0
- package/build-module/form/primitives/input-layout/input-layout.mjs +12 -111
- package/build-module/form/primitives/input-layout/input-layout.mjs.map +3 -3
- package/build-module/form/primitives/input-layout/slot.mjs +6 -94
- package/build-module/form/primitives/input-layout/slot.mjs.map +2 -2
- package/build-module/form/primitives/select/index.mjs +12 -0
- package/build-module/form/primitives/select/index.mjs.map +7 -0
- package/build-module/form/primitives/select/item.mjs +63 -0
- package/build-module/form/primitives/select/item.mjs.map +7 -0
- package/build-module/form/primitives/select/popup.mjs +76 -0
- package/build-module/form/primitives/select/popup.mjs.map +7 -0
- package/build-module/form/primitives/select/root.mjs +10 -0
- package/build-module/form/primitives/select/root.mjs.map +7 -0
- package/build-module/form/primitives/select/trigger.mjs +81 -0
- package/build-module/form/primitives/select/trigger.mjs.map +7 -0
- package/build-module/form/primitives/select/types.mjs +1 -0
- package/build-module/form/primitives/select/types.mjs.map +7 -0
- package/build-module/index.mjs +4 -0
- package/build-module/index.mjs.map +2 -2
- package/build-module/lock-unlock.mjs +11 -0
- package/build-module/lock-unlock.mjs.map +7 -0
- package/build-module/stack/stack.mjs +6 -11
- package/build-module/stack/stack.mjs.map +2 -2
- package/build-module/tooltip/index.mjs +12 -0
- package/build-module/tooltip/index.mjs.map +7 -0
- package/build-module/tooltip/popup.mjs +67 -0
- package/build-module/tooltip/popup.mjs.map +7 -0
- package/build-module/tooltip/provider.mjs +10 -0
- package/build-module/tooltip/provider.mjs.map +7 -0
- package/build-module/tooltip/root.mjs +10 -0
- package/build-module/tooltip/root.mjs.map +7 -0
- package/build-module/tooltip/trigger.mjs +13 -0
- package/build-module/tooltip/trigger.mjs.map +7 -0
- package/build-module/tooltip/types.mjs +1 -0
- package/build-module/tooltip/types.mjs.map +7 -0
- package/build-module/visually-hidden/visually-hidden.mjs +6 -19
- package/build-module/visually-hidden/visually-hidden.mjs.map +2 -2
- package/build-types/badge/stories/choosing-intent.story.d.ts +17 -0
- package/build-types/badge/stories/choosing-intent.story.d.ts.map +1 -0
- package/build-types/badge/stories/index.story.d.ts +1 -1
- package/build-types/badge/stories/index.story.d.ts.map +1 -1
- package/build-types/box/stories/index.story.d.ts +1 -1
- package/build-types/box/stories/index.story.d.ts.map +1 -1
- package/build-types/button/stories/index.story.d.ts +1 -1
- package/build-types/button/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/constants.d.ts +9 -0
- package/build-types/form/primitives/constants.d.ts.map +1 -0
- package/build-types/form/primitives/field/stories/index.story.d.ts +1 -1
- package/build-types/form/primitives/field/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/stories/index.story.d.ts +1 -1
- package/build-types/form/primitives/fieldset/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/index.d.ts +2 -0
- package/build-types/form/primitives/index.d.ts.map +1 -1
- package/build-types/form/primitives/input/index.d.ts +2 -0
- package/build-types/form/primitives/input/index.d.ts.map +1 -0
- package/build-types/form/primitives/input/input.d.ts +10 -0
- package/build-types/form/primitives/input/input.d.ts.map +1 -0
- package/build-types/form/primitives/input/stories/index.story.d.ts +13 -0
- package/build-types/form/primitives/input/stories/index.story.d.ts.map +1 -0
- package/build-types/form/primitives/input/test/index.test.d.ts +2 -0
- package/build-types/form/primitives/input/test/index.test.d.ts.map +1 -0
- package/build-types/form/primitives/input/types.d.ts +27 -0
- package/build-types/form/primitives/input/types.d.ts.map +1 -0
- package/build-types/form/primitives/input-layout/stories/index.story.d.ts +1 -1
- package/build-types/form/primitives/input-layout/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/select/index.d.ts +5 -0
- package/build-types/form/primitives/select/index.d.ts.map +1 -0
- package/build-types/form/primitives/select/item.d.ts +7 -0
- package/build-types/form/primitives/select/item.d.ts.map +1 -0
- package/build-types/form/primitives/select/popup.d.ts +2 -0
- package/build-types/form/primitives/select/popup.d.ts.map +1 -0
- package/build-types/form/primitives/select/root.d.ts +3 -0
- package/build-types/form/primitives/select/root.d.ts.map +1 -0
- package/build-types/form/primitives/select/stories/index.story.d.ts +50 -0
- package/build-types/form/primitives/select/stories/index.story.d.ts.map +1 -0
- package/build-types/form/primitives/select/test/index.test.d.ts +2 -0
- package/build-types/form/primitives/select/test/index.test.d.ts.map +1 -0
- package/build-types/form/primitives/select/trigger.d.ts +7 -0
- package/build-types/form/primitives/select/trigger.d.ts.map +1 -0
- package/build-types/form/primitives/select/types.d.ts +42 -0
- package/build-types/form/primitives/select/types.d.ts.map +1 -0
- package/build-types/icon/stories/index.story.d.ts +1 -1
- package/build-types/icon/stories/index.story.d.ts.map +1 -1
- package/build-types/index.d.ts +1 -0
- package/build-types/index.d.ts.map +1 -1
- package/build-types/lock-unlock.d.ts +2 -0
- package/build-types/lock-unlock.d.ts.map +1 -0
- package/build-types/stack/stories/index.story.d.ts +1 -1
- package/build-types/stack/stories/index.story.d.ts.map +1 -1
- package/build-types/tooltip/index.d.ts +6 -0
- package/build-types/tooltip/index.d.ts.map +1 -0
- package/build-types/tooltip/popup.d.ts +4 -0
- package/build-types/tooltip/popup.d.ts.map +1 -0
- package/build-types/tooltip/provider.d.ts +4 -0
- package/build-types/tooltip/provider.d.ts.map +1 -0
- package/build-types/tooltip/root.d.ts +4 -0
- package/build-types/tooltip/root.d.ts.map +1 -0
- package/build-types/tooltip/stories/index.story.d.ts +23 -0
- package/build-types/tooltip/stories/index.story.d.ts.map +1 -0
- package/build-types/tooltip/test/index.test.d.ts +2 -0
- package/build-types/tooltip/test/index.test.d.ts.map +1 -0
- package/build-types/tooltip/trigger.d.ts +4 -0
- package/build-types/tooltip/trigger.d.ts.map +1 -0
- package/build-types/tooltip/types.d.ts +18 -0
- package/build-types/tooltip/types.d.ts.map +1 -0
- package/build-types/utils/types.d.ts +0 -3
- package/build-types/utils/types.d.ts.map +1 -1
- package/build-types/visually-hidden/stories/index.story.d.ts +1 -1
- package/build-types/visually-hidden/stories/index.story.d.ts.map +1 -1
- package/package.json +12 -10
- package/src/badge/stories/choosing-intent.mdx +29 -32
- package/src/badge/stories/choosing-intent.story.tsx +129 -0
- package/src/badge/stories/index.story.tsx +1 -1
- package/src/box/box.tsx +2 -2
- package/src/box/stories/index.story.tsx +1 -1
- package/src/box/test/box.test.tsx +0 -11
- package/src/button/stories/index.story.tsx +1 -6
- package/src/button/style.module.css +2 -2
- package/src/button/test/button.test.tsx +1 -16
- package/src/form/primitives/constants.ts +10 -0
- package/src/form/primitives/field/stories/index.story.tsx +1 -1
- package/src/form/primitives/fieldset/stories/index.story.tsx +1 -1
- package/src/form/primitives/index.ts +2 -0
- package/src/form/primitives/input/index.ts +1 -0
- package/src/form/primitives/input/input.tsx +28 -0
- package/src/form/primitives/input/stories/index.story.tsx +40 -0
- package/src/form/primitives/input/style.module.css +34 -0
- package/src/form/primitives/input/test/index.test.tsx +13 -0
- package/src/form/primitives/input/types.ts +31 -0
- package/src/form/primitives/input-layout/stories/index.story.tsx +1 -1
- package/src/form/primitives/input-layout/style.module.css +5 -4
- package/src/form/primitives/select/index.ts +4 -0
- package/src/form/primitives/select/item.tsx +39 -0
- package/src/form/primitives/select/popup.tsx +55 -0
- package/src/form/primitives/select/root.tsx +6 -0
- package/src/form/primitives/select/stories/index.story.tsx +276 -0
- package/src/form/primitives/select/style.module.css +7 -0
- package/src/form/primitives/select/test/index.test.tsx +35 -0
- package/src/form/primitives/select/trigger.tsx +58 -0
- package/src/form/primitives/select/types.ts +52 -0
- package/src/icon/stories/index.story.tsx +1 -1
- package/src/index.ts +1 -0
- package/src/lock-unlock.ts +7 -0
- package/src/stack/stories/index.story.tsx +1 -1
- package/src/stories/introduction.mdx +1 -1
- package/src/tooltip/index.ts +6 -0
- package/src/tooltip/popup.tsx +64 -0
- package/src/tooltip/provider.tsx +8 -0
- package/src/tooltip/root.tsx +8 -0
- package/src/tooltip/stories/index.story.tsx +97 -0
- package/src/tooltip/style.module.css +20 -0
- package/src/tooltip/test/index.test.tsx +87 -0
- package/src/tooltip/trigger.tsx +15 -0
- package/src/tooltip/types.ts +26 -0
- package/src/utils/css/dropdown-motion.module.css +47 -0
- package/src/utils/css/focus.module.css +1 -1
- package/src/utils/css/item-popup.module.css +127 -0
- package/src/utils/css/select-trigger.module.css +58 -0
- package/src/utils/types.ts +0 -3
- package/src/visually-hidden/stories/index.story.tsx +1 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import '@wordpress/theme/design-tokens.css';
|
|
3
|
+
import { Select } from '../../../..';
|
|
4
|
+
|
|
5
|
+
const meta: Meta< typeof Select.Root > = {
|
|
6
|
+
title: 'Design System/Components/Form/Primitives/Select',
|
|
7
|
+
component: Select.Root,
|
|
8
|
+
subcomponents: {
|
|
9
|
+
Trigger: Select.Trigger,
|
|
10
|
+
Popup: Select.Popup,
|
|
11
|
+
Item: Select.Item,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export default meta;
|
|
15
|
+
|
|
16
|
+
type Story = StoryObj< typeof Select.Root >;
|
|
17
|
+
|
|
18
|
+
export const Default: Story = {
|
|
19
|
+
args: {
|
|
20
|
+
children: (
|
|
21
|
+
<>
|
|
22
|
+
<Select.Trigger />
|
|
23
|
+
<Select.Popup>
|
|
24
|
+
{ Array.from( { length: 6 }, ( _, index ) => (
|
|
25
|
+
<Select.Item
|
|
26
|
+
key={ index }
|
|
27
|
+
value={ `Item ${ index + 1 }` }
|
|
28
|
+
/>
|
|
29
|
+
) ) }
|
|
30
|
+
</Select.Popup>
|
|
31
|
+
</>
|
|
32
|
+
),
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const Compact: Story = {
|
|
37
|
+
args: {
|
|
38
|
+
children: (
|
|
39
|
+
<>
|
|
40
|
+
<Select.Trigger size="compact" />
|
|
41
|
+
<Select.Popup>
|
|
42
|
+
{ Array.from( { length: 6 }, ( _, index ) => (
|
|
43
|
+
<Select.Item
|
|
44
|
+
key={ index }
|
|
45
|
+
value={ `Item ${ index + 1 }` }
|
|
46
|
+
size="compact"
|
|
47
|
+
/>
|
|
48
|
+
) ) }
|
|
49
|
+
</Select.Popup>
|
|
50
|
+
</>
|
|
51
|
+
),
|
|
52
|
+
defaultValue: 'Item 1',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The `minimal` variant must be used judiciously, because in many
|
|
58
|
+
* contexts it can be unclear to users that it is a select trigger.
|
|
59
|
+
*
|
|
60
|
+
* Combined with the `small` size, `minimal` can be used to create a
|
|
61
|
+
* very low-profile `Select`, intended for rare use cases like
|
|
62
|
+
* a pagination control.
|
|
63
|
+
*/
|
|
64
|
+
export const Minimal: Story = {
|
|
65
|
+
args: {
|
|
66
|
+
children: (
|
|
67
|
+
<>
|
|
68
|
+
<Select.Trigger size="small" variant="minimal" />
|
|
69
|
+
<Select.Popup>
|
|
70
|
+
{ Array.from( { length: 6 }, ( _, index ) => (
|
|
71
|
+
<Select.Item
|
|
72
|
+
key={ index }
|
|
73
|
+
value={ `${ index + 1 }` }
|
|
74
|
+
size="small"
|
|
75
|
+
/>
|
|
76
|
+
) ) }
|
|
77
|
+
</Select.Popup>
|
|
78
|
+
</>
|
|
79
|
+
),
|
|
80
|
+
defaultValue: '1',
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const withEmptyOptionItems = [
|
|
85
|
+
{
|
|
86
|
+
value: '',
|
|
87
|
+
label: 'Select',
|
|
88
|
+
disabled: true,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
value: 'Item 2',
|
|
92
|
+
label: 'Item 2',
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* By passing an `items` array to `Select.Root`, the `Select.Trigger` will be able to
|
|
98
|
+
* render a `label` string for each item rather than the raw `value` string. In this
|
|
99
|
+
* case, the option with an empty string value has a `"Select"` label string.
|
|
100
|
+
*
|
|
101
|
+
* This may be easier than writing a custom render function for the `Select.Trigger`.
|
|
102
|
+
*/
|
|
103
|
+
export const WithEmptyValueOption: Story = {
|
|
104
|
+
args: {
|
|
105
|
+
items: withEmptyOptionItems,
|
|
106
|
+
children: (
|
|
107
|
+
<>
|
|
108
|
+
<Select.Trigger />
|
|
109
|
+
<Select.Popup>
|
|
110
|
+
{ withEmptyOptionItems.map( ( item ) => (
|
|
111
|
+
<Select.Item
|
|
112
|
+
key={ item.value }
|
|
113
|
+
value={ item.value }
|
|
114
|
+
label={ item.label }
|
|
115
|
+
disabled={ item.disabled }
|
|
116
|
+
>
|
|
117
|
+
{ item.label }
|
|
118
|
+
</Select.Item>
|
|
119
|
+
) ) }
|
|
120
|
+
</Select.Popup>
|
|
121
|
+
</>
|
|
122
|
+
),
|
|
123
|
+
defaultValue: '',
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* When accessibly labeling a `Select`, note that the label must be associated with the `Select.Trigger`,
|
|
129
|
+
* not the `Select.Root`.
|
|
130
|
+
*
|
|
131
|
+
* Whether labeling with `aria-label`, `htmlFor`, or `aria-labelledby`, the association must be made to the `Select.Trigger`.
|
|
132
|
+
*/
|
|
133
|
+
export const Labeling: Story = {
|
|
134
|
+
args: {
|
|
135
|
+
children: (
|
|
136
|
+
<>
|
|
137
|
+
<Select.Trigger aria-label="User role" />
|
|
138
|
+
<Select.Popup>
|
|
139
|
+
<Select.Item value="Administrator" />
|
|
140
|
+
<Select.Item value="Editor" />
|
|
141
|
+
</Select.Popup>
|
|
142
|
+
</>
|
|
143
|
+
),
|
|
144
|
+
defaultValue: 'Administrator',
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const longItemValue =
|
|
149
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.';
|
|
150
|
+
|
|
151
|
+
export const WithOverflow: Story = {
|
|
152
|
+
args: {
|
|
153
|
+
children: (
|
|
154
|
+
<>
|
|
155
|
+
<Select.Trigger />
|
|
156
|
+
<Select.Popup>
|
|
157
|
+
<Select.Item value={ longItemValue } />
|
|
158
|
+
<Select.Item value="Item 2" />
|
|
159
|
+
</Select.Popup>
|
|
160
|
+
</>
|
|
161
|
+
),
|
|
162
|
+
defaultValue: longItemValue,
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const Disabled: Story = {
|
|
167
|
+
args: {
|
|
168
|
+
children: (
|
|
169
|
+
<>
|
|
170
|
+
<Select.Trigger />
|
|
171
|
+
<Select.Popup>
|
|
172
|
+
<Select.Item value="Item 1" />
|
|
173
|
+
<Select.Item value="Item 2" />
|
|
174
|
+
</Select.Popup>
|
|
175
|
+
</>
|
|
176
|
+
),
|
|
177
|
+
defaultValue: 'Item 1',
|
|
178
|
+
disabled: true,
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export const WithDisabledItem: Story = {
|
|
183
|
+
args: {
|
|
184
|
+
children: (
|
|
185
|
+
<>
|
|
186
|
+
<Select.Trigger />
|
|
187
|
+
<Select.Popup>
|
|
188
|
+
<Select.Item value="Item 1" />
|
|
189
|
+
<Select.Item value="Item 2" disabled />
|
|
190
|
+
</Select.Popup>
|
|
191
|
+
</>
|
|
192
|
+
),
|
|
193
|
+
defaultValue: 'Item 1',
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const customOptions = [
|
|
198
|
+
{
|
|
199
|
+
value: 'User 1',
|
|
200
|
+
label: 'User 1 (Admin)',
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
value: 'User 2',
|
|
204
|
+
label: 'User 2 (Editor)',
|
|
205
|
+
},
|
|
206
|
+
];
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* For custom needs, a `Select.Trigger` can take a custom render function as its children,
|
|
210
|
+
* while `Select.Item` can take arbitrary content as children.
|
|
211
|
+
*/
|
|
212
|
+
export const WithCustomTriggerAndItem: Story = {
|
|
213
|
+
args: {
|
|
214
|
+
children: (
|
|
215
|
+
<>
|
|
216
|
+
<Select.Trigger>
|
|
217
|
+
{ ( value ) => (
|
|
218
|
+
<span
|
|
219
|
+
style={ {
|
|
220
|
+
display: 'flex',
|
|
221
|
+
alignItems: 'center',
|
|
222
|
+
gap: 8,
|
|
223
|
+
} }
|
|
224
|
+
>
|
|
225
|
+
<img
|
|
226
|
+
src={ `https://gravatar.com/avatar/?d=initials&name=${ value }` }
|
|
227
|
+
alt=""
|
|
228
|
+
width="20"
|
|
229
|
+
style={ {
|
|
230
|
+
borderRadius: '50%',
|
|
231
|
+
} }
|
|
232
|
+
/>
|
|
233
|
+
{ value }
|
|
234
|
+
</span>
|
|
235
|
+
) }
|
|
236
|
+
</Select.Trigger>
|
|
237
|
+
<Select.Popup>
|
|
238
|
+
{ customOptions.map( ( item ) => (
|
|
239
|
+
<Select.Item
|
|
240
|
+
key={ item.value }
|
|
241
|
+
value={ item.value }
|
|
242
|
+
label={ item.label }
|
|
243
|
+
>
|
|
244
|
+
{ item.label }
|
|
245
|
+
</Select.Item>
|
|
246
|
+
) ) }
|
|
247
|
+
</Select.Popup>
|
|
248
|
+
</>
|
|
249
|
+
),
|
|
250
|
+
defaultValue: 'User 1',
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Popovers in Gutenberg are managed with explicit z-index values, which can create
|
|
256
|
+
* situations where a popover renders below another popover, when you want it to be rendered above.
|
|
257
|
+
*
|
|
258
|
+
* The `--wp-ui-select-z-index` CSS variable, available on the `Select.Popup` component,
|
|
259
|
+
* is an escape hatch that can be used to override the z-index of a given `Select` popover
|
|
260
|
+
* on a case-by-case basis.
|
|
261
|
+
*/
|
|
262
|
+
export const WithCustomZIndex: Story = {
|
|
263
|
+
name: 'With Custom z-index',
|
|
264
|
+
args: {
|
|
265
|
+
children: (
|
|
266
|
+
<>
|
|
267
|
+
<Select.Trigger />
|
|
268
|
+
<Select.Popup style={ { '--wp-ui-select-z-index': '1000001' } }>
|
|
269
|
+
<Select.Item value="Item 1" />
|
|
270
|
+
<Select.Item value="Item 2" />
|
|
271
|
+
</Select.Popup>
|
|
272
|
+
</>
|
|
273
|
+
),
|
|
274
|
+
defaultValue: 'Item 1',
|
|
275
|
+
},
|
|
276
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { render } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { createRef } from '@wordpress/element';
|
|
4
|
+
import * as Select from '../index';
|
|
5
|
+
|
|
6
|
+
jest.setTimeout( 10000 );
|
|
7
|
+
|
|
8
|
+
describe( 'Select', () => {
|
|
9
|
+
it( 'forwards ref', async () => {
|
|
10
|
+
const user = userEvent.setup();
|
|
11
|
+
const triggerRef = createRef< HTMLButtonElement >();
|
|
12
|
+
const popupRef = createRef< HTMLDivElement >();
|
|
13
|
+
const itemRef = createRef< HTMLDivElement >();
|
|
14
|
+
|
|
15
|
+
render(
|
|
16
|
+
<Select.Root>
|
|
17
|
+
<Select.Trigger ref={ triggerRef } />
|
|
18
|
+
<Select.Popup ref={ popupRef }>
|
|
19
|
+
<Select.Item ref={ itemRef } value="Item 1" />
|
|
20
|
+
<Select.Item value="Item 2" />
|
|
21
|
+
</Select.Popup>
|
|
22
|
+
</Select.Root>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
// Test trigger ref before interaction
|
|
26
|
+
expect( triggerRef.current ).toBeInstanceOf( HTMLButtonElement );
|
|
27
|
+
|
|
28
|
+
// Click on the trigger to open the select dropdown
|
|
29
|
+
await user.click( triggerRef.current! );
|
|
30
|
+
|
|
31
|
+
// Now test that the popup and item refs are also available
|
|
32
|
+
expect( popupRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
33
|
+
expect( itemRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
34
|
+
} );
|
|
35
|
+
} );
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Select as _Select } from '@base-ui/react/select';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { forwardRef } from '@wordpress/element';
|
|
4
|
+
import { chevronDown } from '@wordpress/icons';
|
|
5
|
+
import focusStyles from '../../../utils/css/focus.module.css';
|
|
6
|
+
import selectTriggerStyles from '../../../utils/css/select-trigger.module.css';
|
|
7
|
+
import { InputLayout } from '../input-layout';
|
|
8
|
+
import { Icon } from '../../../icon';
|
|
9
|
+
import type { SelectTriggerProps } from './types';
|
|
10
|
+
|
|
11
|
+
export const Trigger = forwardRef< HTMLButtonElement, SelectTriggerProps >(
|
|
12
|
+
function Trigger(
|
|
13
|
+
{ className, size, variant, children, ...restProps },
|
|
14
|
+
ref
|
|
15
|
+
) {
|
|
16
|
+
return (
|
|
17
|
+
<InputLayout
|
|
18
|
+
className={ clsx(
|
|
19
|
+
focusStyles[ 'outset-ring--focus-within-except-active' ],
|
|
20
|
+
selectTriggerStyles[ 'trigger-wrapper' ],
|
|
21
|
+
variant === 'minimal' &&
|
|
22
|
+
selectTriggerStyles[ 'is-minimal' ],
|
|
23
|
+
className
|
|
24
|
+
) }
|
|
25
|
+
size={ size }
|
|
26
|
+
isBorderless={ variant === 'minimal' }
|
|
27
|
+
>
|
|
28
|
+
<_Select.Trigger
|
|
29
|
+
{ ...restProps }
|
|
30
|
+
className={ clsx(
|
|
31
|
+
selectTriggerStyles.trigger,
|
|
32
|
+
variant === 'minimal' &&
|
|
33
|
+
selectTriggerStyles[ 'is-minimal' ]
|
|
34
|
+
) }
|
|
35
|
+
data-can-disable-input-layout
|
|
36
|
+
ref={ ref }
|
|
37
|
+
>
|
|
38
|
+
<_Select.Value
|
|
39
|
+
className={ ( state ) =>
|
|
40
|
+
clsx(
|
|
41
|
+
selectTriggerStyles[ 'trigger-value' ],
|
|
42
|
+
state.value === '' &&
|
|
43
|
+
selectTriggerStyles[ 'is-placeholder' ]
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
>
|
|
47
|
+
{ children }
|
|
48
|
+
</_Select.Value>
|
|
49
|
+
<Icon
|
|
50
|
+
className={ selectTriggerStyles[ 'trigger-caret' ] }
|
|
51
|
+
icon={ chevronDown }
|
|
52
|
+
size={ 18 }
|
|
53
|
+
/>
|
|
54
|
+
</_Select.Trigger>
|
|
55
|
+
</InputLayout>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Select as _Select } from '@base-ui/react/select';
|
|
2
|
+
import type { InputLayoutProps } from '../input-layout/types';
|
|
3
|
+
|
|
4
|
+
// The second type parameter is the `multiple` flag (currently disabled).
|
|
5
|
+
export type SelectRootProps = Omit<
|
|
6
|
+
_Select.Root.Props< string, false >,
|
|
7
|
+
'multiple'
|
|
8
|
+
>;
|
|
9
|
+
|
|
10
|
+
export type SelectTriggerProps = Omit< _Select.Trigger.Props, 'children' > & {
|
|
11
|
+
/**
|
|
12
|
+
* The size of the trigger.
|
|
13
|
+
*
|
|
14
|
+
* @default 'default'
|
|
15
|
+
*/
|
|
16
|
+
size?: InputLayoutProps[ 'size' ];
|
|
17
|
+
/**
|
|
18
|
+
* The style variant of the trigger.
|
|
19
|
+
*
|
|
20
|
+
* @default 'default'
|
|
21
|
+
*/
|
|
22
|
+
variant?: 'default' | 'minimal';
|
|
23
|
+
/**
|
|
24
|
+
* A function that gets called with the current value as an argument.
|
|
25
|
+
* Use this to customize the trigger content.
|
|
26
|
+
*/
|
|
27
|
+
children?: _Select.Value.Props[ 'children' ];
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type SelectPopupProps = _Select.Popup.Props;
|
|
31
|
+
|
|
32
|
+
export type SelectItemProps = Omit<
|
|
33
|
+
_Select.Item.Props,
|
|
34
|
+
'children' | 'value'
|
|
35
|
+
> & {
|
|
36
|
+
/**
|
|
37
|
+
* A unique value that identifies this select item.
|
|
38
|
+
*/
|
|
39
|
+
value?: string;
|
|
40
|
+
/**
|
|
41
|
+
* The size of the item.
|
|
42
|
+
*
|
|
43
|
+
* @default 'default'
|
|
44
|
+
*/
|
|
45
|
+
size?: InputLayoutProps[ 'size' ];
|
|
46
|
+
/**
|
|
47
|
+
* The content of the item.
|
|
48
|
+
*
|
|
49
|
+
* @default `value`
|
|
50
|
+
*/
|
|
51
|
+
children?: _Select.Item.Props[ 'children' ];
|
|
52
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis';
|
|
2
|
+
|
|
3
|
+
export const { lock, unlock } =
|
|
4
|
+
__dangerousOptInToUnstableAPIsOnlyForCoreModules(
|
|
5
|
+
'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',
|
|
6
|
+
'@wordpress/ui'
|
|
7
|
+
);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import { Tooltip } from '@base-ui/react/tooltip';
|
|
3
|
+
import { forwardRef } from '@wordpress/element';
|
|
4
|
+
import {
|
|
5
|
+
type ThemeProvider as ThemeProviderType,
|
|
6
|
+
privateApis as themePrivateApis,
|
|
7
|
+
} from '@wordpress/theme';
|
|
8
|
+
import type { PopupProps } from './types';
|
|
9
|
+
import { unlock } from '../lock-unlock';
|
|
10
|
+
import resetStyles from '../utils/css/resets.module.css';
|
|
11
|
+
import styles from './style.module.css';
|
|
12
|
+
|
|
13
|
+
const ThemeProvider: typeof ThemeProviderType =
|
|
14
|
+
unlock( themePrivateApis ).ThemeProvider;
|
|
15
|
+
|
|
16
|
+
const Popup = forwardRef< HTMLDivElement, PopupProps >( function TooltipPopup(
|
|
17
|
+
{
|
|
18
|
+
align = 'center',
|
|
19
|
+
side = 'bottom',
|
|
20
|
+
sideOffset = 4,
|
|
21
|
+
children,
|
|
22
|
+
className,
|
|
23
|
+
style,
|
|
24
|
+
...props
|
|
25
|
+
},
|
|
26
|
+
ref
|
|
27
|
+
) {
|
|
28
|
+
return (
|
|
29
|
+
<Tooltip.Portal>
|
|
30
|
+
<Tooltip.Positioner
|
|
31
|
+
align={ align }
|
|
32
|
+
side={ side }
|
|
33
|
+
sideOffset={ sideOffset }
|
|
34
|
+
style={ style }
|
|
35
|
+
className={ clsx(
|
|
36
|
+
resetStyles[ 'box-sizing' ],
|
|
37
|
+
className,
|
|
38
|
+
styles.positioner
|
|
39
|
+
) }
|
|
40
|
+
>
|
|
41
|
+
{ /* This should ideally use whatever dark color makes sense,
|
|
42
|
+
and not be hardcoded to #1e1e1e. The solutions would be to:
|
|
43
|
+
- review the design of the tooltip, in case we want to stop
|
|
44
|
+
hardcoding it to a dark background
|
|
45
|
+
- create new semantic tokens as needed (aliasing either the "inverted
|
|
46
|
+
bg" or "perma-dark bg" private tokens) and have Tooltip.Popup use
|
|
47
|
+
them;
|
|
48
|
+
- remove the hardcoded `bg` setting from the `ThemeProvider` below
|
|
49
|
+
*/ }
|
|
50
|
+
<ThemeProvider color={ { bg: '#1e1e1e' } }>
|
|
51
|
+
<Tooltip.Popup
|
|
52
|
+
ref={ ref }
|
|
53
|
+
className={ styles.popup }
|
|
54
|
+
{ ...props }
|
|
55
|
+
>
|
|
56
|
+
{ children }
|
|
57
|
+
</Tooltip.Popup>
|
|
58
|
+
</ThemeProvider>
|
|
59
|
+
</Tooltip.Positioner>
|
|
60
|
+
</Tooltip.Portal>
|
|
61
|
+
);
|
|
62
|
+
} );
|
|
63
|
+
|
|
64
|
+
export { Popup };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Tooltip } from '../..';
|
|
3
|
+
|
|
4
|
+
const meta: Meta< typeof Tooltip.Root > = {
|
|
5
|
+
title: 'Design System/Components/Tooltip',
|
|
6
|
+
component: Tooltip.Root,
|
|
7
|
+
subcomponents: {
|
|
8
|
+
Provider: Tooltip.Provider,
|
|
9
|
+
Trigger: Tooltip.Trigger,
|
|
10
|
+
Popup: Tooltip.Popup,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
export const Default: StoryObj< typeof Tooltip.Root > = {
|
|
16
|
+
args: {
|
|
17
|
+
children: (
|
|
18
|
+
<>
|
|
19
|
+
<Tooltip.Trigger>Hover me</Tooltip.Trigger>
|
|
20
|
+
<Tooltip.Popup>Tooltip text</Tooltip.Popup>
|
|
21
|
+
</>
|
|
22
|
+
),
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The `disabled` prop prevents the tooltip from showing, and can be used to
|
|
28
|
+
* show the tooltip conditionally without rendering the underlying react
|
|
29
|
+
* component conditionally (which could cause reconciliation issues).
|
|
30
|
+
*/
|
|
31
|
+
export const Disabled: StoryObj< typeof Tooltip.Root > = {
|
|
32
|
+
...Default,
|
|
33
|
+
args: {
|
|
34
|
+
...Default.args,
|
|
35
|
+
disabled: true,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Use the `side` prop to control where the tooltip appears relative to the
|
|
41
|
+
* trigger element.
|
|
42
|
+
*/
|
|
43
|
+
export const Positioning: StoryObj< typeof Tooltip.Root > = {
|
|
44
|
+
render: () => (
|
|
45
|
+
<div
|
|
46
|
+
style={ {
|
|
47
|
+
display: 'flex',
|
|
48
|
+
gap: '2rem',
|
|
49
|
+
padding: '4rem',
|
|
50
|
+
justifyContent: 'center',
|
|
51
|
+
} }
|
|
52
|
+
>
|
|
53
|
+
<Tooltip.Root>
|
|
54
|
+
<Tooltip.Trigger>Top</Tooltip.Trigger>
|
|
55
|
+
<Tooltip.Popup side="top">Tooltip on top</Tooltip.Popup>
|
|
56
|
+
</Tooltip.Root>
|
|
57
|
+
|
|
58
|
+
<Tooltip.Root>
|
|
59
|
+
<Tooltip.Trigger>Right</Tooltip.Trigger>
|
|
60
|
+
<Tooltip.Popup side="right">Tooltip on right</Tooltip.Popup>
|
|
61
|
+
</Tooltip.Root>
|
|
62
|
+
|
|
63
|
+
<Tooltip.Root>
|
|
64
|
+
<Tooltip.Trigger>Bottom</Tooltip.Trigger>
|
|
65
|
+
<Tooltip.Popup side="bottom">Tooltip on bottom</Tooltip.Popup>
|
|
66
|
+
</Tooltip.Root>
|
|
67
|
+
|
|
68
|
+
<Tooltip.Root>
|
|
69
|
+
<Tooltip.Trigger>Left</Tooltip.Trigger>
|
|
70
|
+
<Tooltip.Popup side="left">Tooltip on left</Tooltip.Popup>
|
|
71
|
+
</Tooltip.Root>
|
|
72
|
+
</div>
|
|
73
|
+
),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Use `Tooltip.Provider` to control the delay before tooltips appear.
|
|
78
|
+
* This is useful when you have multiple tooltips and want them to share
|
|
79
|
+
* the same delay configuration.
|
|
80
|
+
*/
|
|
81
|
+
export const WithProvider: StoryObj< typeof Tooltip.Root > = {
|
|
82
|
+
render: () => (
|
|
83
|
+
<Tooltip.Provider delay={ 0 }>
|
|
84
|
+
<div style={ { display: 'flex', gap: '1rem' } }>
|
|
85
|
+
<Tooltip.Root>
|
|
86
|
+
<Tooltip.Trigger>First</Tooltip.Trigger>
|
|
87
|
+
<Tooltip.Popup>First tooltip</Tooltip.Popup>
|
|
88
|
+
</Tooltip.Root>
|
|
89
|
+
|
|
90
|
+
<Tooltip.Root>
|
|
91
|
+
<Tooltip.Trigger>Second</Tooltip.Trigger>
|
|
92
|
+
<Tooltip.Popup>Second tooltip</Tooltip.Popup>
|
|
93
|
+
</Tooltip.Root>
|
|
94
|
+
</div>
|
|
95
|
+
</Tooltip.Provider>
|
|
96
|
+
),
|
|
97
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@layer wp-ui-utilities, wp-ui-components, wp-ui-compositions, wp-ui-overrides;
|
|
2
|
+
|
|
3
|
+
@layer wp-ui-components {
|
|
4
|
+
.positioner {
|
|
5
|
+
z-index: var(--wp-ui-tooltip-z-index, initial);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.popup {
|
|
9
|
+
background-color: var(--wpds-color-bg-surface-neutral-strong);
|
|
10
|
+
padding:
|
|
11
|
+
var(--wpds-dimension-padding-surface-2xs)
|
|
12
|
+
var(--wpds-dimension-padding-surface-xs);
|
|
13
|
+
border-radius: var(--wpds-border-radius-sm);
|
|
14
|
+
font-family: var(--wpds-font-family-body);
|
|
15
|
+
font-size: var(--wpds-font-size-sm);
|
|
16
|
+
line-height: 1.4; /* TODO: use DS token for line height */
|
|
17
|
+
color: var(--wpds-color-fg-content-neutral);
|
|
18
|
+
box-shadow: var(--wpds-elevation-small);
|
|
19
|
+
}
|
|
20
|
+
}
|