@tempoxyz/ds 0.3.9 → 0.3.11
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/AGENTS.md +9 -0
- package/dist/docs/components/accordion.md +489 -0
- package/dist/docs/components/address-card.md +147 -0
- package/dist/docs/components/agent-logo.md +194 -0
- package/dist/docs/components/alert-dialog.md +631 -0
- package/dist/docs/components/alert.md +448 -0
- package/dist/docs/components/amount-input.md +305 -0
- package/dist/docs/components/amount.md +794 -0
- package/dist/docs/components/app-shell.md +559 -0
- package/dist/docs/components/asset-chip.md +294 -0
- package/dist/docs/components/autocomplete.md +619 -0
- package/dist/docs/components/avatar.md +321 -0
- package/dist/docs/components/badge.md +339 -0
- package/dist/docs/components/badged-logo.md +116 -0
- package/dist/docs/components/banner.md +379 -0
- package/dist/docs/components/bar-chart.md +208 -0
- package/dist/docs/components/breadcrumbs.md +380 -0
- package/dist/docs/components/button-group.md +286 -0
- package/dist/docs/components/button.md +650 -0
- package/dist/docs/components/calendar.md +375 -0
- package/dist/docs/components/callout.md +96 -0
- package/dist/docs/components/checkbox-group.md +521 -0
- package/dist/docs/components/checkbox.md +467 -0
- package/dist/docs/components/choice-group.md +516 -0
- package/dist/docs/components/choicebox.md +641 -0
- package/dist/docs/components/code.md +100 -0
- package/dist/docs/components/combobox.md +939 -0
- package/dist/docs/components/container.md +257 -0
- package/dist/docs/components/copy-button.md +642 -0
- package/dist/docs/components/date-picker.md +514 -0
- package/dist/docs/components/dialog.md +1332 -0
- package/dist/docs/components/drawer.md +966 -0
- package/dist/docs/components/empty.md +340 -0
- package/dist/docs/components/field.md +570 -0
- package/dist/docs/components/fieldset.md +398 -0
- package/dist/docs/components/frame.md +434 -0
- package/dist/docs/components/gauge.md +299 -0
- package/dist/docs/components/get-started-visual.md +117 -0
- package/dist/docs/components/grid.md +288 -0
- package/dist/docs/components/hero-visual.md +155 -0
- package/dist/docs/components/hex.md +487 -0
- package/dist/docs/components/icon-tile.md +292 -0
- package/dist/docs/components/identicon.md +371 -0
- package/dist/docs/components/inline.md +233 -0
- package/dist/docs/components/inset.md +225 -0
- package/dist/docs/components/kbd.md +423 -0
- package/dist/docs/components/list-group.md +981 -0
- package/dist/docs/components/loading-dots.md +237 -0
- package/dist/docs/components/menu.md +934 -0
- package/dist/docs/components/native-select.md +204 -0
- package/dist/docs/components/network-logo.md +248 -0
- package/dist/docs/components/number-field.md +543 -0
- package/dist/docs/components/otp-field.md +616 -0
- package/dist/docs/components/pagination.md +516 -0
- package/dist/docs/components/popover.md +544 -0
- package/dist/docs/components/progress.md +388 -0
- package/dist/docs/components/qr.md +314 -0
- package/dist/docs/components/radio-group.md +528 -0
- package/dist/docs/components/secret-value.md +406 -0
- package/dist/docs/components/select.md +751 -0
- package/dist/docs/components/separator.md +379 -0
- package/dist/docs/components/sidebar-menu.md +922 -0
- package/dist/docs/components/skeleton.md +517 -0
- package/dist/docs/components/slider.md +539 -0
- package/dist/docs/components/snippet.md +424 -0
- package/dist/docs/components/spinner.md +216 -0
- package/dist/docs/components/split-bar.md +139 -0
- package/dist/docs/components/split-button.md +464 -0
- package/dist/docs/components/stack.md +299 -0
- package/dist/docs/components/status-chip.md +226 -0
- package/dist/docs/components/status-indicator.md +119 -0
- package/dist/docs/components/status-row.md +174 -0
- package/dist/docs/components/stepper.md +451 -0
- package/dist/docs/components/success-hero.md +157 -0
- package/dist/docs/components/surface.md +639 -0
- package/dist/docs/components/switch.md +472 -0
- package/dist/docs/components/table.md +967 -0
- package/dist/docs/components/tabs.md +627 -0
- package/dist/docs/components/tempo-logo.md +185 -0
- package/dist/docs/components/text-input.md +624 -0
- package/dist/docs/components/textarea.md +352 -0
- package/dist/docs/components/toast.md +535 -0
- package/dist/docs/components/token-logo.md +371 -0
- package/dist/docs/components/token.md +247 -0
- package/dist/docs/components/tooltip.md +490 -0
- package/dist/docs/components/verification-code.md +116 -0
- package/dist/docs/components/visual.md +249 -0
- package/dist/docs/components.md +203 -0
- package/dist/docs/foundations/accessibility.md +377 -0
- package/dist/docs/foundations/agents.md +150 -0
- package/dist/docs/foundations/color.md +522 -0
- package/dist/docs/foundations/content/tone.md +194 -0
- package/dist/docs/foundations/content/voice.md +194 -0
- package/dist/docs/foundations/content/writing-style.md +406 -0
- package/dist/docs/foundations/iconography.md +282 -0
- package/dist/docs/foundations/intent.md +360 -0
- package/dist/docs/foundations/layout.md +508 -0
- package/dist/docs/foundations/linter.md +296 -0
- package/dist/docs/foundations/motion.md +151 -0
- package/dist/docs/foundations/radius-and-padding.md +86 -0
- package/dist/docs/foundations/typography.md +266 -0
- package/dist/docs/index.md +137 -0
- package/dist/docs/introduction/faq.md +132 -0
- package/dist/docs/introduction/getting-started.md +377 -0
- package/dist/docs/patterns/blockchain-values.md +709 -0
- package/dist/docs/patterns/dashboards.md +638 -0
- package/dist/docs/patterns/destructive-actions.md +626 -0
- package/dist/docs/patterns/empty-states.md +612 -0
- package/dist/docs/patterns/errors-and-validation.md +808 -0
- package/dist/docs/patterns/feedback-and-status.md +518 -0
- package/dist/docs/patterns/forms.md +679 -0
- package/dist/docs/patterns/loading.md +630 -0
- package/dist/docs/patterns/navigation.md +397 -0
- package/dist/docs/patterns/payments.md +765 -0
- package/dist/docs/patterns/responsive-layout.md +997 -0
- package/dist/docs/patterns/tables-and-lists.md +964 -0
- package/dist/docs/products/tempo-console.md +671 -0
- package/dist/docs/products/tempo-performance.md +437 -0
- package/dist/docs/products/tempo-wallet.md +438 -0
- package/dist/web/components/OtpField.css +1 -1
- package/dist/web/components/OtpField.d.ts +1 -1
- package/dist/web/components/OtpField.d.ts.map +1 -1
- package/dist/web/components/OtpField.js +3 -4
- package/dist/web/components/OtpField.js.map +1 -1
- package/dist/web/components/OtpField.js.zyzz.json +1 -1
- package/dist/web/index.js.zyzz.json +1 -1
- package/package.json +1 -1
- package/src/web/components/OtpField.tsx +2 -24
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
# Field
|
|
2
|
+
|
|
3
|
+
Links a label, description, and error message to a control.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Field.tsx)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
A field links a label, description, and error message to the control inside it.
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Basic
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Field, TextInput } from '@tempoxyz/ds'
|
|
17
|
+
|
|
18
|
+
export function Demo() {
|
|
19
|
+
return (
|
|
20
|
+
<Field.Root>
|
|
21
|
+
<Field.Label>Email</Field.Label>
|
|
22
|
+
<TextInput.Group>
|
|
23
|
+
<TextInput.Control placeholder="alice@example.com" type="email" />
|
|
24
|
+
</TextInput.Group>
|
|
25
|
+
<Field.Description>Used for receipts.</Field.Description>
|
|
26
|
+
</Field.Root>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Field/Basic.tsx)
|
|
32
|
+
|
|
33
|
+
### Invalid
|
|
34
|
+
|
|
35
|
+
Set `invalid` to fill the control red and show a matching `Field.Error` in place of the description.
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { Field, TextInput } from '@tempoxyz/ds'
|
|
39
|
+
|
|
40
|
+
export function Demo() {
|
|
41
|
+
return (
|
|
42
|
+
<Field.Root invalid>
|
|
43
|
+
<Field.Label>Invalid</Field.Label>
|
|
44
|
+
<TextInput.Group>
|
|
45
|
+
<TextInput.Control defaultValue="alice" type="email" />
|
|
46
|
+
</TextInput.Group>
|
|
47
|
+
<Field.Description>Used for receipts.</Field.Description>
|
|
48
|
+
<Field.Error match>Enter a valid email.</Field.Error>
|
|
49
|
+
</Field.Root>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Field/Invalid.tsx)
|
|
55
|
+
|
|
56
|
+
### Success
|
|
57
|
+
|
|
58
|
+
Set `success` to end a text field with a check, and to set the description in the positive color.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { Field, TextInput } from '@tempoxyz/ds'
|
|
62
|
+
|
|
63
|
+
export function Demo() {
|
|
64
|
+
return (
|
|
65
|
+
<Field.Root success>
|
|
66
|
+
<Field.Label>Success</Field.Label>
|
|
67
|
+
<TextInput.Group>
|
|
68
|
+
<TextInput.Control defaultValue="alice@example.com" type="email" />
|
|
69
|
+
</TextInput.Group>
|
|
70
|
+
</Field.Root>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Field/Success.tsx)
|
|
76
|
+
|
|
77
|
+
### Secondary Label
|
|
78
|
+
|
|
79
|
+
Put a `Field.SecondaryLabel` inside `Field.Label` for a qualifier at the end of the label row, such as Optional. It joins the control's accessible name.
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
83
|
+
|
|
84
|
+
export const fill = true
|
|
85
|
+
export function Demo() {
|
|
86
|
+
return (
|
|
87
|
+
<Field.Root {...styles.field()}>
|
|
88
|
+
<Field.Label>
|
|
89
|
+
Memo <Field.SecondaryLabel>Optional</Field.SecondaryLabel>
|
|
90
|
+
</Field.Label>
|
|
91
|
+
<TextInput.Group>
|
|
92
|
+
<TextInput.Control placeholder="What is it for?" />
|
|
93
|
+
</TextInput.Group>
|
|
94
|
+
<Field.Description>Only you and Maya can see this</Field.Description>
|
|
95
|
+
</Field.Root>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
namespace styles {
|
|
100
|
+
export const field = style({ maxWidth: '24rem !custom' })
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Field/SecondaryLabel.tsx)
|
|
105
|
+
|
|
106
|
+
### Size
|
|
107
|
+
|
|
108
|
+
Set `size` to `medium` (default) or `large`. A large field sets the label in the regular weight with its secondary label beside it, sets the description at 14px, and insets a text field or textarea 20px.
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import { Field, style, Textarea, TextInput } from '@tempoxyz/ds'
|
|
112
|
+
|
|
113
|
+
export function Demo() {
|
|
114
|
+
return (
|
|
115
|
+
<div {...styles.grid()}>
|
|
116
|
+
<Field.Root size="large">
|
|
117
|
+
<Field.Label>
|
|
118
|
+
Display name<Field.SecondaryLabel>Optional</Field.SecondaryLabel>
|
|
119
|
+
</Field.Label>
|
|
120
|
+
<TextInput.Group>
|
|
121
|
+
<TextInput.Control placeholder="Maya Chen" />
|
|
122
|
+
</TextInput.Group>
|
|
123
|
+
<Field.Description>Shown to people you pay</Field.Description>
|
|
124
|
+
</Field.Root>
|
|
125
|
+
<Field.Root size="large">
|
|
126
|
+
<Field.Label>
|
|
127
|
+
Bio<Field.SecondaryLabel>Optional</Field.SecondaryLabel>
|
|
128
|
+
</Field.Label>
|
|
129
|
+
<Textarea placeholder="A few words about you" rows={2} />
|
|
130
|
+
<Field.Description>Up to 160 characters</Field.Description>
|
|
131
|
+
</Field.Root>
|
|
132
|
+
</div>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
namespace styles {
|
|
137
|
+
export const grid = style({
|
|
138
|
+
alignItems: 'start',
|
|
139
|
+
display: 'grid',
|
|
140
|
+
gap: '24',
|
|
141
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(min(280px, 100%), 1fr)) !custom',
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Field/Size.tsx)
|
|
147
|
+
|
|
148
|
+
### Disabled
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { Field, TextInput } from '@tempoxyz/ds'
|
|
152
|
+
|
|
153
|
+
export function Demo() {
|
|
154
|
+
return (
|
|
155
|
+
<Field.Root disabled>
|
|
156
|
+
<Field.Label>Disabled</Field.Label>
|
|
157
|
+
<TextInput.Group>
|
|
158
|
+
<TextInput.Control defaultValue="Locked" />
|
|
159
|
+
</TextInput.Group>
|
|
160
|
+
</Field.Root>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Field/Disabled.tsx)
|
|
166
|
+
|
|
167
|
+
### Item
|
|
168
|
+
|
|
169
|
+
Wrap a checkbox or radio and its `Field.Label` in `Field.Item` to put them on one row.
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { Checkbox, Field } from '@tempoxyz/ds'
|
|
173
|
+
|
|
174
|
+
export function Demo() {
|
|
175
|
+
return (
|
|
176
|
+
<Field.Root>
|
|
177
|
+
<Field.Item>
|
|
178
|
+
<Checkbox defaultChecked />
|
|
179
|
+
<Field.Label>Item with a checkbox</Field.Label>
|
|
180
|
+
</Field.Item>
|
|
181
|
+
</Field.Root>
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Field/Item.tsx)
|
|
187
|
+
|
|
188
|
+
## Anatomy
|
|
189
|
+
|
|
190
|
+
Import the component and assemble its parts.
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { Field } from '@tempoxyz/ds'
|
|
194
|
+
|
|
195
|
+
<Field.Root>
|
|
196
|
+
<Field.Label>
|
|
197
|
+
<Field.SecondaryLabel />
|
|
198
|
+
</Field.Label>
|
|
199
|
+
<Field.Item />
|
|
200
|
+
<Field.Description />
|
|
201
|
+
<Field.Error />
|
|
202
|
+
</Field.Root>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Guidelines
|
|
206
|
+
|
|
207
|
+
### When to Use
|
|
208
|
+
|
|
209
|
+
* Label an input control, such as [TextInput](/docs/components/text-input), [AmountInput](/docs/components/amount-input), [Textarea](/docs/components/textarea), [Select](/docs/components/select), or [Combobox](/docs/components/combobox).
|
|
210
|
+
* Attach a hint or an error to that control.
|
|
211
|
+
* Put a [Checkbox](/docs/components/checkbox) or radio on one row with its label through `Field.Item`.
|
|
212
|
+
* Label a [Switch](/docs/components/switch) above it, with its description below.
|
|
213
|
+
|
|
214
|
+
### When Not to Use
|
|
215
|
+
|
|
216
|
+
* Use [Fieldset](/docs/components/fieldset) to name a group of related fields, such as a billing address.
|
|
217
|
+
* Use [ListGroup](/docs/components/list-group) for read-only details.
|
|
218
|
+
* Use an [Alert](/docs/components/alert) above the form to summarize a failed submission.
|
|
219
|
+
|
|
220
|
+
### Give Every Control a Visible Label
|
|
221
|
+
|
|
222
|
+
**Do:** Name the control with a `Field.Label` and put the format in the description.
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
/**
|
|
226
|
+
* Do example for "Give Every Control a Visible Label" on the Field page.
|
|
227
|
+
* Name the control with a `Field.Label` and put the format in the description.
|
|
228
|
+
* @module
|
|
229
|
+
*/
|
|
230
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
231
|
+
|
|
232
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
233
|
+
export function Demo() {
|
|
234
|
+
return (
|
|
235
|
+
<Field.Root {...styles.field()}>
|
|
236
|
+
<Field.Label>Recipient</Field.Label>
|
|
237
|
+
<TextInput.Group>
|
|
238
|
+
<TextInput.Control placeholder="0x…" />
|
|
239
|
+
</TextInput.Group>
|
|
240
|
+
<Field.Description>A Tempo address that starts with 0x.</Field.Description>
|
|
241
|
+
</Field.Root>
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
namespace styles {
|
|
246
|
+
export const field = style({ width: '100% !custom' })
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Don't:** Use the placeholder as the only label.
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
/**
|
|
254
|
+
* Don't example for "Give Every Control a Visible Label" on the Field page.
|
|
255
|
+
* Don't use the placeholder as the only label.
|
|
256
|
+
* @module
|
|
257
|
+
*/
|
|
258
|
+
import { style, TextInput } from '@tempoxyz/ds'
|
|
259
|
+
|
|
260
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
261
|
+
export function Demo() {
|
|
262
|
+
return (
|
|
263
|
+
<TextInput.Group {...styles.group()}>
|
|
264
|
+
<TextInput.Control aria-label="Recipient" placeholder="Recipient address" />
|
|
265
|
+
</TextInput.Group>
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
namespace styles {
|
|
270
|
+
export const group = style({ width: '100% !custom' })
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Keep Hints in the Description
|
|
275
|
+
|
|
276
|
+
Use `Field.Description` for one fact about the value, such as a format or a limit. Keep the label to the name of the value.
|
|
277
|
+
|
|
278
|
+
**Do:** Put the limit in `Field.Description` below the control.
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
/**
|
|
282
|
+
* Do example for "Keep Hints in the Description" on the Field page.
|
|
283
|
+
* Put the limit in `Field.Description` below the control.
|
|
284
|
+
* @module
|
|
285
|
+
*/
|
|
286
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
287
|
+
|
|
288
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
289
|
+
export function Demo() {
|
|
290
|
+
return (
|
|
291
|
+
<Field.Root {...styles.field()}>
|
|
292
|
+
<Field.Label>Key name</Field.Label>
|
|
293
|
+
<TextInput.Group>
|
|
294
|
+
<TextInput.Control defaultValue="Payroll server" />
|
|
295
|
+
</TextInput.Group>
|
|
296
|
+
<Field.Description>Up to 32 letters, numbers, or spaces.</Field.Description>
|
|
297
|
+
</Field.Root>
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
namespace styles {
|
|
302
|
+
export const field = style({ width: '100% !custom' })
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Don't:** Pack formats and limits into the label.
|
|
307
|
+
|
|
308
|
+
```tsx
|
|
309
|
+
/**
|
|
310
|
+
* Don't example for "Keep Hints in the Description" on the Field page.
|
|
311
|
+
* Don't pack formats and limits into the label.
|
|
312
|
+
* @module
|
|
313
|
+
*/
|
|
314
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
315
|
+
|
|
316
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
317
|
+
export function Demo() {
|
|
318
|
+
return (
|
|
319
|
+
<Field.Root {...styles.field()}>
|
|
320
|
+
<Field.Label>Key name (up to 32 letters, numbers, or spaces)</Field.Label>
|
|
321
|
+
<TextInput.Group>
|
|
322
|
+
<TextInput.Control defaultValue="Payroll server" />
|
|
323
|
+
</TextInput.Group>
|
|
324
|
+
</Field.Root>
|
|
325
|
+
)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
namespace styles {
|
|
329
|
+
export const field = style({ width: '100% !custom' })
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Write Errors That Say How to Fix the Value
|
|
334
|
+
|
|
335
|
+
Start the `Field.Error` with a verb, such as Enter or Choose, and include the limit, such as Enter an amount up to 250.00 USDC. A shown error replaces the description, so repeat any limit the error depends on.
|
|
336
|
+
|
|
337
|
+
**Do:** Say what the value needs, such as the https\:// scheme.
|
|
338
|
+
|
|
339
|
+
```tsx
|
|
340
|
+
/**
|
|
341
|
+
* Do example for "Write Errors That Say How to Fix the Value" on the Field page.
|
|
342
|
+
* Say what the value needs, such as the https:// scheme.
|
|
343
|
+
* @module
|
|
344
|
+
*/
|
|
345
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
346
|
+
|
|
347
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
348
|
+
export function Demo() {
|
|
349
|
+
return (
|
|
350
|
+
<Field.Root invalid {...styles.field()}>
|
|
351
|
+
<Field.Label>Webhook URL</Field.Label>
|
|
352
|
+
<TextInput.Group>
|
|
353
|
+
<TextInput.Control defaultValue="http://api.example.com/hooks" type="url" />
|
|
354
|
+
</TextInput.Group>
|
|
355
|
+
<Field.Error match>Enter a URL that starts with https://.</Field.Error>
|
|
356
|
+
</Field.Root>
|
|
357
|
+
)
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
namespace styles {
|
|
361
|
+
export const field = style({ width: '100% !custom' })
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**Don't:** Show a generic message such as Invalid input.
|
|
366
|
+
|
|
367
|
+
```tsx
|
|
368
|
+
/**
|
|
369
|
+
* Don't example for "Write Errors That Say How to Fix the Value" on the Field page.
|
|
370
|
+
* Don't show a generic message such as Invalid input.
|
|
371
|
+
* @module
|
|
372
|
+
*/
|
|
373
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
374
|
+
|
|
375
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
376
|
+
export function Demo() {
|
|
377
|
+
return (
|
|
378
|
+
<Field.Root invalid {...styles.field()}>
|
|
379
|
+
<Field.Label>Webhook URL</Field.Label>
|
|
380
|
+
<TextInput.Group>
|
|
381
|
+
<TextInput.Control defaultValue="http://api.example.com/hooks" type="url" />
|
|
382
|
+
</TextInput.Group>
|
|
383
|
+
<Field.Error match>Invalid input.</Field.Error>
|
|
384
|
+
</Field.Root>
|
|
385
|
+
)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
namespace styles {
|
|
389
|
+
export const field = style({ width: '100% !custom' })
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Validate When the Value Is Complete
|
|
394
|
+
|
|
395
|
+
`Field.Root` validates on submit, then on each change after a failed submit. For format checks, such as a URL, set `validationMode="onBlur"`. Pass `validate` for custom rules. If another library owns validation, set `invalid`. See [Errors and Validation](/docs/patterns/errors-and-validation).
|
|
396
|
+
|
|
397
|
+
**Do:** Leave a partial value unmarked until focus leaves the field.
|
|
398
|
+
|
|
399
|
+
```tsx
|
|
400
|
+
/**
|
|
401
|
+
* Do example for "Validate When the Value Is Complete" on the Field page.
|
|
402
|
+
* Leave a partial value unmarked until focus leaves the field.
|
|
403
|
+
* @module
|
|
404
|
+
*/
|
|
405
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
406
|
+
|
|
407
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
408
|
+
export function Demo() {
|
|
409
|
+
return (
|
|
410
|
+
<Field.Root validationMode="onBlur" {...styles.field()}>
|
|
411
|
+
<Field.Label>Webhook URL</Field.Label>
|
|
412
|
+
<TextInput.Group>
|
|
413
|
+
<TextInput.Control defaultValue="https://api.exa" type="url" />
|
|
414
|
+
</TextInput.Group>
|
|
415
|
+
<Field.Description>Starts with https://.</Field.Description>
|
|
416
|
+
</Field.Root>
|
|
417
|
+
)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
namespace styles {
|
|
421
|
+
export const field = style({ width: '100% !custom' })
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
**Don't:** Flag a format error before the value is complete.
|
|
426
|
+
|
|
427
|
+
```tsx
|
|
428
|
+
/**
|
|
429
|
+
* Don't example for "Validate When the Value Is Complete" on the Field page.
|
|
430
|
+
* Don't flag a format error before the value is complete.
|
|
431
|
+
* @module
|
|
432
|
+
*/
|
|
433
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
434
|
+
|
|
435
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
436
|
+
export function Demo() {
|
|
437
|
+
return (
|
|
438
|
+
<Field.Root invalid {...styles.field()}>
|
|
439
|
+
<Field.Label>Webhook URL</Field.Label>
|
|
440
|
+
<TextInput.Group>
|
|
441
|
+
<TextInput.Control defaultValue="https://api.exa" type="url" />
|
|
442
|
+
</TextInput.Group>
|
|
443
|
+
<Field.Error match>Enter a URL that starts with https://.</Field.Error>
|
|
444
|
+
</Field.Root>
|
|
445
|
+
)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
namespace styles {
|
|
449
|
+
export const field = style({ width: '100% !custom' })
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Reserve Success for Verified Values
|
|
454
|
+
|
|
455
|
+
Set `success` only after the app checks the value, such as an address that resolves to a contact. It sets no ARIA state, so state the result in the description too.
|
|
456
|
+
|
|
457
|
+
**Do:** Mark only the checked value, and state the result in the description.
|
|
458
|
+
|
|
459
|
+
```tsx
|
|
460
|
+
/**
|
|
461
|
+
* Do example for "Reserve Success for Verified Values" on the Field page.
|
|
462
|
+
* Mark only the checked value, and state the result in the description.
|
|
463
|
+
* @module
|
|
464
|
+
*/
|
|
465
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
466
|
+
|
|
467
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
468
|
+
export function Demo() {
|
|
469
|
+
return (
|
|
470
|
+
<div {...styles.form()}>
|
|
471
|
+
<Field.Root success>
|
|
472
|
+
<Field.Label>Recipient address</Field.Label>
|
|
473
|
+
<TextInput.Group>
|
|
474
|
+
<TextInput.Control defaultValue="0x8f3a…12c4" />
|
|
475
|
+
</TextInput.Group>
|
|
476
|
+
<Field.Description>Matches your contact Alice Chen.</Field.Description>
|
|
477
|
+
</Field.Root>
|
|
478
|
+
<Field.Root>
|
|
479
|
+
<Field.Label>Memo</Field.Label>
|
|
480
|
+
<TextInput.Group>
|
|
481
|
+
<TextInput.Control defaultValue="Rent for May" />
|
|
482
|
+
</TextInput.Group>
|
|
483
|
+
</Field.Root>
|
|
484
|
+
</div>
|
|
485
|
+
)
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
namespace styles {
|
|
489
|
+
export const form = style({ display: 'grid', gap: '16', width: '100% !custom' })
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Don't:** Mark every filled field successful.
|
|
494
|
+
|
|
495
|
+
```tsx
|
|
496
|
+
/**
|
|
497
|
+
* Don't example for "Reserve Success for Verified Values" on the Field page.
|
|
498
|
+
* Don't turn every filled field green.
|
|
499
|
+
* @module
|
|
500
|
+
*/
|
|
501
|
+
import { Field, style, TextInput } from '@tempoxyz/ds'
|
|
502
|
+
|
|
503
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
504
|
+
export function Demo() {
|
|
505
|
+
return (
|
|
506
|
+
<div {...styles.form()}>
|
|
507
|
+
<Field.Root success>
|
|
508
|
+
<Field.Label>Recipient address</Field.Label>
|
|
509
|
+
<TextInput.Group>
|
|
510
|
+
<TextInput.Control defaultValue="0x8f3a…12c4" />
|
|
511
|
+
</TextInput.Group>
|
|
512
|
+
</Field.Root>
|
|
513
|
+
<Field.Root success>
|
|
514
|
+
<Field.Label>Memo</Field.Label>
|
|
515
|
+
<TextInput.Group>
|
|
516
|
+
<TextInput.Control defaultValue="Rent for May" />
|
|
517
|
+
</TextInput.Group>
|
|
518
|
+
</Field.Root>
|
|
519
|
+
</div>
|
|
520
|
+
)
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
namespace styles {
|
|
524
|
+
export const form = style({ display: 'grid', gap: '16', width: '100% !custom' })
|
|
525
|
+
}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## Accessibility
|
|
529
|
+
|
|
530
|
+
A field connects a control to its label, description, and error. See [Accessibility](/docs/foundations/accessibility) for the baseline.
|
|
531
|
+
|
|
532
|
+
### Semantics
|
|
533
|
+
|
|
534
|
+
* **Field.Label (label):** Names the control. A click focuses or toggles it.
|
|
535
|
+
* **Field.Description (aria-describedby):** Read after the control's name.
|
|
536
|
+
* **Field.Error (aria-describedby):** Once shown, read after the description.
|
|
537
|
+
* **Invalid State (aria-invalid):** Set on failed validation or `invalid`.
|
|
538
|
+
* **Disabled (disabled):** Disables the control and dims the label and description.
|
|
539
|
+
* **Field.Item:** Labels one checkbox or radio inside a group.
|
|
540
|
+
|
|
541
|
+
### Your Responsibilities
|
|
542
|
+
|
|
543
|
+
* **Label Every Control (Field.Label):** A placeholder disappears once the reader types, so it can't replace a label.
|
|
544
|
+
* **Explain the Fix:** State the fix in the error, not only the problem, such as "Enter an email address."
|
|
545
|
+
* **Focus the First Error:** The error is not a live region. If a submit fails, focus the first invalid field.
|
|
546
|
+
* **Confirm Success in Text (success):** The `success` check sets no ARIA state and isn't announced. Confirm a verified value in text.
|
|
547
|
+
* **State Requirements:** State requirements and formats in text, such as "(required)" in the label, not only with a symbol.
|
|
548
|
+
* **Label a Date Picker Trigger (aria-labelledby):** `Field.Label` doesn't name a [DatePicker](/docs/components/date-picker) trigger. Point `aria-labelledby` at a visible label.
|
|
549
|
+
|
|
550
|
+
## Related
|
|
551
|
+
|
|
552
|
+
[TextInput](/docs/components/text-input)
|
|
553
|
+
|
|
554
|
+
Use for single-line text.
|
|
555
|
+
|
|
556
|
+
[Fieldset](/docs/components/fieldset)
|
|
557
|
+
|
|
558
|
+
Use for grouping fields under a legend.
|
|
559
|
+
|
|
560
|
+
[Textarea](/docs/components/textarea)
|
|
561
|
+
|
|
562
|
+
Use for multi-line text.
|
|
563
|
+
|
|
564
|
+
[Forms](/docs/patterns/forms)
|
|
565
|
+
|
|
566
|
+
Covers laying out and submitting forms.
|
|
567
|
+
|
|
568
|
+
[Errors and Validation](/docs/patterns/errors-and-validation)
|
|
569
|
+
|
|
570
|
+
Covers when and how to show errors.
|