@jobber/components 8.26.3 → 8.27.1
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/Select.d.ts +1 -0
- package/Select.js +17 -0
- package/dist/BottomSheet-cjs.js +8 -7
- package/dist/BottomSheet-es.js +9 -8
- package/dist/ComboboxChipRemove-cjs.js +2 -1
- package/dist/ComboboxChipRemove-es.js +4 -3
- package/dist/DrawerDescription-cjs.js +4 -97
- package/dist/DrawerDescription-es.js +6 -98
- package/dist/FieldDescription-cjs.js +880 -0
- package/dist/FieldDescription-es.js +856 -0
- package/dist/InputNumberExperimental-cjs.js +5 -875
- package/dist/InputNumberExperimental-es.js +2 -854
- package/dist/MenuSubmenuTrigger-es.js +4 -4
- package/dist/Modal/index.cjs +12 -2
- package/dist/Modal/index.mjs +13 -3
- package/dist/NumberFieldInput-cjs.js +2 -2
- package/dist/NumberFieldInput-es.js +1 -1
- package/dist/ScrollAreaViewport-cjs.js +2122 -12
- package/dist/ScrollAreaViewport-es.js +2118 -13
- package/dist/Select/Select.d.ts +31 -0
- package/dist/Select/Select.types.d.ts +145 -0
- package/dist/Select/SelectBottomSheet.d.ts +4 -0
- package/dist/Select/SelectDropdown.d.ts +4 -0
- package/dist/Select/index.cjs +41 -0
- package/dist/Select/index.d.ts +2 -0
- package/dist/Select/index.mjs +35 -0
- package/dist/Select-cjs.js +231 -0
- package/dist/Select-es.js +229 -0
- package/dist/SelectPrimitive-cjs.js +20 -3
- package/dist/SelectPrimitive-es.js +20 -3
- package/dist/dialogReturnFocus-cjs.js +8 -5
- package/dist/dialogReturnFocus-es.js +9 -6
- package/dist/docs/Dialog/Dialog.md +74 -21
- package/dist/docs/Select/Select.md +428 -0
- package/dist/docs/SelectPrimitive/SelectPrimitive.md +14 -1
- package/dist/docs/index.md +1 -0
- package/dist/floating-ui.react-dom-es.js +1 -1
- package/dist/floating-ui.react-es.js +1 -1
- package/dist/floating-ui.utils.dom-es.js +1 -1
- package/dist/index.cjs +9 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +8 -0
- package/dist/primitives/ComboboxPrimitive/index.cjs +1 -0
- package/dist/primitives/ComboboxPrimitive/index.mjs +1 -0
- package/dist/primitives/HelperText/HelperText.d.ts +2 -1
- package/dist/primitives/InputNumberExperimental/index.cjs +3 -1
- package/dist/primitives/InputNumberExperimental/index.mjs +3 -1
- package/dist/primitives/SelectPrimitive/SelectPrimitive.d.ts +11 -0
- package/dist/primitives/SelectPrimitive/index.d.ts +1 -1
- package/dist/primitives/SelectPrimitive/types.d.ts +15 -0
- package/dist/primitives/index.cjs +2 -0
- package/dist/primitives/index.mjs +2 -0
- package/dist/stringifyLocale-cjs.js +13 -0
- package/dist/stringifyLocale-es.js +11 -0
- package/dist/styles.css +300 -10
- package/dist/unstyledPrimitives/index.cjs +219 -2230
- package/dist/unstyledPrimitives/index.mjs +225 -2236
- package/dist/useButton-es.js +2 -2
- package/dist/useCompositeListItem-es.js +1 -1
- package/dist/useLabel-cjs.js +0 -11
- package/dist/useLabel-es.js +2 -12
- package/dist/useScrollLock-es.js +3 -3
- package/dist/utils/meta/meta.json +5 -0
- package/package.json +7 -2
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
# Select
|
|
2
|
+
|
|
3
|
+
Select presents a defined list of options to choose from. It is a prop-driven,
|
|
4
|
+
labelled dropdown wrapped in a field structure that handles the label,
|
|
5
|
+
description, and error messaging for you.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import React, { useState } from "react";
|
|
9
|
+
import { Select } from "@jobber/components/Select";
|
|
10
|
+
|
|
11
|
+
export function SelectBasicExample() {
|
|
12
|
+
const [value, setValue] = useState<string | undefined>("active");
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Select label="Status" value={value} onValueChange={setValue}>
|
|
16
|
+
<Select.Item value="active">Active</Select.Item>
|
|
17
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
18
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
19
|
+
</Select>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Design & usage guidelines
|
|
25
|
+
|
|
26
|
+
Use Select when a user needs to pick a single value from a known, reasonably
|
|
27
|
+
short list of options. Each option is declared with `Select.Item`, where the
|
|
28
|
+
`value` is submitted and the children are shown as the label.
|
|
29
|
+
|
|
30
|
+
Select is controlled: pass the current `value` and an `onValueChange` handler to
|
|
31
|
+
keep your state in sync.
|
|
32
|
+
|
|
33
|
+
## Empty state
|
|
34
|
+
|
|
35
|
+
The `label` doubles as the placeholder: while no value is selected it sits
|
|
36
|
+
centered inside the field, then rises to a floating mini-label once the user
|
|
37
|
+
picks an option. There is no separate `placeholder` prop — the label fills that
|
|
38
|
+
role.
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import React, { useState } from "react";
|
|
42
|
+
import { Select } from "@jobber/components/Select";
|
|
43
|
+
|
|
44
|
+
export function SelectEmptyExample() {
|
|
45
|
+
const [value, setValue] = useState<string | undefined>();
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Select label="Status" value={value} onValueChange={setValue}>
|
|
49
|
+
<Select.Item value="active">Active</Select.Item>
|
|
50
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
51
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
52
|
+
</Select>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Description
|
|
58
|
+
|
|
59
|
+
Use `description` to add supporting help text beneath the field.
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import React, { useState } from "react";
|
|
63
|
+
import { Select } from "@jobber/components/Select";
|
|
64
|
+
|
|
65
|
+
export function SelectDescriptionExample() {
|
|
66
|
+
const [value, setValue] = useState<string | undefined>();
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<Select
|
|
70
|
+
label="Status"
|
|
71
|
+
description="This controls who can see the record."
|
|
72
|
+
value={value}
|
|
73
|
+
onValueChange={setValue}
|
|
74
|
+
>
|
|
75
|
+
<Select.Item value="active">Active</Select.Item>
|
|
76
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
77
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
78
|
+
</Select>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## States
|
|
84
|
+
|
|
85
|
+
### Error
|
|
86
|
+
|
|
87
|
+
Pass an `error` message to mark the field invalid and show the message beneath
|
|
88
|
+
the field. The error replaces the description while it is present. Use `invalid`
|
|
89
|
+
instead to apply the invalid styling without a message — for example when a form
|
|
90
|
+
library such as React Hook Form renders the error text itself.
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import React, { useState } from "react";
|
|
94
|
+
import { Select } from "@jobber/components/Select";
|
|
95
|
+
|
|
96
|
+
export function SelectErrorExample() {
|
|
97
|
+
const [value, setValue] = useState<string | undefined>();
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<Select
|
|
101
|
+
label="Status"
|
|
102
|
+
description="This controls who can see the record."
|
|
103
|
+
error="Please choose a status."
|
|
104
|
+
value={value}
|
|
105
|
+
onValueChange={setValue}
|
|
106
|
+
>
|
|
107
|
+
<Select.Item value="active">Active</Select.Item>
|
|
108
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
109
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
110
|
+
</Select>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Disabled
|
|
116
|
+
|
|
117
|
+
Set `disabled` to prevent interaction with the field.
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import React from "react";
|
|
121
|
+
import { Select } from "@jobber/components/Select";
|
|
122
|
+
|
|
123
|
+
export function SelectDisabledExample() {
|
|
124
|
+
return (
|
|
125
|
+
<Select label="Status" disabled value="active">
|
|
126
|
+
<Select.Item value="active">Active</Select.Item>
|
|
127
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
128
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
129
|
+
</Select>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Grouping
|
|
135
|
+
|
|
136
|
+
Organize related options under section headers with `Select.Group` and
|
|
137
|
+
`Select.GroupLabel`. Adjacent groups are divided automatically, so you don't
|
|
138
|
+
need to add a separator between them. `Select.Separator` is available for adding
|
|
139
|
+
a divider elsewhere in the list.
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
import React, { useState } from "react";
|
|
143
|
+
import { Select } from "@jobber/components/Select";
|
|
144
|
+
|
|
145
|
+
export function SelectGroupedExample() {
|
|
146
|
+
const [value, setValue] = useState<string | undefined>();
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<Select label="Produce" value={value} onValueChange={setValue}>
|
|
150
|
+
<Select.Group>
|
|
151
|
+
<Select.GroupLabel>Fruits</Select.GroupLabel>
|
|
152
|
+
<Select.Item value="apple">Apple</Select.Item>
|
|
153
|
+
<Select.Item value="banana">Banana</Select.Item>
|
|
154
|
+
</Select.Group>
|
|
155
|
+
<Select.Group>
|
|
156
|
+
<Select.GroupLabel>Vegetables</Select.GroupLabel>
|
|
157
|
+
<Select.Item value="carrot">Carrot</Select.Item>
|
|
158
|
+
<Select.Item value="spinach">Spinach</Select.Item>
|
|
159
|
+
</Select.Group>
|
|
160
|
+
</Select>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Custom selected value
|
|
166
|
+
|
|
167
|
+
The closed trigger shows the selected value capitalized by default. Pass
|
|
168
|
+
`renderValue` to display something different from the option's label — here the
|
|
169
|
+
list shows short labels (`Low`, `Medium`, `High`) while the trigger shows the
|
|
170
|
+
full `"High priority"`. The open list always shows each `Select.Item`'s
|
|
171
|
+
children.
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import React, { useState } from "react";
|
|
175
|
+
import { Select } from "@jobber/components/Select";
|
|
176
|
+
|
|
177
|
+
const PRIORITY_LABELS: Record<string, string> = {
|
|
178
|
+
low: "Low priority",
|
|
179
|
+
medium: "Medium priority",
|
|
180
|
+
high: "High priority",
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export function SelectRenderValueExample() {
|
|
184
|
+
const [value, setValue] = useState<string | undefined>("high");
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<Select
|
|
188
|
+
label="Priority"
|
|
189
|
+
value={value}
|
|
190
|
+
onValueChange={setValue}
|
|
191
|
+
renderValue={selected => PRIORITY_LABELS[selected]}
|
|
192
|
+
>
|
|
193
|
+
<Select.Item value="low">Low</Select.Item>
|
|
194
|
+
<Select.Item value="medium">Medium</Select.Item>
|
|
195
|
+
<Select.Item value="high">High</Select.Item>
|
|
196
|
+
</Select>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Sizes
|
|
202
|
+
|
|
203
|
+
Use the `size` prop to render a `small` control for tighter layouts. The
|
|
204
|
+
floating mini-label is hidden at the `small` size, so the compact control keeps
|
|
205
|
+
a single-line height.
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
import React, { useState } from "react";
|
|
209
|
+
import { Select } from "@jobber/components/Select";
|
|
210
|
+
|
|
211
|
+
export function SelectSizeExample() {
|
|
212
|
+
const [value, setValue] = useState<string | undefined>("active");
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
<Select label="Status" size="small" value={value} onValueChange={setValue}>
|
|
216
|
+
<Select.Item value="active">Active</Select.Item>
|
|
217
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
218
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
219
|
+
</Select>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Inline
|
|
225
|
+
|
|
226
|
+
Set `inline` to embed the Select within a line of text. The description and
|
|
227
|
+
error messaging are suppressed in inline mode.
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
import React, { useState } from "react";
|
|
231
|
+
import { Select } from "@jobber/components/Select";
|
|
232
|
+
|
|
233
|
+
export function SelectInlineExample() {
|
|
234
|
+
const [value, setValue] = useState<string | undefined>("active");
|
|
235
|
+
|
|
236
|
+
return (
|
|
237
|
+
<div>
|
|
238
|
+
Set the record to{" "}
|
|
239
|
+
<Select label="Status" inline value={value} onValueChange={setValue}>
|
|
240
|
+
<Select.Item value="active">Active</Select.Item>
|
|
241
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
242
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
243
|
+
</Select>{" "}
|
|
244
|
+
today.
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Mobile
|
|
251
|
+
|
|
252
|
+
On small (touch-sized) web screens — viewport widths of `490px` or less — the
|
|
253
|
+
options open as a bottom sheet instead of an anchored dropdown, matching the
|
|
254
|
+
mobile pattern used by `Menu` and `Dialog`. This is automatic and requires no
|
|
255
|
+
props; selection, keyboard, and focus behaviour are unchanged. Resize the
|
|
256
|
+
preview narrow (or open the examples above on a phone) to see the sheet.
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
## Content
|
|
260
|
+
|
|
261
|
+
### Options and labels
|
|
262
|
+
|
|
263
|
+
Declare each option with `Select.Item`. The `value` prop is what `onValueChange`
|
|
264
|
+
reports and what is submitted with a form; the children are the human-readable
|
|
265
|
+
label shown in the open list.
|
|
266
|
+
|
|
267
|
+
### The selected value display
|
|
268
|
+
|
|
269
|
+
The closed trigger shows the selected **value**, capitalized by default (e.g.
|
|
270
|
+
`"active"` → `"Active"`). It does not read the option's children — so when the
|
|
271
|
+
label differs from the capitalized value, pass `renderValue` to control what the
|
|
272
|
+
trigger shows:
|
|
273
|
+
|
|
274
|
+
```tsx
|
|
275
|
+
<Select
|
|
276
|
+
label="Status"
|
|
277
|
+
value={value}
|
|
278
|
+
onValueChange={setValue}
|
|
279
|
+
renderValue={value => STATUS_LABELS[value]}
|
|
280
|
+
>
|
|
281
|
+
{/* Select.Item options */}
|
|
282
|
+
</Select>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Grouping
|
|
286
|
+
|
|
287
|
+
* `Select.Group`: wraps a set of related options.
|
|
288
|
+
* `Select.GroupLabel`: the section header text for a group.
|
|
289
|
+
* `Select.Separator`: an optional visual divider. Adjacent `Select.Group`s are
|
|
290
|
+
already divided automatically, so reach for this only to divide options
|
|
291
|
+
elsewhere in the list.
|
|
292
|
+
|
|
293
|
+
## Component customization
|
|
294
|
+
|
|
295
|
+
Select is intentionally opinionated: it exposes a curated set of props rather
|
|
296
|
+
than the full underlying API. The subcomponents (`Select.Item`, `Select.Group`,
|
|
297
|
+
`Select.GroupLabel`, `Select.Separator`) accept `className` and `style` for
|
|
298
|
+
per-option styling; reach out to UXF if you need behaviour beyond what the props
|
|
299
|
+
provide.
|
|
300
|
+
|
|
301
|
+
### Controlled usage
|
|
302
|
+
|
|
303
|
+
Select is controlled only. Always pass `value` and `onValueChange`; there is no
|
|
304
|
+
uncontrolled `defaultValue`. The `id` and `name` are generated for you and wired
|
|
305
|
+
to the label automatically.
|
|
306
|
+
|
|
307
|
+
The change handler is named `onValueChange` to stay isomorphic with Base UI, and
|
|
308
|
+
to encode the payload (the value, not an event) in its name.
|
|
309
|
+
|
|
310
|
+
### Using with a form library
|
|
311
|
+
|
|
312
|
+
Select is form-library-agnostic — it exposes plain controlled props, so any
|
|
313
|
+
system (React Hook Form, Formik, TanStack Form, or plain `useState`) drives it
|
|
314
|
+
by wiring:
|
|
315
|
+
|
|
316
|
+
* `value` — the current value
|
|
317
|
+
* `onValueChange` — the library's value setter
|
|
318
|
+
* `onBlur` / `onFocus` — touched state and blur/focus-mode validation
|
|
319
|
+
* `error` (message) or `invalid` (styling only) — validation feedback
|
|
320
|
+
* `ref` — exposes `focus()`, so a form can focus this field on error
|
|
321
|
+
|
|
322
|
+
Because the change prop is `onValueChange` (not `onChange`), spreading a field
|
|
323
|
+
object whose handler is named `onChange` — for example React Hook Form's `field`
|
|
324
|
+
via `<Select {...field} />` — will **not** wire up the change handler.
|
|
325
|
+
`field.onChange` lands on a prop nothing reads, and JSX spread does not error,
|
|
326
|
+
so the field silently stops updating. Wire the props explicitly instead:
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
<Controller
|
|
330
|
+
control={control}
|
|
331
|
+
name="status"
|
|
332
|
+
render={({ field }) => (
|
|
333
|
+
<Select
|
|
334
|
+
label="Status"
|
|
335
|
+
name={field.name}
|
|
336
|
+
value={field.value}
|
|
337
|
+
onValueChange={field.onChange}
|
|
338
|
+
onBlur={field.onBlur}
|
|
339
|
+
ref={field.ref}
|
|
340
|
+
>
|
|
341
|
+
{/* Select.Item options */}
|
|
342
|
+
</Select>
|
|
343
|
+
)}
|
|
344
|
+
/>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
If you want spread ergonomics, keep the remap in your own app — the design
|
|
348
|
+
system intentionally ships no form-library adapter:
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
// app-side helper, not part of @jobber/components
|
|
352
|
+
const toValueField = ({ onChange, ...field }) => ({
|
|
353
|
+
...field,
|
|
354
|
+
onValueChange: onChange,
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
<Select label="Status" {...toValueField(field)}>
|
|
358
|
+
{/* Select.Item options */}
|
|
359
|
+
</Select>;
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
> **Note:** Select is built on Base UI's `Field` primitive, but it is not yet
|
|
363
|
+
> wired to participate in a surrounding Base UI `<Form>` — the `Form` `errors`
|
|
364
|
+
> prop and `Form`-driven focus-on-error do not reach Select. Drive validation
|
|
365
|
+
> through the `error` / `invalid` props for now.
|
|
366
|
+
|
|
367
|
+
## Related components
|
|
368
|
+
|
|
369
|
+
* [LegacySelect](../LegacySelect/LegacySelect.md): the previous native `<select>`-based
|
|
370
|
+
implementation.
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
## Props
|
|
374
|
+
|
|
375
|
+
### Web
|
|
376
|
+
|
|
377
|
+
#### Select
|
|
378
|
+
|
|
379
|
+
| Prop | Type | Required | Default | Description |
|
|
380
|
+
|------|------|----------|---------|-------------|
|
|
381
|
+
| `children` | `ReactNode` | No | — | `Select.Item`, `Select.Group`, `Select.GroupLabel`, and `Select.Separator` that make up the dropdown list. |
|
|
382
|
+
| `description` | `ReactNode` | No | — | Helper text rendered beneath the field. |
|
|
383
|
+
| `disabled` | `boolean` | No | — | Disables the whole field. |
|
|
384
|
+
| `error` | `string` | No | — | Error message. Shows the message beneath the field and applies invalid styling. Replaces the description while present. |
|
|
385
|
+
| `id` | `string` | No | — | Id applied to the field's trigger. Auto-generated when omitted. |
|
|
386
|
+
| `inline` | `boolean` | No | — | Renders the field inline and suppresses the description / error. |
|
|
387
|
+
| `invalid` | `boolean` | No | — | Applies invalid styling without rendering a message. Use when the message is rendered elsewhere (e.g. by React Hook F... |
|
|
388
|
+
| `label` | `string` | No | — | Floating label shown inside the field. It sits as the placeholder when no value is selected and rises to a mini-label... |
|
|
389
|
+
| `name` | `string` | No | — | Name used for the form field (FormData key, autofill, test selectors). |
|
|
390
|
+
| `onBlur` | `() => void` | No | — | Called when the field's trigger loses focus. Useful for touched state and blur-mode validation. |
|
|
391
|
+
| `onFocus` | `() => void` | No | — | Called when the field's trigger receives focus. |
|
|
392
|
+
| `onValueChange` | `(value: string) => void` | No | — | Called with the newly selected value. Named to match Base UI. Note: React Hook Form's `field.onChange` will not be wi... |
|
|
393
|
+
| `ref` | `Ref<SelectRef>` | No | — | Imperative handle exposing `focus()`. |
|
|
394
|
+
| `renderValue` | `(value: string) => ReactNode` | No | — | Renders the selected value shown in the closed trigger. When omitted, the value is shown capitalized (e.g. `"active"`... |
|
|
395
|
+
| `size` | `"large" | "small"` | No | — | Field size. |
|
|
396
|
+
| `value` | `string` | No | — | The controlled selected value. `null` (or `undefined`) when empty. |
|
|
397
|
+
|
|
398
|
+
#### Select.Group
|
|
399
|
+
|
|
400
|
+
| Prop | Type | Required | Default | Description |
|
|
401
|
+
|------|------|----------|---------|-------------|
|
|
402
|
+
| `children` | `ReactNode` | No | — | A `Select.GroupLabel` and the `Select.Item`s that belong to the group. |
|
|
403
|
+
| `className` | `string` | No | — | |
|
|
404
|
+
| `style` | `CSSProperties` | No | — | |
|
|
405
|
+
|
|
406
|
+
#### Select.GroupLabel
|
|
407
|
+
|
|
408
|
+
| Prop | Type | Required | Default | Description |
|
|
409
|
+
|------|------|----------|---------|-------------|
|
|
410
|
+
| `children` | `ReactNode` | No | — | The section heading shown above the group's options. |
|
|
411
|
+
| `className` | `string` | No | — | |
|
|
412
|
+
| `style` | `CSSProperties` | No | — | |
|
|
413
|
+
|
|
414
|
+
#### Select.Item
|
|
415
|
+
|
|
416
|
+
| Prop | Type | Required | Default | Description |
|
|
417
|
+
|------|------|----------|---------|-------------|
|
|
418
|
+
| `children` | `ReactNode` | Yes | — | The display label for the option. |
|
|
419
|
+
| `value` | `string` | Yes | — | The value submitted when this option is selected. |
|
|
420
|
+
| `className` | `string` | No | — | |
|
|
421
|
+
| `style` | `CSSProperties` | No | — | |
|
|
422
|
+
|
|
423
|
+
#### Select.Separator
|
|
424
|
+
|
|
425
|
+
| Prop | Type | Required | Default | Description |
|
|
426
|
+
|------|------|----------|---------|-------------|
|
|
427
|
+
| `className` | `string` | No | — | |
|
|
428
|
+
| `style` | `CSSProperties` | No | — | |
|
|
@@ -194,7 +194,7 @@ Base UI.
|
|
|
194
194
|
|------|------|----------|---------|-------------|
|
|
195
195
|
| `className` | `string | ((state: SelectPortalState) => string)` | No | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
|
|
196
196
|
| `container` | `HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot>` | No | — | A parent element to render the portal element into. |
|
|
197
|
-
| `ref` | `Ref<
|
|
197
|
+
| `ref` | `Ref<HTMLButtonElement>` | No | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (... |
|
|
198
198
|
| `render` | `ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectPortalState>` | No | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accep... |
|
|
199
199
|
| `style` | `CSSProperties | ((state: SelectPortalState) => CSSProperties)` | No | — | Style applied to the element, or a function that returns a style object based on the component's state. |
|
|
200
200
|
|
|
@@ -226,6 +226,13 @@ Base UI.
|
|
|
226
226
|
| `required` | `boolean` | No | `false` | Whether the user must choose a value before submitting a form. |
|
|
227
227
|
| `value` | `SelectValueType<Value, Multiple>` | No | — | The value of the select. Use when controlled. |
|
|
228
228
|
|
|
229
|
+
#### SelectPrimitiveFieldTrigger
|
|
230
|
+
|
|
231
|
+
| Prop | Type | Required | Default | Description |
|
|
232
|
+
|------|------|----------|---------|-------------|
|
|
233
|
+
| `ref` | `Ref<HTMLButtonElement>` | No | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (... |
|
|
234
|
+
| `valueSlot` | `ReactNode` | No | — | The value/placeholder display element rendered before the chevron. |
|
|
235
|
+
|
|
229
236
|
#### SelectPrimitiveGroup
|
|
230
237
|
|
|
231
238
|
| Prop | Type | Required | Default | Description |
|
|
@@ -337,3 +344,9 @@ Base UI.
|
|
|
337
344
|
| `placeholder` | `ReactNode` | No | — | The placeholder value to display when no value is selected. This is overridden by `children` if specified, or by a nu... |
|
|
338
345
|
| `render` | `ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectValueState>` | No | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accep... |
|
|
339
346
|
| `style` | `CSSProperties | ((state: SelectValueState) => CSSProperties)` | No | — | Style applied to the element, or a function that returns a style object based on the component's state. |
|
|
347
|
+
|
|
348
|
+
#### SelectPrimitiveValueText
|
|
349
|
+
|
|
350
|
+
| Prop | Type | Required | Default | Description |
|
|
351
|
+
|------|------|----------|---------|-------------|
|
|
352
|
+
| `ref` | `Ref<HTMLButtonElement>` | No | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (... |
|
package/dist/docs/index.md
CHANGED
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
[ResponsiveSwitcher](./ResponsiveSwitcher/ResponsiveSwitcher.md)
|
|
82
82
|
[scaffolding](./scaffolding/scaffolding.md)
|
|
83
83
|
[SegmentedControl](./SegmentedControl/SegmentedControl.md)
|
|
84
|
+
[Select](./Select/Select.md)
|
|
84
85
|
[SelectPrimitive](./SelectPrimitive/SelectPrimitive.md)
|
|
85
86
|
[settings](./settings/settings.md)
|
|
86
87
|
[SideDrawer](./SideDrawer/SideDrawer.md)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { g as getSideAxis, a as getAlignmentAxis, b as getSide, c as getAlignment, e as evaluate, d as getPaddingObject, r as rectToClientRect, h as getOppositePlacement, i as getExpandedPlacements, j as getOppositeAxisPlacements, k as getAlignmentSides, l as clamp, m as min, n as max, o as getAxisLength, s as sides, p as getOppositeAxis, q as placements, t as getOppositeAlignmentPlacement, u as createCoords, v as round, f as floor } from './floating-ui.utils-es.js';
|
|
2
|
-
import { k as getDocumentElement, b as isElement,
|
|
2
|
+
import { k as getDocumentElement, b as isElement, i as isHTMLElement, l as isTopLayer, g as getNodeName, m as isOverflowElement, n as getNodeScroll, o as getWindow, e as getParentNode, d as isLastTraversableNode, p as isTableElement, q as isContainingBlock, r as getContainingBlock, f as getComputedStyle$1, h as getOverflowAncestors, s as getFrameElement, j as isWebKit } from './floating-ui.utils.dom-es.js';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { useLayoutEffect } from 'react';
|
|
5
5
|
import * as ReactDOM from 'react-dom';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useLayoutEffect } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { a as isShadowRoot, i as isHTMLElement, b as isElement, c as isNode, g as getNodeName, d as isLastTraversableNode, e as getParentNode, f as getComputedStyle$1, h as getOverflowAncestors, j as isWebKit } from './floating-ui.utils.dom-es.js';
|
|
4
4
|
import { f as floor } from './floating-ui.utils-es.js';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import * as ReactDOM from 'react-dom';
|
|
@@ -162,4 +162,4 @@ function getFrameElement(win) {
|
|
|
162
162
|
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
export {
|
|
165
|
+
export { isShadowRoot as a, isElement as b, isNode as c, isLastTraversableNode as d, getParentNode as e, getComputedStyle as f, getNodeName as g, getOverflowAncestors as h, isHTMLElement as i, isWebKit as j, getDocumentElement as k, isTopLayer as l, isOverflowElement as m, getNodeScroll as n, getWindow as o, isTableElement as p, isContainingBlock as q, getContainingBlock as r, getFrameElement as s };
|
package/dist/index.cjs
CHANGED
|
@@ -73,6 +73,7 @@ var RadioGroup = require('./RadioGroup-cjs.js');
|
|
|
73
73
|
var ResponsiveSwitcher = require('./ResponsiveSwitcher-cjs.js');
|
|
74
74
|
var LegacySelect = require('./LegacySelect-cjs.js');
|
|
75
75
|
var SegmentedControl = require('./SegmentedControl-cjs.js');
|
|
76
|
+
var Select = require('./Select-cjs.js');
|
|
76
77
|
var SideDrawer = require('./SideDrawer-cjs.js');
|
|
77
78
|
var SideKick = require('./SideKick-cjs.js');
|
|
78
79
|
var Spinner = require('./Spinner-cjs.js');
|
|
@@ -190,6 +191,13 @@ require('./MenuSubmenuTrigger-cjs.js');
|
|
|
190
191
|
require('./useCompositeListItem-cjs.js');
|
|
191
192
|
require('./isElementDisabled-cjs.js');
|
|
192
193
|
require('./AtlantisPortalContent-cjs.js');
|
|
194
|
+
require('./SelectPrimitive-cjs.js');
|
|
195
|
+
require('./SelectGroupLabel-cjs.js');
|
|
196
|
+
require('./useLabelableId-cjs.js');
|
|
197
|
+
require('./resolveAriaLabelledBy-cjs.js');
|
|
198
|
+
require('./HelperText-cjs.js');
|
|
199
|
+
require('./FieldDescription-cjs.js');
|
|
200
|
+
require('./useLabel-cjs.js');
|
|
193
201
|
require('@jobber/formatters');
|
|
194
202
|
require('react-dom/client');
|
|
195
203
|
|
|
@@ -324,6 +332,7 @@ exports.SegmentedControl = SegmentedControl.SegmentedControl;
|
|
|
324
332
|
exports.SegmentedControlContext = SegmentedControl.SegmentedControlContext;
|
|
325
333
|
exports.SegmentedControlProvider = SegmentedControl.SegmentedControlProvider;
|
|
326
334
|
exports.useSegmentedControl = SegmentedControl.useSegmentedControl;
|
|
335
|
+
exports.Select = Select.Select;
|
|
327
336
|
exports.SideDrawer = SideDrawer.SideDrawer;
|
|
328
337
|
exports.SideKick = SideKick.SideKick;
|
|
329
338
|
exports.Spinner = Spinner.Spinner;
|
package/dist/index.d.mts
CHANGED
|
@@ -64,6 +64,7 @@ export * from "./RadioGroup";
|
|
|
64
64
|
export * from "./ResponsiveSwitcher";
|
|
65
65
|
export * from "./LegacySelect";
|
|
66
66
|
export * from "./SegmentedControl";
|
|
67
|
+
export * from "./Select";
|
|
67
68
|
export * from "./SideDrawer";
|
|
68
69
|
export * from "./SideKick";
|
|
69
70
|
export * from "./Spinner";
|
package/dist/index.d.ts
CHANGED
|
@@ -64,6 +64,7 @@ export * from "./RadioGroup";
|
|
|
64
64
|
export * from "./ResponsiveSwitcher";
|
|
65
65
|
export * from "./LegacySelect";
|
|
66
66
|
export * from "./SegmentedControl";
|
|
67
|
+
export * from "./Select";
|
|
67
68
|
export * from "./SideDrawer";
|
|
68
69
|
export * from "./SideKick";
|
|
69
70
|
export * from "./Spinner";
|
package/dist/index.mjs
CHANGED
|
@@ -71,6 +71,7 @@ export { R as RadioGroup, a as RadioOption } from './RadioGroup-es.js';
|
|
|
71
71
|
export { R as ResponsiveSwitcher } from './ResponsiveSwitcher-es.js';
|
|
72
72
|
export { L as LegacySelect, S as Option } from './LegacySelect-es.js';
|
|
73
73
|
export { S as SegmentedControl, a as SegmentedControlContext, b as SegmentedControlProvider, u as useSegmentedControl } from './SegmentedControl-es.js';
|
|
74
|
+
export { S as Select } from './Select-es.js';
|
|
74
75
|
export { S as SideDrawer } from './SideDrawer-es.js';
|
|
75
76
|
export { S as SideKick } from './SideKick-es.js';
|
|
76
77
|
export { S as Spinner } from './Spinner-es.js';
|
|
@@ -188,6 +189,13 @@ import './MenuSubmenuTrigger-es.js';
|
|
|
188
189
|
import './useCompositeListItem-es.js';
|
|
189
190
|
import './isElementDisabled-es.js';
|
|
190
191
|
import './AtlantisPortalContent-es.js';
|
|
192
|
+
import './SelectPrimitive-es.js';
|
|
193
|
+
import './SelectGroupLabel-es.js';
|
|
194
|
+
import './useLabelableId-es.js';
|
|
195
|
+
import './resolveAriaLabelledBy-es.js';
|
|
196
|
+
import './HelperText-es.js';
|
|
197
|
+
import './FieldDescription-es.js';
|
|
198
|
+
import './useLabel-es.js';
|
|
191
199
|
import '@jobber/formatters';
|
|
192
200
|
import 'react-dom/client';
|
|
193
201
|
|
|
@@ -22,6 +22,7 @@ require('react/jsx-runtime');
|
|
|
22
22
|
require('../../floating-ui.utils-cjs.js');
|
|
23
23
|
require('../../floating-ui.react-dom-cjs.js');
|
|
24
24
|
require('../../resolveAriaLabelledBy-cjs.js');
|
|
25
|
+
require('../../stringifyLocale-cjs.js');
|
|
25
26
|
require('../../useLabel-cjs.js');
|
|
26
27
|
require('../../Separator-cjs.js');
|
|
27
28
|
|
|
@@ -20,5 +20,6 @@ import 'react/jsx-runtime';
|
|
|
20
20
|
import '../../floating-ui.utils-es.js';
|
|
21
21
|
import '../../floating-ui.react-dom-es.js';
|
|
22
22
|
import '../../resolveAriaLabelledBy-es.js';
|
|
23
|
+
import '../../stringifyLocale-es.js';
|
|
23
24
|
import '../../useLabel-es.js';
|
|
24
25
|
import '../../Separator-es.js';
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
2
3
|
export interface HelperTextProps {
|
|
3
4
|
/**
|
|
4
5
|
* The helper message.
|
|
5
6
|
*/
|
|
6
|
-
readonly message:
|
|
7
|
+
readonly message: ReactNode;
|
|
7
8
|
/**
|
|
8
9
|
* `neutral` renders subdued text. `critical` renders an `alert` icon
|
|
9
10
|
* followed by error-coloured text.
|
|
@@ -11,13 +11,15 @@ require('../../Icon-cjs.js');
|
|
|
11
11
|
require('@jobber/design');
|
|
12
12
|
require('../../Typography-cjs.js');
|
|
13
13
|
require('../../useRenderElement-cjs.js');
|
|
14
|
+
require('../../FieldDescription-cjs.js');
|
|
14
15
|
require('../../useButton-cjs.js');
|
|
15
16
|
require('../../floating-ui.utils.dom-cjs.js');
|
|
16
17
|
require('react-dom');
|
|
17
18
|
require('../../useLabelableId-cjs.js');
|
|
18
19
|
require('react/jsx-runtime');
|
|
19
|
-
require('../../NumberFieldInput-cjs.js');
|
|
20
20
|
require('../../useLabel-cjs.js');
|
|
21
|
+
require('../../NumberFieldInput-cjs.js');
|
|
22
|
+
require('../../stringifyLocale-cjs.js');
|
|
21
23
|
require('../../clamp-cjs.js');
|
|
22
24
|
|
|
23
25
|
|
|
@@ -9,11 +9,13 @@ import '../../Icon-es.js';
|
|
|
9
9
|
import '@jobber/design';
|
|
10
10
|
import '../../Typography-es.js';
|
|
11
11
|
import '../../useRenderElement-es.js';
|
|
12
|
+
import '../../FieldDescription-es.js';
|
|
12
13
|
import '../../useButton-es.js';
|
|
13
14
|
import '../../floating-ui.utils.dom-es.js';
|
|
14
15
|
import 'react-dom';
|
|
15
16
|
import '../../useLabelableId-es.js';
|
|
16
17
|
import 'react/jsx-runtime';
|
|
17
|
-
import '../../NumberFieldInput-es.js';
|
|
18
18
|
import '../../useLabel-es.js';
|
|
19
|
+
import '../../NumberFieldInput-es.js';
|
|
20
|
+
import '../../stringifyLocale-es.js';
|
|
19
21
|
import '../../clamp-es.js';
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import type { SelectPrimitiveFieldTriggerProps, SelectPrimitiveValueTextProps } from "./types";
|
|
2
3
|
import { Select } from "../../unstyledPrimitives";
|
|
3
4
|
import { OverlaySeparator } from "../OverlaySeparator";
|
|
5
|
+
declare function SelectPrimitiveFieldTrigger({ valueSlot, className, ...props }: SelectPrimitiveFieldTriggerProps): React.JSX.Element;
|
|
6
|
+
declare namespace SelectPrimitiveFieldTrigger {
|
|
7
|
+
var displayName: string;
|
|
8
|
+
}
|
|
4
9
|
declare function SelectPrimitiveTrigger({ className, children, ...props }: React.ComponentPropsWithoutRef<typeof Select.Trigger>): React.JSX.Element;
|
|
5
10
|
declare namespace SelectPrimitiveTrigger {
|
|
6
11
|
var displayName: string;
|
|
@@ -9,6 +14,10 @@ declare function SelectPrimitiveValue({ className, ...props }: React.ComponentPr
|
|
|
9
14
|
declare namespace SelectPrimitiveValue {
|
|
10
15
|
var displayName: string;
|
|
11
16
|
}
|
|
17
|
+
declare function SelectPrimitiveValueText({ className, ...props }: SelectPrimitiveValueTextProps): React.JSX.Element;
|
|
18
|
+
declare namespace SelectPrimitiveValueText {
|
|
19
|
+
var displayName: string;
|
|
20
|
+
}
|
|
12
21
|
declare function SelectPrimitivePositioner({ className, sideOffset, alignItemWithTrigger, ...props }: React.ComponentPropsWithoutRef<typeof Select.Positioner>): React.JSX.Element;
|
|
13
22
|
declare namespace SelectPrimitivePositioner {
|
|
14
23
|
var displayName: string;
|
|
@@ -48,7 +57,9 @@ declare namespace SelectPrimitiveSeparator {
|
|
|
48
57
|
export declare const SelectPrimitive: {
|
|
49
58
|
Root: typeof Select.Root;
|
|
50
59
|
Trigger: typeof SelectPrimitiveTrigger;
|
|
60
|
+
FieldTrigger: typeof SelectPrimitiveFieldTrigger;
|
|
51
61
|
Value: typeof SelectPrimitiveValue;
|
|
62
|
+
ValueText: typeof SelectPrimitiveValueText;
|
|
52
63
|
Portal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react").SelectPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
53
64
|
Positioner: typeof SelectPrimitivePositioner;
|
|
54
65
|
Popup: typeof SelectPrimitivePopup;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { SelectPrimitive } from "./SelectPrimitive";
|
|
2
|
-
export type { SelectPrimitiveRootProps, SelectPrimitiveTriggerProps, SelectPrimitiveValueProps, SelectPrimitivePortalProps, SelectPrimitivePositionerProps, SelectPrimitivePopupProps, SelectPrimitiveListProps, SelectPrimitiveItemProps, SelectPrimitiveItemTextProps, SelectPrimitiveItemIndicatorProps, SelectPrimitiveGroupProps, SelectPrimitiveGroupLabelProps, SelectPrimitiveSeparatorProps, } from "./types";
|
|
2
|
+
export type { SelectPrimitiveRootProps, SelectPrimitiveTriggerProps, SelectPrimitiveFieldTriggerProps, SelectPrimitiveValueProps, SelectPrimitiveValueTextProps, SelectPrimitivePortalProps, SelectPrimitivePositionerProps, SelectPrimitivePopupProps, SelectPrimitiveListProps, SelectPrimitiveItemProps, SelectPrimitiveItemTextProps, SelectPrimitiveItemIndicatorProps, SelectPrimitiveGroupProps, SelectPrimitiveGroupLabelProps, SelectPrimitiveSeparatorProps, } from "./types";
|