@jobber/components-native 0.113.3 → 0.113.4
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/docs/Select/Select.md +276 -143
- package/dist/package.json +2 -2
- package/dist/src/Button/Button.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/Button/Button.tsx +1 -1
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
# Select
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
Select presents a defined list of options and lets the user pick a single value.
|
|
6
|
+
Use it when the choice is one of a known, reasonably short list that lives
|
|
7
|
+
inside a form. For longer lists or free-text search, use
|
|
8
|
+
[Autocomplete](/components/Autocomplete); for triggering an action rather than
|
|
9
|
+
picking a value, use [Menu](/components/Menu).
|
|
6
10
|
|
|
7
11
|
```tsx
|
|
8
12
|
import React, { useState } from "react";
|
|
@@ -21,21 +25,30 @@ export function SelectBasicExample() {
|
|
|
21
25
|
}
|
|
22
26
|
```
|
|
23
27
|
|
|
24
|
-
##
|
|
28
|
+
## Anatomy
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
| Part | Description |
|
|
31
|
+
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
32
|
+
| Trigger | The field the user clicks to open the list |
|
|
33
|
+
| Label | Names the field. Sits inside the trigger when empty, floats to a mini-label once a value is chosen. Doubles as the empty-state hint |
|
|
34
|
+
| Value | The selected option, shown inside the trigger |
|
|
35
|
+
| Dropdown | The floating panel of options on large screens |
|
|
36
|
+
| Bottom sheet | The panel of options on small screens (≤490px). Automatic |
|
|
37
|
+
| Item | An individual option in the list |
|
|
38
|
+
| Group | Optional — wraps related items under a shared heading |
|
|
39
|
+
| Group label | Optional — the heading shown above a group |
|
|
40
|
+
| Separator | Optional — a divider between items outside of groups |
|
|
41
|
+
| Description | Optional — helper text shown beneath the field |
|
|
42
|
+
| Error message | Optional — replaces the description while an error is present |
|
|
29
43
|
|
|
30
|
-
|
|
31
|
-
keep your state in sync.
|
|
44
|
+
## Behaviour
|
|
32
45
|
|
|
33
|
-
|
|
46
|
+
#### Label as placeholder
|
|
34
47
|
|
|
35
|
-
The `label` doubles as the
|
|
36
|
-
centered inside the
|
|
37
|
-
|
|
38
|
-
role.
|
|
48
|
+
The `label` names the field and doubles as the empty state. While no value is
|
|
49
|
+
selected it sits centered inside the trigger; once the user picks an option it
|
|
50
|
+
floats up as a mini-label. There is no separate `placeholder` prop — the label
|
|
51
|
+
fills that role.
|
|
39
52
|
|
|
40
53
|
```tsx
|
|
41
54
|
import React, { useState } from "react";
|
|
@@ -54,89 +67,62 @@ export function SelectEmptyExample() {
|
|
|
54
67
|
}
|
|
55
68
|
```
|
|
56
69
|
|
|
57
|
-
|
|
70
|
+
#### Selected value display
|
|
58
71
|
|
|
59
|
-
|
|
72
|
+
The closed trigger shows the selected `value`, capitalized (e.g. `"active"` →
|
|
73
|
+
`"Active"`). It does **not** read the item's children. When the display label
|
|
74
|
+
differs from the capitalized value, pass `renderValue` to control what the
|
|
75
|
+
trigger shows — otherwise the trigger will silently drift from the list.
|
|
60
76
|
|
|
61
77
|
```tsx
|
|
62
78
|
import React, { useState } from "react";
|
|
63
79
|
import { Select } from "@jobber/components/Select";
|
|
64
80
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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";
|
|
81
|
+
const PRIORITY_LABELS: Record<string, string> = {
|
|
82
|
+
low: "Low priority",
|
|
83
|
+
medium: "Medium priority",
|
|
84
|
+
high: "High priority",
|
|
85
|
+
};
|
|
95
86
|
|
|
96
|
-
export function
|
|
97
|
-
const [value, setValue] = useState<string | undefined>();
|
|
87
|
+
export function SelectRenderValueExample() {
|
|
88
|
+
const [value, setValue] = useState<string | undefined>("high");
|
|
98
89
|
|
|
99
90
|
return (
|
|
100
91
|
<Select
|
|
101
|
-
label="
|
|
102
|
-
description="This controls who can see the record."
|
|
103
|
-
error="Please choose a status."
|
|
92
|
+
label="Priority"
|
|
104
93
|
value={value}
|
|
105
94
|
onValueChange={setValue}
|
|
95
|
+
renderValue={selected => PRIORITY_LABELS[selected]}
|
|
106
96
|
>
|
|
107
|
-
<Select.Item value="
|
|
108
|
-
<Select.Item value="
|
|
109
|
-
<Select.Item value="
|
|
97
|
+
<Select.Item value="low">Low</Select.Item>
|
|
98
|
+
<Select.Item value="medium">Medium</Select.Item>
|
|
99
|
+
<Select.Item value="high">High</Select.Item>
|
|
110
100
|
</Select>
|
|
111
101
|
);
|
|
112
102
|
}
|
|
113
103
|
```
|
|
114
104
|
|
|
115
|
-
|
|
105
|
+
#### Small screens
|
|
116
106
|
|
|
117
|
-
|
|
107
|
+
On viewports ≤490px the options open as a bottom sheet instead of an anchored
|
|
108
|
+
dropdown, matching the pattern used by [Menu](/components/Menu) and
|
|
109
|
+
[Dialog](/components/Dialog). This is automatic — the same authored child tree
|
|
110
|
+
renders on both. Resize the preview narrow to see the sheet.
|
|
118
111
|
|
|
119
|
-
|
|
120
|
-
import React from "react";
|
|
121
|
-
import { Select } from "@jobber/components/Select";
|
|
112
|
+
#### Controlled only
|
|
122
113
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
<Select.Item value="draft">Draft</Select.Item>
|
|
129
|
-
</Select>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
```
|
|
114
|
+
Select is controlled: always pass `value` and `onValueChange`. There is no
|
|
115
|
+
uncontrolled `defaultValue`. The change prop is named `onValueChange` (not
|
|
116
|
+
`onChange`) to match the Base UI foundation and to encode the payload — the
|
|
117
|
+
value, not an event — in its name. See [Content guidelines](#content-guidelines)
|
|
118
|
+
for how this affects form-library wiring.
|
|
133
119
|
|
|
134
|
-
|
|
120
|
+
#### Grouping
|
|
135
121
|
|
|
136
122
|
Organize related options under section headers with `Select.Group` and
|
|
137
123
|
`Select.GroupLabel`. Adjacent groups are divided automatically, so you don't
|
|
138
|
-
need
|
|
139
|
-
|
|
124
|
+
need a `Select.Separator` between them — reach for `Select.Separator` only to
|
|
125
|
+
divide items that sit outside groups.
|
|
140
126
|
|
|
141
127
|
```tsx
|
|
142
128
|
import React, { useState } from "react";
|
|
@@ -162,47 +148,85 @@ export function SelectGroupedExample() {
|
|
|
162
148
|
}
|
|
163
149
|
```
|
|
164
150
|
|
|
165
|
-
|
|
151
|
+
#### States
|
|
166
152
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
153
|
+
* **Description** — pass `description` to add supporting help text beneath the
|
|
154
|
+
field.
|
|
155
|
+
* **Error** — pass an `error` message to mark the field invalid and show the
|
|
156
|
+
message beneath the field. The error replaces the description while it is
|
|
157
|
+
present.
|
|
158
|
+
* **Invalid without a message** — use `invalid` on its own to apply the invalid
|
|
159
|
+
styling without a message, for example when a form library renders the error
|
|
160
|
+
text itself.
|
|
161
|
+
* **Disabled** — set `disabled` to prevent interaction with the field.
|
|
172
162
|
|
|
173
163
|
```tsx
|
|
174
164
|
import React, { useState } from "react";
|
|
175
165
|
import { Select } from "@jobber/components/Select";
|
|
176
166
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
medium: "Medium priority",
|
|
180
|
-
high: "High priority",
|
|
181
|
-
};
|
|
167
|
+
export function SelectDescriptionExample() {
|
|
168
|
+
const [value, setValue] = useState<string | undefined>();
|
|
182
169
|
|
|
183
|
-
|
|
184
|
-
|
|
170
|
+
return (
|
|
171
|
+
<Select
|
|
172
|
+
label="Status"
|
|
173
|
+
description="This controls who can see the record."
|
|
174
|
+
value={value}
|
|
175
|
+
onValueChange={setValue}
|
|
176
|
+
>
|
|
177
|
+
<Select.Item value="active">Active</Select.Item>
|
|
178
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
179
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
180
|
+
</Select>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import React, { useState } from "react";
|
|
187
|
+
import { Select } from "@jobber/components/Select";
|
|
188
|
+
|
|
189
|
+
export function SelectErrorExample() {
|
|
190
|
+
const [value, setValue] = useState<string | undefined>();
|
|
185
191
|
|
|
186
192
|
return (
|
|
187
193
|
<Select
|
|
188
|
-
label="
|
|
194
|
+
label="Status"
|
|
195
|
+
description="This controls who can see the record."
|
|
196
|
+
error="Please choose a status."
|
|
189
197
|
value={value}
|
|
190
198
|
onValueChange={setValue}
|
|
191
|
-
renderValue={selected => PRIORITY_LABELS[selected]}
|
|
192
199
|
>
|
|
193
|
-
<Select.Item value="
|
|
194
|
-
<Select.Item value="
|
|
195
|
-
<Select.Item value="
|
|
200
|
+
<Select.Item value="active">Active</Select.Item>
|
|
201
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
202
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
196
203
|
</Select>
|
|
197
204
|
);
|
|
198
205
|
}
|
|
199
206
|
```
|
|
200
207
|
|
|
201
|
-
|
|
208
|
+
```tsx
|
|
209
|
+
import React from "react";
|
|
210
|
+
import { Select } from "@jobber/components/Select";
|
|
211
|
+
|
|
212
|
+
export function SelectDisabledExample() {
|
|
213
|
+
return (
|
|
214
|
+
<Select label="Status" disabled value="active">
|
|
215
|
+
<Select.Item value="active">Active</Select.Item>
|
|
216
|
+
<Select.Item value="archived">Archived</Select.Item>
|
|
217
|
+
<Select.Item value="draft">Draft</Select.Item>
|
|
218
|
+
</Select>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Variants
|
|
224
|
+
|
|
225
|
+
### Sizes
|
|
202
226
|
|
|
203
|
-
Use
|
|
204
|
-
|
|
205
|
-
|
|
227
|
+
Use `size="small"` for tighter layouts. The floating mini-label is hidden at the
|
|
228
|
+
small size, so the compact control keeps a single-line height. Prefer the
|
|
229
|
+
default (large) size in forms so the label remains visible after selection.
|
|
206
230
|
|
|
207
231
|
```tsx
|
|
208
232
|
import React, { useState } from "react";
|
|
@@ -221,10 +245,11 @@ export function SelectSizeExample() {
|
|
|
221
245
|
}
|
|
222
246
|
```
|
|
223
247
|
|
|
224
|
-
|
|
248
|
+
### Inline
|
|
225
249
|
|
|
226
250
|
Set `inline` to embed the Select within a line of text. The description and
|
|
227
|
-
error messaging are suppressed in inline mode
|
|
251
|
+
error messaging are suppressed in inline mode, so pair it with validation that
|
|
252
|
+
lives elsewhere in the surrounding sentence or paragraph.
|
|
228
253
|
|
|
229
254
|
```tsx
|
|
230
255
|
import React, { useState } from "react";
|
|
@@ -247,48 +272,170 @@ export function SelectInlineExample() {
|
|
|
247
272
|
}
|
|
248
273
|
```
|
|
249
274
|
|
|
250
|
-
##
|
|
275
|
+
## Content guidelines
|
|
251
276
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
preview narrow (or open the examples above on a phone) to see the sheet.
|
|
277
|
+
Option labels are scanned quickly while the list is open and then read back as
|
|
278
|
+
the chosen value once it's closed so they have to work in both places. And
|
|
279
|
+
because the `label` prop doubles as the empty-state hint, it has to work as a
|
|
280
|
+
field name and as an invitation to pick.
|
|
257
281
|
|
|
282
|
+
#### Sentence case
|
|
258
283
|
|
|
259
|
-
|
|
284
|
+
Option labels and group labels are sentence-cased. Capitalize only the first
|
|
285
|
+
letter unless there is a proper noun (a person's name, a brand). Jobber features
|
|
286
|
+
like jobs, quotes, and invoices are not proper nouns.
|
|
260
287
|
|
|
261
|
-
|
|
288
|
+
| ✅ Do | ❌ Don't |
|
|
289
|
+
| ----------------- | ----------------- |
|
|
290
|
+
| Credit/debit card | Credit/Debit Card |
|
|
291
|
+
| Bank transfer | BANK TRANSFER |
|
|
292
|
+
| Authorize.net | authorize.net |
|
|
293
|
+
| Jasmine Williams | jasmine williams |
|
|
262
294
|
|
|
263
|
-
|
|
264
|
-
reports and what is submitted with a form; the children are the human-readable
|
|
265
|
-
label shown in the open list.
|
|
295
|
+
#### Noun-first labels
|
|
266
296
|
|
|
267
|
-
|
|
297
|
+
Select options represent things the user is picking, not actions they're taking.
|
|
298
|
+
Lead with the noun. If a label reads like an imperative verb phrase, reach for
|
|
299
|
+
[Menu](/components/Menu) or a set of buttons instead.
|
|
268
300
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
301
|
+
| ✅ Do | ❌ Don't |
|
|
302
|
+
| ------- | -------------------- |
|
|
303
|
+
| Cash | Paid by cash |
|
|
304
|
+
| Draft | Save as draft |
|
|
305
|
+
| Overdue | Show overdue only |
|
|
306
|
+
| Active | Set status to active |
|
|
307
|
+
|
|
308
|
+
#### Keep labels short and parallel
|
|
309
|
+
|
|
310
|
+
Aim for 1–3 words. Every item in the same list should follow the same
|
|
311
|
+
grammatical shape.
|
|
273
312
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
313
|
+
| ✅ Do | ❌ Don't |
|
|
314
|
+
| ---------------------------------- | ---------------------------------------------------- |
|
|
315
|
+
| Small / Medium / Large | Small / 12px / Large |
|
|
316
|
+
| Draft / Sent / Paid | Draft / Sent to client / Payment received |
|
|
317
|
+
| Bank transfer / Credit card / Cash | Bank transfer / Charge to credit card / Cash on hand |
|
|
318
|
+
|
|
319
|
+
#### The `label` prop names the field and is the empty state
|
|
320
|
+
|
|
321
|
+
The `label` is both the field heading and, before a value is picked, the
|
|
322
|
+
placeholder inside the trigger. Use a noun or short noun phrase (1–3 words).
|
|
323
|
+
Don't include the word "Select" or "Choose"; the field itself is the invitation.
|
|
324
|
+
|
|
325
|
+
| ✅ Do | ❌ Don't |
|
|
326
|
+
| -------------- | --------------------------- |
|
|
327
|
+
| Payment method | Select a payment method |
|
|
328
|
+
| Status | Choose a status |
|
|
329
|
+
| Team member | Please assign a team member |
|
|
330
|
+
|
|
331
|
+
#### Don't repeat the label in every option
|
|
332
|
+
|
|
333
|
+
The `label` already names the category. Repeating it in each option adds noise
|
|
334
|
+
and eats horizontal space in the trigger. With a `label` of "Payment method":
|
|
335
|
+
|
|
336
|
+
| ✅ Do | ❌ Don't |
|
|
337
|
+
| ---------- | --------------------- |
|
|
338
|
+
| Cash | Cash payment method |
|
|
339
|
+
| Cheque | Cheque payment method |
|
|
340
|
+
| E-transfer | Payment by e-transfer |
|
|
341
|
+
|
|
342
|
+
#### Group labels describe, don't instruct
|
|
343
|
+
|
|
344
|
+
Keep group labels to 1–2 words that name the category. Don't phrase them as
|
|
345
|
+
prompts to the user.
|
|
346
|
+
|
|
347
|
+
| ✅ Do | ❌ Don't |
|
|
348
|
+
| --------------- | ------------------------- |
|
|
349
|
+
| Jobber Payments | Payments through Jobber |
|
|
350
|
+
| Manual entry | Record a payment manually |
|
|
351
|
+
| Active | Currently active statuses |
|
|
352
|
+
|
|
353
|
+
#### Use `renderValue` when the trigger should differ from the item
|
|
354
|
+
|
|
355
|
+
By default the trigger shows the selected `value` capitalized. Pass
|
|
356
|
+
`renderValue` when the item label carries detail the trigger doesn't need, when
|
|
357
|
+
the underlying value is a raw enum, or when items include an icon or adornment.
|
|
358
|
+
The item shows what the user is choosing between; the trigger
|
|
359
|
+
shows what they chose.
|
|
360
|
+
|
|
361
|
+
| Scenario | Item label | `renderValue` returns |
|
|
362
|
+
| ------------------------------- | ----------------------------- | --------------------- |
|
|
363
|
+
| Item has qualifying detail | `High — needs response today` | `High` |
|
|
364
|
+
| Item includes an icon adornment | `🔒 Private` | `Private` |
|
|
365
|
+
|
|
366
|
+
## Do's and Don'ts
|
|
367
|
+
|
|
368
|
+
#### Do:
|
|
369
|
+
|
|
370
|
+
* ✅ Use sentence case for option and group labels
|
|
371
|
+
* ✅ Pass `renderValue` whenever the item label differs from the capitalized
|
|
372
|
+
`value`
|
|
373
|
+
* ✅ Wire `value`, `onValueChange`, `onBlur`, and `ref` explicitly when using a
|
|
374
|
+
form library
|
|
375
|
+
* ✅ Group options with `Select.Group` + `Select.GroupLabel` when they fall into
|
|
376
|
+
two or more categories
|
|
377
|
+
* ✅ Reach for [Autocomplete](/components/Autocomplete) instead when the list is
|
|
378
|
+
long or benefits from typeahead
|
|
379
|
+
|
|
380
|
+
#### Don't:
|
|
284
381
|
|
|
285
|
-
|
|
382
|
+
* ❌ Don't spread a React Hook Form `field` object into Select — `onValueChange`
|
|
383
|
+
won't wire from `field.onChange` and the field will silently stop updating
|
|
384
|
+
* ❌ Don't include "Select" or "Choose" in the `label` — the field itself is the
|
|
385
|
+
invitation
|
|
386
|
+
* ❌ Don't mix noun options and verb options in the same list; if the items are
|
|
387
|
+
actions, use [Menu](/components/Menu) instead
|
|
388
|
+
* ❌ Don't repeat the field's label as a prefix in every option
|
|
389
|
+
* ❌ Don't assume the trigger shows the item's children — it shows the `value`,
|
|
390
|
+
capitalized, unless you pass `renderValue`
|
|
391
|
+
|
|
392
|
+
## Accessibility
|
|
393
|
+
|
|
394
|
+
Select is built on Base UI's `Field` and `Select` primitives, which handle label
|
|
395
|
+
wiring, ARIA state, and the interaction model.
|
|
396
|
+
|
|
397
|
+
#### Keyboard navigation
|
|
398
|
+
|
|
399
|
+
| Key | Behaviour |
|
|
400
|
+
| ------------------ | ------------------------------------------------------------------- |
|
|
401
|
+
| Tab | Moves focus to the trigger |
|
|
402
|
+
| Enter or Space | Opens the dropdown / bottom sheet |
|
|
403
|
+
| Up and Down arrows | Move through the list. Wrap at the ends |
|
|
404
|
+
| Home / End | Jump to the first or last option |
|
|
405
|
+
| Enter | Selects the highlighted option and closes |
|
|
406
|
+
| Esc | Closes without selecting |
|
|
407
|
+
| Type-to-select | Typing letters jumps to the next option starting with those letters |
|
|
408
|
+
|
|
409
|
+
#### Screen readers
|
|
410
|
+
|
|
411
|
+
The `label` is wired to the trigger via `Field.Label`, so screen readers
|
|
412
|
+
announce the field's purpose along with the selected value. When `error` or
|
|
413
|
+
`invalid` is set, the field is announced as invalid; the `error` message is
|
|
414
|
+
associated with the field so it is read after the label.
|
|
415
|
+
|
|
416
|
+
#### Focus management
|
|
417
|
+
|
|
418
|
+
Select exposes an imperative `ref.focus()` handle that moves focus to the
|
|
419
|
+
trigger. Use it to implement focus-on-error in a form — for example, focusing
|
|
420
|
+
the first invalid Select when the SP tries to submit.
|
|
421
|
+
|
|
422
|
+
#### Touch targets
|
|
423
|
+
|
|
424
|
+
On small screens (≤490px) the options open as a bottom sheet, so each item gets
|
|
425
|
+
the vertical space needed to hit standard touch-target sizing. No per-item
|
|
426
|
+
configuration required.
|
|
427
|
+
|
|
428
|
+
## Related components
|
|
429
|
+
|
|
430
|
+
* Use [LegacySelect](/components/LegacySelect) if you are working in an app that
|
|
431
|
+
has not yet migrated off the previous native `<select>`-based implementation.
|
|
432
|
+
* Use [Autocomplete](/components/Autocomplete) when the list is long, needs
|
|
433
|
+
typeahead search, or when the user might type a value that isn't in the list.
|
|
434
|
+
* Use [Menu](/components/Menu) when the choice triggers an action rather than
|
|
435
|
+
picking a value that persists in the form.
|
|
436
|
+
* Use [RadioGroup](/components/RadioGroup) when the set of options is small
|
|
437
|
+
(roughly five or fewer) and it helps the SP to see all of them at once.
|
|
286
438
|
|
|
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
439
|
|
|
293
440
|
## Component customization
|
|
294
441
|
|
|
@@ -298,16 +445,7 @@ than the full underlying API. The subcomponents (`Select.Item`, `Select.Group`,
|
|
|
298
445
|
per-option styling; reach out to UXF if you need behaviour beyond what the props
|
|
299
446
|
provide.
|
|
300
447
|
|
|
301
|
-
|
|
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
|
|
448
|
+
## Using with a form library
|
|
311
449
|
|
|
312
450
|
Select is form-library-agnostic — it exposes plain controlled props, so any
|
|
313
451
|
system (React Hook Form, Formik, TanStack Form, or plain `useState`) drives it
|
|
@@ -364,11 +502,6 @@ const toValueField = ({ onChange, ...field }) => ({
|
|
|
364
502
|
> prop and `Form`-driven focus-on-error do not reach Select. Drive validation
|
|
365
503
|
> through the `error` / `invalid` props for now.
|
|
366
504
|
|
|
367
|
-
## Related components
|
|
368
|
-
|
|
369
|
-
* [LegacySelect](/components/LegacySelect): the previous native `<select>`-based
|
|
370
|
-
implementation.
|
|
371
|
-
|
|
372
505
|
|
|
373
506
|
## Props
|
|
374
507
|
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components-native",
|
|
3
|
-
"version": "0.113.
|
|
3
|
+
"version": "0.113.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React Native implementation of Atlantis",
|
|
6
6
|
"repository": {
|
|
@@ -124,5 +124,5 @@
|
|
|
124
124
|
"react-native-screens": ">=4.18.0",
|
|
125
125
|
"react-native-svg": ">=12.0.0"
|
|
126
126
|
},
|
|
127
|
-
"gitHead": "
|
|
127
|
+
"gitHead": "b151fce2d669e8b85cea91becf7d9aacee827c3e"
|
|
128
128
|
}
|
|
@@ -58,7 +58,7 @@ function getIconColorVariation(variation, type, disabled) {
|
|
|
58
58
|
return "disabled";
|
|
59
59
|
}
|
|
60
60
|
if (type === "primary" && variation !== "cancel") {
|
|
61
|
-
return "
|
|
61
|
+
return "surface"; // This should be a text color token instead, but the action label also uses this
|
|
62
62
|
}
|
|
63
63
|
switch (variation) {
|
|
64
64
|
case "learning":
|