ionbase-ui 0.16.0 → 0.17.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/README.md +34 -7
- package/dist/meta/Alert.json +248 -0
- package/dist/meta/Avatar.json +97 -0
- package/dist/meta/AvatarGroup.json +82 -0
- package/dist/meta/Badge.json +83 -0
- package/dist/meta/Button.json +518 -0
- package/dist/meta/Checkbox.json +113 -0
- package/dist/meta/Divider.json +30 -0
- package/dist/meta/FullCard.json +97 -0
- package/dist/meta/Header.json +91 -0
- package/dist/meta/Icon.json +35 -0
- package/dist/meta/Input.json +558 -0
- package/dist/meta/Link.json +239 -0
- package/dist/meta/Logo.json +46 -0
- package/dist/meta/LogoMark.json +41 -0
- package/dist/meta/Menu.json +50 -0
- package/dist/meta/MenuItem.json +75 -0
- package/dist/meta/Modal.json +241 -0
- package/dist/meta/NavItem.json +76 -0
- package/dist/meta/PhoneInput.json +472 -0
- package/dist/meta/Popover.json +124 -0
- package/dist/meta/Radio.json +104 -0
- package/dist/meta/RadioGroup.json +126 -0
- package/dist/meta/ScrollProgress.json +63 -0
- package/dist/meta/Select.json +195 -0
- package/dist/meta/TabItem.json +15 -0
- package/dist/meta/Table.json +135 -0
- package/dist/meta/TableBody.json +43 -0
- package/dist/meta/TableCell.json +105 -0
- package/dist/meta/TableHead.json +43 -0
- package/dist/meta/TableRow.json +56 -0
- package/dist/meta/Tabs.json +186 -0
- package/dist/meta/Toast.json +105 -0
- package/dist/meta/ToastProvider.json +75 -0
- package/dist/meta/Toggle.json +102 -0
- package/dist/meta/Tooltip.json +78 -0
- package/dist/meta/components.json +4757 -0
- package/dist/meta/index.json +479 -0
- package/dist/styles/tokens/base.css +25 -25
- package/dist/styles/tokens/theme-dark.css +11 -11
- package/dist/tokens/index.d.ts +8 -8
- package/dist/tokens/index.js +8 -8
- package/package.json +12 -6
|
@@ -0,0 +1,4757 @@
|
|
|
1
|
+
{
|
|
2
|
+
"package": "ionbase-ui",
|
|
3
|
+
"version": "0.17.0",
|
|
4
|
+
"generated": "by scripts/build-meta.mjs — do not edit; intent lives in meta/*.json",
|
|
5
|
+
"hooks": [
|
|
6
|
+
"useToast"
|
|
7
|
+
],
|
|
8
|
+
"components": {
|
|
9
|
+
"Alert": {
|
|
10
|
+
"name": "Alert",
|
|
11
|
+
"source": "src/components/Alert.tsx",
|
|
12
|
+
"propsType": "AlertProps",
|
|
13
|
+
"description": "Alert — Figma `Alert` (812:1902).\n\n`Intent` x `Emphasis` x `Layout`, with the parts as props rather than\nvariants. Intents match `Badge` exactly, so a status mapped to one can be\npassed to the other.\n\nROLE IS CHOSEN BY INTENT, NOT PASSED IN. `error` and `warning` render\n`role=\"alert\"`, which interrupts a screen reader; the rest render\n`role=\"status\"`, which waits for a pause. Getting this backwards is the\ncommon failure — a page of `role=\"alert\"` status messages talks over the\nuser, and an error announced as a status is missed.\n\nThe icon is decorative: it repeats what the intent's colour and copy already\nsay, so it is `aria-hidden` and the live region carries the text alone.",
|
|
14
|
+
"import": "import { Alert } from 'ionbase-ui';",
|
|
15
|
+
"status": "stable",
|
|
16
|
+
"since": "0.13.1",
|
|
17
|
+
"summary": "A persistent, in-page status message. Intent picks the ARIA role for you.",
|
|
18
|
+
"useWhen": [
|
|
19
|
+
"the message belongs to the page and should stay until the condition clears",
|
|
20
|
+
"form-level validation summaries, permission notices, degraded-state banners"
|
|
21
|
+
],
|
|
22
|
+
"useInstead": [
|
|
23
|
+
{
|
|
24
|
+
"when": "the message is transient and self-dismissing",
|
|
25
|
+
"use": "Toast",
|
|
26
|
+
"why": "an Alert stays in the layout; a Toast does not"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"when": "it labels a value inline rather than telling the user something",
|
|
30
|
+
"use": "Badge",
|
|
31
|
+
"why": "Badge shares Alert's intent vocabulary exactly, so a status mapped to one passes to the other"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"variants": {
|
|
35
|
+
"intent": {
|
|
36
|
+
"error": {
|
|
37
|
+
"use": "something failed and the user must act",
|
|
38
|
+
"aria": "role=alert — interrupts the screen reader"
|
|
39
|
+
},
|
|
40
|
+
"warning": {
|
|
41
|
+
"use": "something may fail or has degraded",
|
|
42
|
+
"aria": "role=alert — interrupts the screen reader"
|
|
43
|
+
},
|
|
44
|
+
"success": {
|
|
45
|
+
"use": "an operation completed",
|
|
46
|
+
"aria": "role=status"
|
|
47
|
+
},
|
|
48
|
+
"information": {
|
|
49
|
+
"use": "neutral context the user did not ask for",
|
|
50
|
+
"aria": "role=status"
|
|
51
|
+
},
|
|
52
|
+
"primary": {
|
|
53
|
+
"use": "product announcements and promotions",
|
|
54
|
+
"aria": "role=status"
|
|
55
|
+
},
|
|
56
|
+
"neutral": {
|
|
57
|
+
"use": "low-emphasis context",
|
|
58
|
+
"aria": "role=status"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"emphasis": {
|
|
62
|
+
"subtle": {
|
|
63
|
+
"use": "the default — tinted surface, readable in long pages"
|
|
64
|
+
},
|
|
65
|
+
"solid": {
|
|
66
|
+
"use": "reserve for a single high-stakes banner; it dominates the layout"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"layout": {
|
|
70
|
+
"inline": {
|
|
71
|
+
"use": "inside a form or card, in the flow of content"
|
|
72
|
+
},
|
|
73
|
+
"banner": {
|
|
74
|
+
"use": "full-bleed at the top of a page or region"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"a11y": {
|
|
79
|
+
"guarantees": [
|
|
80
|
+
"the role follows the intent — error and warning are role=alert, everything else role=status",
|
|
81
|
+
"the icon is aria-hidden, so the live region announces the text once and not the glyph"
|
|
82
|
+
],
|
|
83
|
+
"requires": [
|
|
84
|
+
"`dismissLabel` when `onDismiss` is set and the surrounding copy does not name the action"
|
|
85
|
+
],
|
|
86
|
+
"notes": [
|
|
87
|
+
"role=alert interrupts whatever the screen reader is saying; role=status waits for a pause. This is why the role is not a prop."
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
"antiPatterns": [
|
|
91
|
+
{
|
|
92
|
+
"dont": "using intent=\"error\" for a message that is merely informational",
|
|
93
|
+
"why": "error renders role=alert, which interrupts the screen reader. A page of interrupting status messages talks over the user."
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"dont": "using intent=\"information\" for a genuine failure",
|
|
97
|
+
"why": "role=status waits for a pause, so a real error can be missed entirely"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"dont": "rendering an Alert conditionally for a transient confirmation",
|
|
101
|
+
"do": "useToast",
|
|
102
|
+
"why": "an Alert that appears and disappears shifts the layout under the user"
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"stylesheet": "src/styles/alert.css",
|
|
106
|
+
"tokens": [
|
|
107
|
+
"--border-default",
|
|
108
|
+
"--border-error-strong",
|
|
109
|
+
"--border-error-subtle",
|
|
110
|
+
"--border-information-strong",
|
|
111
|
+
"--border-information-subtle",
|
|
112
|
+
"--border-inverse",
|
|
113
|
+
"--border-primary-strong",
|
|
114
|
+
"--border-primary-subtle",
|
|
115
|
+
"--border-success-strong",
|
|
116
|
+
"--border-success-subtle",
|
|
117
|
+
"--border-warning-strong",
|
|
118
|
+
"--border-warning-subtle",
|
|
119
|
+
"--border-width-default",
|
|
120
|
+
"--border-width-thick",
|
|
121
|
+
"--font-family-sans",
|
|
122
|
+
"--font-weight-medium",
|
|
123
|
+
"--font-weight-regular",
|
|
124
|
+
"--icon-error",
|
|
125
|
+
"--icon-information",
|
|
126
|
+
"--icon-on-color",
|
|
127
|
+
"--icon-primary",
|
|
128
|
+
"--icon-secondary",
|
|
129
|
+
"--icon-size-md",
|
|
130
|
+
"--icon-success",
|
|
131
|
+
"--icon-warning",
|
|
132
|
+
"--ion-alert-border",
|
|
133
|
+
"--ion-alert-icon",
|
|
134
|
+
"--ion-alert-surface",
|
|
135
|
+
"--ion-alert-text",
|
|
136
|
+
"--ion-duration-base",
|
|
137
|
+
"--ion-ease-out",
|
|
138
|
+
"--radius-md",
|
|
139
|
+
"--radius-sm",
|
|
140
|
+
"--ring-focus",
|
|
141
|
+
"--spacing-12",
|
|
142
|
+
"--spacing-16",
|
|
143
|
+
"--spacing-32",
|
|
144
|
+
"--spacing-8",
|
|
145
|
+
"--surface-error",
|
|
146
|
+
"--surface-error-subtle",
|
|
147
|
+
"--surface-hover",
|
|
148
|
+
"--surface-information",
|
|
149
|
+
"--surface-information-subtle",
|
|
150
|
+
"--surface-inverse",
|
|
151
|
+
"--surface-muted",
|
|
152
|
+
"--surface-primary",
|
|
153
|
+
"--surface-primary-subtle",
|
|
154
|
+
"--surface-success",
|
|
155
|
+
"--surface-success-subtle",
|
|
156
|
+
"--surface-warning",
|
|
157
|
+
"--surface-warning-subtle",
|
|
158
|
+
"--text-error",
|
|
159
|
+
"--text-information",
|
|
160
|
+
"--text-link",
|
|
161
|
+
"--text-on-color",
|
|
162
|
+
"--text-secondary",
|
|
163
|
+
"--text-success",
|
|
164
|
+
"--text-warning",
|
|
165
|
+
"--type-body",
|
|
166
|
+
"--type-body-line-height"
|
|
167
|
+
],
|
|
168
|
+
"props": {
|
|
169
|
+
"intent": {
|
|
170
|
+
"type": "AlertIntent | undefined",
|
|
171
|
+
"required": false,
|
|
172
|
+
"origin": "own",
|
|
173
|
+
"description": "Matches the Figma `Intent` variant. Same vocabulary as `Badge`.",
|
|
174
|
+
"values": [
|
|
175
|
+
"neutral",
|
|
176
|
+
"primary",
|
|
177
|
+
"success",
|
|
178
|
+
"warning",
|
|
179
|
+
"error",
|
|
180
|
+
"information"
|
|
181
|
+
],
|
|
182
|
+
"default": "information"
|
|
183
|
+
},
|
|
184
|
+
"emphasis": {
|
|
185
|
+
"type": "AlertEmphasis | undefined",
|
|
186
|
+
"required": false,
|
|
187
|
+
"origin": "own",
|
|
188
|
+
"description": "Matches the Figma `Emphasis` variant.",
|
|
189
|
+
"values": [
|
|
190
|
+
"subtle",
|
|
191
|
+
"solid"
|
|
192
|
+
],
|
|
193
|
+
"default": "subtle"
|
|
194
|
+
},
|
|
195
|
+
"layout": {
|
|
196
|
+
"type": "AlertLayout | undefined",
|
|
197
|
+
"required": false,
|
|
198
|
+
"origin": "own",
|
|
199
|
+
"description": "Matches the Figma `Layout` variant.",
|
|
200
|
+
"values": [
|
|
201
|
+
"inline",
|
|
202
|
+
"banner"
|
|
203
|
+
],
|
|
204
|
+
"default": "inline"
|
|
205
|
+
},
|
|
206
|
+
"title": {
|
|
207
|
+
"type": "React.ReactNode",
|
|
208
|
+
"required": false,
|
|
209
|
+
"origin": "own",
|
|
210
|
+
"description": "Optional heading above the message."
|
|
211
|
+
},
|
|
212
|
+
"hideIcon": {
|
|
213
|
+
"type": "boolean | undefined",
|
|
214
|
+
"required": false,
|
|
215
|
+
"origin": "own",
|
|
216
|
+
"description": "Hide the leading icon. Shown by default."
|
|
217
|
+
},
|
|
218
|
+
"icon": {
|
|
219
|
+
"type": "React.ReactNode",
|
|
220
|
+
"required": false,
|
|
221
|
+
"origin": "own",
|
|
222
|
+
"description": "Replace the intent's glyph."
|
|
223
|
+
},
|
|
224
|
+
"actions": {
|
|
225
|
+
"type": "React.ReactNode",
|
|
226
|
+
"required": false,
|
|
227
|
+
"origin": "own",
|
|
228
|
+
"description": "Action buttons, rendered under the message."
|
|
229
|
+
},
|
|
230
|
+
"onDismiss": {
|
|
231
|
+
"type": "(() => void) | undefined",
|
|
232
|
+
"required": false,
|
|
233
|
+
"origin": "own",
|
|
234
|
+
"description": "Called when the dismiss button is pressed. Omit for no dismiss button."
|
|
235
|
+
},
|
|
236
|
+
"dismissLabel": {
|
|
237
|
+
"type": "string | undefined",
|
|
238
|
+
"required": false,
|
|
239
|
+
"origin": "own",
|
|
240
|
+
"description": "Accessible name for the dismiss button.",
|
|
241
|
+
"default": "Dismiss"
|
|
242
|
+
},
|
|
243
|
+
"children": {
|
|
244
|
+
"type": "React.ReactNode",
|
|
245
|
+
"required": false,
|
|
246
|
+
"origin": "own",
|
|
247
|
+
"description": "The message."
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"propCounts": {
|
|
251
|
+
"own": 10,
|
|
252
|
+
"aria": 0,
|
|
253
|
+
"dom": 276,
|
|
254
|
+
"other": 0
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"Avatar": {
|
|
258
|
+
"name": "Avatar",
|
|
259
|
+
"source": "src/components/Avatar.tsx",
|
|
260
|
+
"propsType": "AvatarProps",
|
|
261
|
+
"description": "Avatar picks its content the way Figma's `Type` variant does, but by\nprecedence rather than by a prop: image, then initials, then icon. A caller\npassing `src` and `initials` gets the image with the initials as its alt\nfallback, which is what you want when the image 404s.\n\nA failed `src` falls through to initials (then icon) rather than leaving the\nbrowser's broken-image glyph — that is why initials exist alongside `src`.\n\nIt is a `<span>`, not a `<div>`, so it can sit inline beside text without the\ncaller fighting a block element.",
|
|
262
|
+
"import": "import { Avatar } from 'ionbase-ui';",
|
|
263
|
+
"stylesheet": "src/styles/avatar.css",
|
|
264
|
+
"tokens": [
|
|
265
|
+
"--border-strong",
|
|
266
|
+
"--border-width-default",
|
|
267
|
+
"--font-family-sans",
|
|
268
|
+
"--font-weight-medium",
|
|
269
|
+
"--icon-size-2xs",
|
|
270
|
+
"--icon-size-lg",
|
|
271
|
+
"--icon-size-md",
|
|
272
|
+
"--icon-size-sm",
|
|
273
|
+
"--icon-tertiary",
|
|
274
|
+
"--ion-avatar-font-size",
|
|
275
|
+
"--ion-avatar-group-overlap",
|
|
276
|
+
"--ion-avatar-icon",
|
|
277
|
+
"--ion-avatar-line-height",
|
|
278
|
+
"--ion-avatar-radius",
|
|
279
|
+
"--ion-avatar-size",
|
|
280
|
+
"--radius-full",
|
|
281
|
+
"--radius-md",
|
|
282
|
+
"--radius-sm",
|
|
283
|
+
"--radius-xs",
|
|
284
|
+
"--spacing-24",
|
|
285
|
+
"--spacing-32",
|
|
286
|
+
"--spacing-40",
|
|
287
|
+
"--spacing-48",
|
|
288
|
+
"--surface-muted",
|
|
289
|
+
"--text-tertiary",
|
|
290
|
+
"--type-body",
|
|
291
|
+
"--type-body-line-height",
|
|
292
|
+
"--type-body-sm",
|
|
293
|
+
"--type-body-sm-line-height",
|
|
294
|
+
"--type-caption",
|
|
295
|
+
"--type-caption-line-height",
|
|
296
|
+
"--type-h5",
|
|
297
|
+
"--type-h5-line-height"
|
|
298
|
+
],
|
|
299
|
+
"props": {
|
|
300
|
+
"size": {
|
|
301
|
+
"type": "AvatarSize | undefined",
|
|
302
|
+
"required": false,
|
|
303
|
+
"origin": "own",
|
|
304
|
+
"description": "Matches the Figma `Size` variant: Mini 24, Small 32, Medium 40, Large 48.",
|
|
305
|
+
"values": [
|
|
306
|
+
"mini",
|
|
307
|
+
"sm",
|
|
308
|
+
"md",
|
|
309
|
+
"lg"
|
|
310
|
+
]
|
|
311
|
+
},
|
|
312
|
+
"shape": {
|
|
313
|
+
"type": "AvatarShape | undefined",
|
|
314
|
+
"required": false,
|
|
315
|
+
"origin": "own",
|
|
316
|
+
"description": "Matches the Figma `Shape` variant.",
|
|
317
|
+
"values": [
|
|
318
|
+
"circle",
|
|
319
|
+
"square"
|
|
320
|
+
]
|
|
321
|
+
},
|
|
322
|
+
"src": {
|
|
323
|
+
"type": "string | undefined",
|
|
324
|
+
"required": false,
|
|
325
|
+
"origin": "own",
|
|
326
|
+
"description": "Image source. Figma's `Type=Image`."
|
|
327
|
+
},
|
|
328
|
+
"alt": {
|
|
329
|
+
"type": "string | undefined",
|
|
330
|
+
"required": false,
|
|
331
|
+
"origin": "own",
|
|
332
|
+
"description": "Describes the person, not the picture. Falls back to `initials` so the\navatar is never announced as an unlabelled image."
|
|
333
|
+
},
|
|
334
|
+
"initials": {
|
|
335
|
+
"type": "string | undefined",
|
|
336
|
+
"required": false,
|
|
337
|
+
"origin": "own",
|
|
338
|
+
"description": "Figma's `Type=Character`. Rendered when there is no `src`, or when `src`\nfails to load."
|
|
339
|
+
},
|
|
340
|
+
"icon": {
|
|
341
|
+
"type": "React.ReactNode",
|
|
342
|
+
"required": false,
|
|
343
|
+
"origin": "own",
|
|
344
|
+
"description": "Figma's `Type=Icon`. Rendered when there is neither `src` nor `initials`."
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
"propCounts": {
|
|
348
|
+
"own": 6,
|
|
349
|
+
"aria": 0,
|
|
350
|
+
"dom": 278,
|
|
351
|
+
"other": 0
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
"AvatarGroup": {
|
|
355
|
+
"name": "AvatarGroup",
|
|
356
|
+
"source": "src/components/Avatar.tsx",
|
|
357
|
+
"propsType": "AvatarGroupProps",
|
|
358
|
+
"description": "AvatarGroup overlaps its children by a quarter of the avatar size, matching\nFigma's -6 / -8 / -10 / -12 gaps at Mini / Small / Medium / Large.\n\nGroup defaults fill in `size` / `shape` only when a child Avatar has not set\nthem itself — an explicit child prop wins. Non-Avatar children are left\nalone so `size`/`shape` are never pushed onto arbitrary DOM nodes.\n\nChildren render in source order because that is Figma's stacking: each avatar\npaints over the one before it, so the `+N` overflow ends up on top. Later\nsiblings paint later, so this needs no z-index.",
|
|
359
|
+
"import": "import { AvatarGroup } from 'ionbase-ui';",
|
|
360
|
+
"stylesheet": "src/styles/avatar.css",
|
|
361
|
+
"tokens": [
|
|
362
|
+
"--border-strong",
|
|
363
|
+
"--border-width-default",
|
|
364
|
+
"--font-family-sans",
|
|
365
|
+
"--font-weight-medium",
|
|
366
|
+
"--icon-size-2xs",
|
|
367
|
+
"--icon-size-lg",
|
|
368
|
+
"--icon-size-md",
|
|
369
|
+
"--icon-size-sm",
|
|
370
|
+
"--icon-tertiary",
|
|
371
|
+
"--ion-avatar-font-size",
|
|
372
|
+
"--ion-avatar-group-overlap",
|
|
373
|
+
"--ion-avatar-icon",
|
|
374
|
+
"--ion-avatar-line-height",
|
|
375
|
+
"--ion-avatar-radius",
|
|
376
|
+
"--ion-avatar-size",
|
|
377
|
+
"--radius-full",
|
|
378
|
+
"--radius-md",
|
|
379
|
+
"--radius-sm",
|
|
380
|
+
"--radius-xs",
|
|
381
|
+
"--spacing-24",
|
|
382
|
+
"--spacing-32",
|
|
383
|
+
"--spacing-40",
|
|
384
|
+
"--spacing-48",
|
|
385
|
+
"--surface-muted",
|
|
386
|
+
"--text-tertiary",
|
|
387
|
+
"--type-body",
|
|
388
|
+
"--type-body-line-height",
|
|
389
|
+
"--type-body-sm",
|
|
390
|
+
"--type-body-sm-line-height",
|
|
391
|
+
"--type-caption",
|
|
392
|
+
"--type-caption-line-height",
|
|
393
|
+
"--type-h5",
|
|
394
|
+
"--type-h5-line-height"
|
|
395
|
+
],
|
|
396
|
+
"props": {
|
|
397
|
+
"size": {
|
|
398
|
+
"type": "AvatarSize | undefined",
|
|
399
|
+
"required": false,
|
|
400
|
+
"origin": "own",
|
|
401
|
+
"values": [
|
|
402
|
+
"mini",
|
|
403
|
+
"sm",
|
|
404
|
+
"md",
|
|
405
|
+
"lg"
|
|
406
|
+
]
|
|
407
|
+
},
|
|
408
|
+
"max": {
|
|
409
|
+
"type": "number | undefined",
|
|
410
|
+
"required": false,
|
|
411
|
+
"origin": "own",
|
|
412
|
+
"description": "Cap on avatars shown; the remainder becomes a `+N` overflow avatar."
|
|
413
|
+
},
|
|
414
|
+
"shape": {
|
|
415
|
+
"type": "AvatarShape | undefined",
|
|
416
|
+
"required": false,
|
|
417
|
+
"origin": "own",
|
|
418
|
+
"values": [
|
|
419
|
+
"circle",
|
|
420
|
+
"square"
|
|
421
|
+
]
|
|
422
|
+
},
|
|
423
|
+
"children": {
|
|
424
|
+
"type": "React.ReactNode",
|
|
425
|
+
"required": false,
|
|
426
|
+
"origin": "own"
|
|
427
|
+
}
|
|
428
|
+
},
|
|
429
|
+
"propCounts": {
|
|
430
|
+
"own": 4,
|
|
431
|
+
"aria": 0,
|
|
432
|
+
"dom": 277,
|
|
433
|
+
"other": 0
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
"Badge": {
|
|
437
|
+
"name": "Badge",
|
|
438
|
+
"source": "src/components/Badge.tsx",
|
|
439
|
+
"propsType": "BadgeProps",
|
|
440
|
+
"description": "Badge is presentational — no role, no interaction. React Aria has nothing to\noffer here, so this is a plain span rather than a hook wrapper for its own\nsake.\n\nIt carries no `status` or `alert` role on purpose: a badge is a label on\nsomething else, and announcing it as a live region would interrupt screen\nreader users on every render. Wrap it yourself if the value genuinely changes\nand matters.",
|
|
441
|
+
"import": "import { Badge } from 'ionbase-ui';",
|
|
442
|
+
"stylesheet": "src/styles/badge.css",
|
|
443
|
+
"tokens": [
|
|
444
|
+
"--border-default",
|
|
445
|
+
"--border-error-subtle",
|
|
446
|
+
"--border-information-subtle",
|
|
447
|
+
"--border-primary-subtle",
|
|
448
|
+
"--border-success-subtle",
|
|
449
|
+
"--border-warning-subtle",
|
|
450
|
+
"--border-width-default",
|
|
451
|
+
"--font-family-sans",
|
|
452
|
+
"--font-weight-medium",
|
|
453
|
+
"--icon-error",
|
|
454
|
+
"--icon-information",
|
|
455
|
+
"--icon-primary",
|
|
456
|
+
"--icon-secondary",
|
|
457
|
+
"--icon-success",
|
|
458
|
+
"--icon-warning",
|
|
459
|
+
"--radius-full",
|
|
460
|
+
"--spacing-2",
|
|
461
|
+
"--spacing-4",
|
|
462
|
+
"--spacing-6",
|
|
463
|
+
"--spacing-8",
|
|
464
|
+
"--surface-error-subtle",
|
|
465
|
+
"--surface-information-subtle",
|
|
466
|
+
"--surface-muted",
|
|
467
|
+
"--surface-primary-subtle",
|
|
468
|
+
"--surface-success-subtle",
|
|
469
|
+
"--surface-warning-subtle",
|
|
470
|
+
"--text-error",
|
|
471
|
+
"--text-information",
|
|
472
|
+
"--text-link",
|
|
473
|
+
"--text-secondary",
|
|
474
|
+
"--text-success",
|
|
475
|
+
"--text-warning",
|
|
476
|
+
"--type-caption",
|
|
477
|
+
"--type-caption-line-height"
|
|
478
|
+
],
|
|
479
|
+
"props": {
|
|
480
|
+
"intent": {
|
|
481
|
+
"type": "BadgeIntent | undefined",
|
|
482
|
+
"required": false,
|
|
483
|
+
"origin": "own",
|
|
484
|
+
"description": "Matches the Figma `Intent` variant.",
|
|
485
|
+
"values": [
|
|
486
|
+
"neutral",
|
|
487
|
+
"primary",
|
|
488
|
+
"success",
|
|
489
|
+
"warning",
|
|
490
|
+
"error",
|
|
491
|
+
"information"
|
|
492
|
+
]
|
|
493
|
+
},
|
|
494
|
+
"dot": {
|
|
495
|
+
"type": "boolean | undefined",
|
|
496
|
+
"required": false,
|
|
497
|
+
"origin": "own",
|
|
498
|
+
"description": "Show the leading dot marker. Figma's `Show Dot` boolean.\nThe dot inherits the intent's foreground colour, so it needs no prop."
|
|
499
|
+
},
|
|
500
|
+
"icon": {
|
|
501
|
+
"type": "React.ReactNode",
|
|
502
|
+
"required": false,
|
|
503
|
+
"origin": "own",
|
|
504
|
+
"description": "Leading icon. Figma's `Show Icon` + `Icon` swap. Mutually exclusive with `dot`."
|
|
505
|
+
},
|
|
506
|
+
"children": {
|
|
507
|
+
"type": "React.ReactNode",
|
|
508
|
+
"required": false,
|
|
509
|
+
"origin": "own"
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
"propCounts": {
|
|
513
|
+
"own": 4,
|
|
514
|
+
"aria": 0,
|
|
515
|
+
"dom": 277,
|
|
516
|
+
"other": 0
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
"Button": {
|
|
520
|
+
"name": "Button",
|
|
521
|
+
"source": "src/components/Button.tsx",
|
|
522
|
+
"propsType": "ButtonProps",
|
|
523
|
+
"import": "import { Button } from 'ionbase-ui';",
|
|
524
|
+
"status": "stable",
|
|
525
|
+
"summary": "Triggers an action in place. Never navigates.",
|
|
526
|
+
"useWhen": [
|
|
527
|
+
"the interaction performs an action — submit, save, delete, open a dialog",
|
|
528
|
+
"the result stays on the current page"
|
|
529
|
+
],
|
|
530
|
+
"useInstead": [
|
|
531
|
+
{
|
|
532
|
+
"when": "it navigates to a URL or changes route",
|
|
533
|
+
"use": "Link",
|
|
534
|
+
"why": "Link renders an <a>. Middle-click, cmd-click, copy-link-address and 'open in new tab' all work on an anchor and none of them work on a button."
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"when": "it toggles a persistent boolean setting",
|
|
538
|
+
"use": "Toggle",
|
|
539
|
+
"why": "a toggle announces its on/off state; a button announces only its name"
|
|
540
|
+
}
|
|
541
|
+
],
|
|
542
|
+
"variants": {
|
|
543
|
+
"variant": {
|
|
544
|
+
"primary-brand": {
|
|
545
|
+
"use": "the single most important action in a view",
|
|
546
|
+
"limit": "one per view or dialog"
|
|
547
|
+
},
|
|
548
|
+
"primary-neutral": {
|
|
549
|
+
"use": "a primary action that should not carry brand colour"
|
|
550
|
+
},
|
|
551
|
+
"primary-soft": {
|
|
552
|
+
"use": "a primary action on a dense or already-colourful surface"
|
|
553
|
+
},
|
|
554
|
+
"secondary": {
|
|
555
|
+
"use": "supporting actions shown alongside a primary one"
|
|
556
|
+
},
|
|
557
|
+
"tertiary": {
|
|
558
|
+
"use": "low-emphasis actions — Cancel, Back, inline row actions"
|
|
559
|
+
},
|
|
560
|
+
"destructive": {
|
|
561
|
+
"use": "irreversible actions",
|
|
562
|
+
"requires": "a Modal confirmation before the action runs"
|
|
563
|
+
},
|
|
564
|
+
"success": {
|
|
565
|
+
"use": "confirms the end of a flow. Rarely the right answer — prefer primary-brand."
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
"size": {
|
|
569
|
+
"sm": {
|
|
570
|
+
"use": "table rows, toolbars, dense layouts"
|
|
571
|
+
},
|
|
572
|
+
"md": {
|
|
573
|
+
"use": "the default; forms and page-level actions"
|
|
574
|
+
},
|
|
575
|
+
"lg": {
|
|
576
|
+
"use": "prominent standalone actions"
|
|
577
|
+
},
|
|
578
|
+
"xl": {
|
|
579
|
+
"use": "marketing and empty-state calls to action"
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
},
|
|
583
|
+
"slots": {
|
|
584
|
+
"startIcon": {
|
|
585
|
+
"accepts": "Icon",
|
|
586
|
+
"note": "omit Icon's `label` — the Button's own text already names it, and a labelled icon is announced twice"
|
|
587
|
+
},
|
|
588
|
+
"endIcon": {
|
|
589
|
+
"accepts": "Icon",
|
|
590
|
+
"note": "same as startIcon"
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
"a11y": {
|
|
594
|
+
"role": "button",
|
|
595
|
+
"guarantees": [
|
|
596
|
+
"the focus ring appears for keyboard focus and not for a mouse click",
|
|
597
|
+
"hover does not latch on touch devices"
|
|
598
|
+
],
|
|
599
|
+
"requires": [
|
|
600
|
+
"an accessible name — `children`, or `aria-label` when the button is icon-only"
|
|
601
|
+
]
|
|
602
|
+
},
|
|
603
|
+
"antiPatterns": [
|
|
604
|
+
{
|
|
605
|
+
"dont": "<Button onPress={() => router.push('/settings')}>Settings</Button>",
|
|
606
|
+
"do": "<Link href=\"/settings\">Settings</Link>",
|
|
607
|
+
"why": "a button that navigates breaks middle-click, cmd-click and copy-link, and is announced as a button rather than a link"
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
"dont": "two variant=\"primary-brand\" buttons in the same dialog",
|
|
611
|
+
"do": "one primary-brand, the rest secondary or tertiary",
|
|
612
|
+
"why": "two primaries is the same as none — nothing indicates the expected action"
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
"dont": "<Button variant=\"destructive\" onPress={deleteAccount}>",
|
|
616
|
+
"do": "open a Modal first and put the destructive Button in its footer",
|
|
617
|
+
"why": "irreversible actions need a confirmation step"
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"dont": "<Button><Icon as={Trash} /></Button>",
|
|
621
|
+
"do": "<Button aria-label=\"Delete\"><Icon as={Trash} /></Button>",
|
|
622
|
+
"why": "an icon-only button with no aria-label is announced as just 'button'"
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
"dont": "<Button onClick={...}>",
|
|
626
|
+
"do": "<Button onPress={...}>",
|
|
627
|
+
"why": "onPress is React Aria's unified pointer/keyboard/touch handler. onClick works but skips the touch and keyboard normalisation the rest of the system relies on."
|
|
628
|
+
}
|
|
629
|
+
],
|
|
630
|
+
"deprecated": [
|
|
631
|
+
{
|
|
632
|
+
"prop": "disabled",
|
|
633
|
+
"replacement": "isDisabled",
|
|
634
|
+
"note": "still type-checks, so this will not fail loudly"
|
|
635
|
+
}
|
|
636
|
+
],
|
|
637
|
+
"stylesheet": "src/styles/button.css",
|
|
638
|
+
"tokens": [
|
|
639
|
+
"--border-disabled",
|
|
640
|
+
"--border-error-strong",
|
|
641
|
+
"--border-inverse",
|
|
642
|
+
"--border-primary",
|
|
643
|
+
"--border-primary-strong",
|
|
644
|
+
"--border-primary-subtle",
|
|
645
|
+
"--border-strong",
|
|
646
|
+
"--border-stronger",
|
|
647
|
+
"--border-success-strong",
|
|
648
|
+
"--border-width-default",
|
|
649
|
+
"--font-family-sans",
|
|
650
|
+
"--font-weight-medium",
|
|
651
|
+
"--icon-size-lg",
|
|
652
|
+
"--icon-size-md",
|
|
653
|
+
"--icon-size-xs",
|
|
654
|
+
"--ion-button-elevation",
|
|
655
|
+
"--ion-button-font-size",
|
|
656
|
+
"--ion-button-gap",
|
|
657
|
+
"--ion-button-icon-size",
|
|
658
|
+
"--ion-button-inset-flush",
|
|
659
|
+
"--ion-button-inset-lifted",
|
|
660
|
+
"--ion-button-line-height",
|
|
661
|
+
"--ion-button-padding-x",
|
|
662
|
+
"--ion-button-pressed",
|
|
663
|
+
"--ion-button-raised",
|
|
664
|
+
"--ion-button-ring",
|
|
665
|
+
"--ion-button-size",
|
|
666
|
+
"--ion-duration-base",
|
|
667
|
+
"--ion-duration-fast",
|
|
668
|
+
"--ion-ease-out",
|
|
669
|
+
"--ion-shadow-focus-md",
|
|
670
|
+
"--ion-shadow-inset-flush-lg",
|
|
671
|
+
"--ion-shadow-inset-flush-sm",
|
|
672
|
+
"--ion-shadow-inset-flush-xs",
|
|
673
|
+
"--ion-shadow-inset-lifted-lg",
|
|
674
|
+
"--ion-shadow-inset-lifted-sm",
|
|
675
|
+
"--ion-shadow-inset-lifted-xs",
|
|
676
|
+
"--ion-shadow-none",
|
|
677
|
+
"--ion-shadow-raised-lifted-lg",
|
|
678
|
+
"--ion-shadow-raised-lifted-sm",
|
|
679
|
+
"--ion-shadow-raised-lifted-xs",
|
|
680
|
+
"--radius-md",
|
|
681
|
+
"--spacing-12",
|
|
682
|
+
"--spacing-16",
|
|
683
|
+
"--spacing-20",
|
|
684
|
+
"--spacing-24",
|
|
685
|
+
"--spacing-32",
|
|
686
|
+
"--spacing-40",
|
|
687
|
+
"--spacing-48",
|
|
688
|
+
"--spacing-56",
|
|
689
|
+
"--spacing-6",
|
|
690
|
+
"--spacing-8",
|
|
691
|
+
"--surface-default",
|
|
692
|
+
"--surface-disabled",
|
|
693
|
+
"--surface-error",
|
|
694
|
+
"--surface-error-hover",
|
|
695
|
+
"--surface-error-pressed",
|
|
696
|
+
"--surface-inverse",
|
|
697
|
+
"--surface-inverse-subtle",
|
|
698
|
+
"--surface-muted",
|
|
699
|
+
"--surface-page",
|
|
700
|
+
"--surface-primary",
|
|
701
|
+
"--surface-primary-hover",
|
|
702
|
+
"--surface-primary-pressed",
|
|
703
|
+
"--surface-primary-subtle",
|
|
704
|
+
"--surface-primary-subtle-hover",
|
|
705
|
+
"--surface-primary-tint",
|
|
706
|
+
"--surface-success",
|
|
707
|
+
"--surface-success-hover",
|
|
708
|
+
"--surface-success-pressed",
|
|
709
|
+
"--text-disabled",
|
|
710
|
+
"--text-on-color",
|
|
711
|
+
"--text-primary",
|
|
712
|
+
"--text-secondary",
|
|
713
|
+
"--type-body",
|
|
714
|
+
"--type-body-lg",
|
|
715
|
+
"--type-body-lg-line-height",
|
|
716
|
+
"--type-body-line-height",
|
|
717
|
+
"--type-body-md",
|
|
718
|
+
"--type-body-md-line-height",
|
|
719
|
+
"--type-body-sm",
|
|
720
|
+
"--type-body-sm-line-height"
|
|
721
|
+
],
|
|
722
|
+
"props": {
|
|
723
|
+
"variant": {
|
|
724
|
+
"type": "\"success\" | \"primary-brand\" | \"primary-neutral\" | \"primary-soft\" | \"secondary\" | \"tertiary\" | \"destructive\" | undefined",
|
|
725
|
+
"required": false,
|
|
726
|
+
"origin": "own",
|
|
727
|
+
"description": "The visual style variant of the button.",
|
|
728
|
+
"values": [
|
|
729
|
+
"success",
|
|
730
|
+
"primary-brand",
|
|
731
|
+
"primary-neutral",
|
|
732
|
+
"primary-soft",
|
|
733
|
+
"secondary",
|
|
734
|
+
"tertiary",
|
|
735
|
+
"destructive"
|
|
736
|
+
],
|
|
737
|
+
"default": "primary-brand"
|
|
738
|
+
},
|
|
739
|
+
"size": {
|
|
740
|
+
"type": "\"sm\" | \"md\" | \"lg\" | \"xl\" | undefined",
|
|
741
|
+
"required": false,
|
|
742
|
+
"origin": "own",
|
|
743
|
+
"description": "The size of the button.",
|
|
744
|
+
"values": [
|
|
745
|
+
"sm",
|
|
746
|
+
"md",
|
|
747
|
+
"lg",
|
|
748
|
+
"xl"
|
|
749
|
+
],
|
|
750
|
+
"default": "md"
|
|
751
|
+
},
|
|
752
|
+
"startIcon": {
|
|
753
|
+
"type": "React.ReactNode",
|
|
754
|
+
"required": false,
|
|
755
|
+
"origin": "own",
|
|
756
|
+
"description": "Optional icon to render before the label."
|
|
757
|
+
},
|
|
758
|
+
"endIcon": {
|
|
759
|
+
"type": "React.ReactNode",
|
|
760
|
+
"required": false,
|
|
761
|
+
"origin": "own",
|
|
762
|
+
"description": "Optional icon to render after the label."
|
|
763
|
+
},
|
|
764
|
+
"className": {
|
|
765
|
+
"type": "string | undefined",
|
|
766
|
+
"required": false,
|
|
767
|
+
"origin": "own",
|
|
768
|
+
"description": "Additional CSS class names."
|
|
769
|
+
},
|
|
770
|
+
"children": {
|
|
771
|
+
"type": "React.ReactNode",
|
|
772
|
+
"required": false,
|
|
773
|
+
"origin": "own",
|
|
774
|
+
"description": "Children element to render inside the button."
|
|
775
|
+
},
|
|
776
|
+
"disabled": {
|
|
777
|
+
"type": "boolean | undefined",
|
|
778
|
+
"required": false,
|
|
779
|
+
"origin": "own",
|
|
780
|
+
"tags": {
|
|
781
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
782
|
+
}
|
|
783
|
+
},
|
|
784
|
+
"isDisabled": {
|
|
785
|
+
"type": "boolean | undefined",
|
|
786
|
+
"required": false,
|
|
787
|
+
"origin": "aria",
|
|
788
|
+
"description": "Whether the button is disabled."
|
|
789
|
+
},
|
|
790
|
+
"onPress": {
|
|
791
|
+
"type": "((e: PressEvent) => void) | undefined",
|
|
792
|
+
"required": false,
|
|
793
|
+
"origin": "aria",
|
|
794
|
+
"description": "Handler that is called when the press is released over the target."
|
|
795
|
+
},
|
|
796
|
+
"onPressStart": {
|
|
797
|
+
"type": "((e: PressEvent) => void) | undefined",
|
|
798
|
+
"required": false,
|
|
799
|
+
"origin": "aria",
|
|
800
|
+
"description": "Handler that is called when a press interaction starts."
|
|
801
|
+
},
|
|
802
|
+
"onPressEnd": {
|
|
803
|
+
"type": "((e: PressEvent) => void) | undefined",
|
|
804
|
+
"required": false,
|
|
805
|
+
"origin": "aria",
|
|
806
|
+
"description": "Handler that is called when a press interaction ends, either\nover the target or when the pointer leaves the target."
|
|
807
|
+
},
|
|
808
|
+
"onPressChange": {
|
|
809
|
+
"type": "((isPressed: boolean) => void) | undefined",
|
|
810
|
+
"required": false,
|
|
811
|
+
"origin": "aria",
|
|
812
|
+
"description": "Handler that is called when the press state changes."
|
|
813
|
+
},
|
|
814
|
+
"onPressUp": {
|
|
815
|
+
"type": "((e: PressEvent) => void) | undefined",
|
|
816
|
+
"required": false,
|
|
817
|
+
"origin": "aria",
|
|
818
|
+
"description": "Handler that is called when a press is released over the target, regardless of\nwhether it started on the target or not."
|
|
819
|
+
},
|
|
820
|
+
"onClick": {
|
|
821
|
+
"type": "((e: MouseEvent<FocusableElement>) => void) | undefined",
|
|
822
|
+
"required": false,
|
|
823
|
+
"origin": "aria",
|
|
824
|
+
"description": "**Not recommended – use `onPress` instead.** `onClick` is an alias for `onPress`\nprovided for compatibility with other libraries. `onPress` provides\nadditional event details for non-mouse interactions."
|
|
825
|
+
},
|
|
826
|
+
"autoFocus": {
|
|
827
|
+
"type": "boolean | undefined",
|
|
828
|
+
"required": false,
|
|
829
|
+
"origin": "aria",
|
|
830
|
+
"description": "Whether the element should receive focus on render."
|
|
831
|
+
},
|
|
832
|
+
"onFocus": {
|
|
833
|
+
"type": "((e: FocusEvent<Element, Element>) => void) | undefined",
|
|
834
|
+
"required": false,
|
|
835
|
+
"origin": "aria",
|
|
836
|
+
"description": "Handler that is called when the element receives focus."
|
|
837
|
+
},
|
|
838
|
+
"onBlur": {
|
|
839
|
+
"type": "((e: FocusEvent<Element, Element>) => void) | undefined",
|
|
840
|
+
"required": false,
|
|
841
|
+
"origin": "aria",
|
|
842
|
+
"description": "Handler that is called when the element loses focus."
|
|
843
|
+
},
|
|
844
|
+
"onFocusChange": {
|
|
845
|
+
"type": "((isFocused: boolean) => void) | undefined",
|
|
846
|
+
"required": false,
|
|
847
|
+
"origin": "aria",
|
|
848
|
+
"description": "Handler that is called when the element's focus status changes."
|
|
849
|
+
},
|
|
850
|
+
"onKeyDown": {
|
|
851
|
+
"type": "((e: KeyboardEvent) => void) | undefined",
|
|
852
|
+
"required": false,
|
|
853
|
+
"origin": "aria",
|
|
854
|
+
"description": "Handler that is called when a key is pressed."
|
|
855
|
+
},
|
|
856
|
+
"onKeyUp": {
|
|
857
|
+
"type": "((e: KeyboardEvent) => void) | undefined",
|
|
858
|
+
"required": false,
|
|
859
|
+
"origin": "aria",
|
|
860
|
+
"description": "Handler that is called when a key is released."
|
|
861
|
+
},
|
|
862
|
+
"href": {
|
|
863
|
+
"type": "string | undefined",
|
|
864
|
+
"required": false,
|
|
865
|
+
"origin": "aria",
|
|
866
|
+
"description": "A URL to link to if elementType=\"a\"."
|
|
867
|
+
},
|
|
868
|
+
"target": {
|
|
869
|
+
"type": "string | undefined",
|
|
870
|
+
"required": false,
|
|
871
|
+
"origin": "aria",
|
|
872
|
+
"description": "The target window for the link."
|
|
873
|
+
},
|
|
874
|
+
"rel": {
|
|
875
|
+
"type": "string | undefined",
|
|
876
|
+
"required": false,
|
|
877
|
+
"origin": "aria",
|
|
878
|
+
"description": "The relationship between the linked resource and the current page. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel)."
|
|
879
|
+
},
|
|
880
|
+
"elementType": {
|
|
881
|
+
"type": "JSXElementConstructor<any> | \"button\" | undefined",
|
|
882
|
+
"required": false,
|
|
883
|
+
"origin": "aria",
|
|
884
|
+
"description": "The HTML element or React element used to render the button, e.g. 'div', 'a', or `RouterLink`.",
|
|
885
|
+
"tags": {
|
|
886
|
+
"default": "'button'"
|
|
887
|
+
}
|
|
888
|
+
},
|
|
889
|
+
"aria-disabled": {
|
|
890
|
+
"type": "boolean | \"true\" | \"false\" | undefined",
|
|
891
|
+
"required": false,
|
|
892
|
+
"origin": "aria",
|
|
893
|
+
"description": "Indicates whether the element is disabled to users of assistive technology."
|
|
894
|
+
},
|
|
895
|
+
"aria-expanded": {
|
|
896
|
+
"type": "boolean | \"true\" | \"false\" | undefined",
|
|
897
|
+
"required": false,
|
|
898
|
+
"origin": "aria",
|
|
899
|
+
"description": "Indicates whether the element, or another grouping element it controls, is currently expanded\nor collapsed."
|
|
900
|
+
},
|
|
901
|
+
"aria-haspopup": {
|
|
902
|
+
"type": "boolean | \"true\" | \"false\" | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\" | undefined",
|
|
903
|
+
"required": false,
|
|
904
|
+
"origin": "aria",
|
|
905
|
+
"description": "Indicates the availability and type of interactive popup element, such as menu or dialog, that\ncan be triggered by an element."
|
|
906
|
+
},
|
|
907
|
+
"aria-controls": {
|
|
908
|
+
"type": "string | undefined",
|
|
909
|
+
"required": false,
|
|
910
|
+
"origin": "aria",
|
|
911
|
+
"description": "Identifies the element (or elements) whose contents or presence are controlled by the current\nelement."
|
|
912
|
+
},
|
|
913
|
+
"aria-pressed": {
|
|
914
|
+
"type": "boolean | \"true\" | \"false\" | \"mixed\" | undefined",
|
|
915
|
+
"required": false,
|
|
916
|
+
"origin": "aria",
|
|
917
|
+
"description": "Indicates the current \"pressed\" state of toggle buttons."
|
|
918
|
+
},
|
|
919
|
+
"aria-current": {
|
|
920
|
+
"type": "boolean | \"true\" | \"false\" | \"page\" | \"step\" | \"location\" | \"date\" | \"time\" | undefined",
|
|
921
|
+
"required": false,
|
|
922
|
+
"origin": "aria",
|
|
923
|
+
"description": "Indicates whether this element represents the current item within a container or set of related\nelements."
|
|
924
|
+
},
|
|
925
|
+
"type": {
|
|
926
|
+
"type": "\"button\" | \"submit\" | \"reset\" | undefined",
|
|
927
|
+
"required": false,
|
|
928
|
+
"origin": "aria",
|
|
929
|
+
"description": "The behavior of the button when used in an HTML form.",
|
|
930
|
+
"values": [
|
|
931
|
+
"button",
|
|
932
|
+
"submit",
|
|
933
|
+
"reset"
|
|
934
|
+
],
|
|
935
|
+
"tags": {
|
|
936
|
+
"default": "'button'"
|
|
937
|
+
}
|
|
938
|
+
},
|
|
939
|
+
"preventFocusOnPress": {
|
|
940
|
+
"type": "boolean | undefined",
|
|
941
|
+
"required": false,
|
|
942
|
+
"origin": "aria",
|
|
943
|
+
"description": "Whether to prevent focus from moving to the button when pressing it.\n\nCaution, this can make the button inaccessible and should only be used when alternative\nkeyboard interaction is provided, such as ComboBox's MenuTrigger or a NumberField's\nincrement/decrement control."
|
|
944
|
+
},
|
|
945
|
+
"form": {
|
|
946
|
+
"type": "string | undefined",
|
|
947
|
+
"required": false,
|
|
948
|
+
"origin": "aria",
|
|
949
|
+
"description": "The `<form>` element to associate the button with.\nThe value of this attribute must be the id of a `<form>` in the same document.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/button#form)."
|
|
950
|
+
},
|
|
951
|
+
"formAction": {
|
|
952
|
+
"type": "string | ((formData: FormData) => void | Promise<void>) | undefined",
|
|
953
|
+
"required": false,
|
|
954
|
+
"origin": "aria",
|
|
955
|
+
"description": "The URL that processes the information submitted by the button.\nOverrides the action attribute of the button's form owner."
|
|
956
|
+
},
|
|
957
|
+
"formEncType": {
|
|
958
|
+
"type": "string | undefined",
|
|
959
|
+
"required": false,
|
|
960
|
+
"origin": "aria",
|
|
961
|
+
"description": "Indicates how to encode the form data that is submitted."
|
|
962
|
+
},
|
|
963
|
+
"formMethod": {
|
|
964
|
+
"type": "string | undefined",
|
|
965
|
+
"required": false,
|
|
966
|
+
"origin": "aria",
|
|
967
|
+
"description": "Indicates the HTTP method used to submit the form."
|
|
968
|
+
},
|
|
969
|
+
"formNoValidate": {
|
|
970
|
+
"type": "boolean | undefined",
|
|
971
|
+
"required": false,
|
|
972
|
+
"origin": "aria",
|
|
973
|
+
"description": "Indicates that the form is not to be validated when it is submitted."
|
|
974
|
+
},
|
|
975
|
+
"formTarget": {
|
|
976
|
+
"type": "string | undefined",
|
|
977
|
+
"required": false,
|
|
978
|
+
"origin": "aria",
|
|
979
|
+
"description": "Overrides the target attribute of the button's form owner."
|
|
980
|
+
},
|
|
981
|
+
"name": {
|
|
982
|
+
"type": "string | undefined",
|
|
983
|
+
"required": false,
|
|
984
|
+
"origin": "aria",
|
|
985
|
+
"description": "Submitted as a pair with the button's value as part of the form data."
|
|
986
|
+
},
|
|
987
|
+
"value": {
|
|
988
|
+
"type": "string | undefined",
|
|
989
|
+
"required": false,
|
|
990
|
+
"origin": "aria",
|
|
991
|
+
"description": "The value associated with the button's name when it's submitted with the form data."
|
|
992
|
+
},
|
|
993
|
+
"excludeFromTabOrder": {
|
|
994
|
+
"type": "boolean | undefined",
|
|
995
|
+
"required": false,
|
|
996
|
+
"origin": "aria",
|
|
997
|
+
"description": "Whether to exclude the element from the sequential tab order. If true,\nthe element will not be focusable via the keyboard by tabbing. This should\nbe avoided except in rare scenarios where an alternative means of accessing\nthe element or its functionality via the keyboard is available."
|
|
998
|
+
},
|
|
999
|
+
"id": {
|
|
1000
|
+
"type": "string | undefined",
|
|
1001
|
+
"required": false,
|
|
1002
|
+
"origin": "aria",
|
|
1003
|
+
"description": "The element's unique identifier. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)."
|
|
1004
|
+
},
|
|
1005
|
+
"aria-label": {
|
|
1006
|
+
"type": "string | undefined",
|
|
1007
|
+
"required": false,
|
|
1008
|
+
"origin": "aria",
|
|
1009
|
+
"description": "Defines a string value that labels the current element."
|
|
1010
|
+
},
|
|
1011
|
+
"aria-labelledby": {
|
|
1012
|
+
"type": "string | undefined",
|
|
1013
|
+
"required": false,
|
|
1014
|
+
"origin": "aria",
|
|
1015
|
+
"description": "Identifies the element (or elements) that labels the current element."
|
|
1016
|
+
},
|
|
1017
|
+
"aria-describedby": {
|
|
1018
|
+
"type": "string | undefined",
|
|
1019
|
+
"required": false,
|
|
1020
|
+
"origin": "aria",
|
|
1021
|
+
"description": "Identifies the element (or elements) that describes the object."
|
|
1022
|
+
},
|
|
1023
|
+
"aria-details": {
|
|
1024
|
+
"type": "string | undefined",
|
|
1025
|
+
"required": false,
|
|
1026
|
+
"origin": "aria",
|
|
1027
|
+
"description": "Identifies the element (or elements) that provide a detailed, extended description for the\nobject."
|
|
1028
|
+
}
|
|
1029
|
+
},
|
|
1030
|
+
"propCounts": {
|
|
1031
|
+
"own": 7,
|
|
1032
|
+
"aria": 39,
|
|
1033
|
+
"dom": 0,
|
|
1034
|
+
"other": 0
|
|
1035
|
+
}
|
|
1036
|
+
},
|
|
1037
|
+
"Checkbox": {
|
|
1038
|
+
"name": "Checkbox",
|
|
1039
|
+
"source": "src/components/Checkbox.tsx",
|
|
1040
|
+
"propsType": "CheckboxProps",
|
|
1041
|
+
"description": "Checkbox wraps a native `<input type=\"checkbox\">` and hides it.\n\nThe native input is kept rather than replaced by a div with `role=checkbox`\nbecause it brings form association, the indeterminate property, label\nclicking, and correct announcement — none of which are free to reimplement,\nand all of which are easy to get subtly wrong.\n\n`indeterminate` is the reason for the effect below: HTML has no\n`indeterminate` attribute, only a DOM property, so React cannot set it\ndeclaratively and it must be written after every render.",
|
|
1042
|
+
"import": "import { Checkbox } from 'ionbase-ui';",
|
|
1043
|
+
"stylesheet": "src/styles/checkbox.css",
|
|
1044
|
+
"tokens": [
|
|
1045
|
+
"--border-disabled",
|
|
1046
|
+
"--border-error-strong",
|
|
1047
|
+
"--border-focus",
|
|
1048
|
+
"--border-inverse",
|
|
1049
|
+
"--border-primary-strong",
|
|
1050
|
+
"--border-stronger",
|
|
1051
|
+
"--border-width-default",
|
|
1052
|
+
"--border-width-thick",
|
|
1053
|
+
"--font-family-sans",
|
|
1054
|
+
"--icon-disabled",
|
|
1055
|
+
"--icon-on-color",
|
|
1056
|
+
"--ion-checkbox-border",
|
|
1057
|
+
"--ion-checkbox-fill",
|
|
1058
|
+
"--ion-checkbox-font-size",
|
|
1059
|
+
"--ion-checkbox-gap",
|
|
1060
|
+
"--ion-checkbox-line-height",
|
|
1061
|
+
"--ion-checkbox-mark",
|
|
1062
|
+
"--ion-checkbox-radius",
|
|
1063
|
+
"--ion-checkbox-raised",
|
|
1064
|
+
"--ion-checkbox-size",
|
|
1065
|
+
"--ion-duration-base",
|
|
1066
|
+
"--ion-ease-out",
|
|
1067
|
+
"--ion-shadow-raised-flush-lg",
|
|
1068
|
+
"--ion-shadow-raised-flush-sm",
|
|
1069
|
+
"--ion-shadow-raised-flush-xs",
|
|
1070
|
+
"--radius-sm",
|
|
1071
|
+
"--radius-xs",
|
|
1072
|
+
"--spacing-12",
|
|
1073
|
+
"--spacing-16",
|
|
1074
|
+
"--spacing-20",
|
|
1075
|
+
"--spacing-24",
|
|
1076
|
+
"--spacing-4",
|
|
1077
|
+
"--spacing-8",
|
|
1078
|
+
"--surface-default",
|
|
1079
|
+
"--surface-disabled",
|
|
1080
|
+
"--surface-error",
|
|
1081
|
+
"--surface-inverse",
|
|
1082
|
+
"--surface-primary",
|
|
1083
|
+
"--text-disabled",
|
|
1084
|
+
"--text-secondary",
|
|
1085
|
+
"--type-body",
|
|
1086
|
+
"--type-body-line-height",
|
|
1087
|
+
"--type-body-sm",
|
|
1088
|
+
"--type-body-sm-line-height"
|
|
1089
|
+
],
|
|
1090
|
+
"props": {
|
|
1091
|
+
"size": {
|
|
1092
|
+
"type": "CheckboxSize | undefined",
|
|
1093
|
+
"required": false,
|
|
1094
|
+
"origin": "own",
|
|
1095
|
+
"description": "Matches the Figma `Size` variant: Small, Medium, Large.",
|
|
1096
|
+
"values": [
|
|
1097
|
+
"sm",
|
|
1098
|
+
"md",
|
|
1099
|
+
"lg"
|
|
1100
|
+
],
|
|
1101
|
+
"default": "md"
|
|
1102
|
+
},
|
|
1103
|
+
"intent": {
|
|
1104
|
+
"type": "CheckboxIntent | undefined",
|
|
1105
|
+
"required": false,
|
|
1106
|
+
"origin": "own",
|
|
1107
|
+
"description": "Matches the Figma `Color` variant: Brand, Neutral, Danger.",
|
|
1108
|
+
"values": [
|
|
1109
|
+
"neutral",
|
|
1110
|
+
"brand",
|
|
1111
|
+
"danger"
|
|
1112
|
+
],
|
|
1113
|
+
"default": "brand"
|
|
1114
|
+
},
|
|
1115
|
+
"isIndeterminate": {
|
|
1116
|
+
"type": "boolean | undefined",
|
|
1117
|
+
"required": false,
|
|
1118
|
+
"origin": "own",
|
|
1119
|
+
"description": "Figma's `Indeterminate` state. Not an HTML attribute — `indeterminate` is a\nDOM property only, so it has to be assigned after render.",
|
|
1120
|
+
"default": false
|
|
1121
|
+
},
|
|
1122
|
+
"isDisabled": {
|
|
1123
|
+
"type": "boolean | undefined",
|
|
1124
|
+
"required": false,
|
|
1125
|
+
"origin": "own",
|
|
1126
|
+
"description": "Whether the checkbox is disabled."
|
|
1127
|
+
},
|
|
1128
|
+
"disabled": {
|
|
1129
|
+
"type": "boolean | undefined",
|
|
1130
|
+
"required": false,
|
|
1131
|
+
"origin": "own",
|
|
1132
|
+
"tags": {
|
|
1133
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
1134
|
+
}
|
|
1135
|
+
},
|
|
1136
|
+
"children": {
|
|
1137
|
+
"type": "React.ReactNode",
|
|
1138
|
+
"required": false,
|
|
1139
|
+
"origin": "own",
|
|
1140
|
+
"description": "Figma's `Show Label` + `Label`. Omit for a bare box."
|
|
1141
|
+
}
|
|
1142
|
+
},
|
|
1143
|
+
"propCounts": {
|
|
1144
|
+
"own": 6,
|
|
1145
|
+
"aria": 0,
|
|
1146
|
+
"dom": 304,
|
|
1147
|
+
"other": 0
|
|
1148
|
+
}
|
|
1149
|
+
},
|
|
1150
|
+
"Divider": {
|
|
1151
|
+
"name": "Divider",
|
|
1152
|
+
"source": "src/components/Divider.tsx",
|
|
1153
|
+
"propsType": "DividerProps",
|
|
1154
|
+
"description": "A single `<hr>`, matching Figma's `Border` (70:22153).\n\n`<hr>` rather than a styled `<div>`: it is a semantic thematic break, so a\nscreen reader announces it as one, and it needs no `role` to get there.\n`aria-orientation` is set for the vertical case, since a vertical rule\ninside a horizontal toolbar is the one shape a screen reader cannot infer\nfrom the element alone.",
|
|
1155
|
+
"import": "import { Divider } from 'ionbase-ui';",
|
|
1156
|
+
"stylesheet": "src/styles/divider.css",
|
|
1157
|
+
"tokens": [
|
|
1158
|
+
"--border-strong",
|
|
1159
|
+
"--border-width-default"
|
|
1160
|
+
],
|
|
1161
|
+
"props": {
|
|
1162
|
+
"orientation": {
|
|
1163
|
+
"type": "DividerOrientation | undefined",
|
|
1164
|
+
"required": false,
|
|
1165
|
+
"origin": "own",
|
|
1166
|
+
"description": "Matches Figma's `Style` variant.",
|
|
1167
|
+
"values": [
|
|
1168
|
+
"horizontal",
|
|
1169
|
+
"vertical"
|
|
1170
|
+
]
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
"propCounts": {
|
|
1174
|
+
"own": 1,
|
|
1175
|
+
"aria": 0,
|
|
1176
|
+
"dom": 278,
|
|
1177
|
+
"other": 0
|
|
1178
|
+
}
|
|
1179
|
+
},
|
|
1180
|
+
"FullCard": {
|
|
1181
|
+
"name": "FullCard",
|
|
1182
|
+
"source": "src/components/FullCard.tsx",
|
|
1183
|
+
"propsType": "FullCardProps",
|
|
1184
|
+
"description": "Full Card — the full-bleed case study row from Figma `Full Card` (592:857).\n\nA text column beside a framed media panel, split down the middle, mirrored\nby the `Alignment` variant.\n\nThe split holds from 1080 and stacks below it, media above content in BOTH\nalignments — `Alignment` names a horizontal side and\nstops meaning anything once there is one column, so it does not get to\ndecide the vertical order too. Size is a media query, not a prop, the same\ncall Header makes about Device.\n\nWHY THE `show*` BOOLEANS ARE GONE\n\nFigma carries `Show Eyebrow`, `Show Description` and `Show Actions` beside\nthe slots they gate, because a Figma component instance always holds every\nlayer and needs a switch to hide one. React has no such constraint — an\nabsent prop is the switch. Badge made the same call with `Show Dot`, and\nkeeping both would have let `showActions` and `actions` disagree.\n\n`headline` is required, and it is the only required prop. The heading is\nwhat makes this a section rather than a decorated div, and every other part\nof the card is optional in Figma too.\n\nNo `'use client'`: nothing here is stateful or interactive. The interactive\nparts arrive through `actions`, and they carry their own boundary.",
|
|
1185
|
+
"import": "import { FullCard } from 'ionbase-ui';",
|
|
1186
|
+
"stylesheet": "src/styles/full-card.css",
|
|
1187
|
+
"tokens": [
|
|
1188
|
+
"--border-default",
|
|
1189
|
+
"--border-width-default",
|
|
1190
|
+
"--font-family-sans",
|
|
1191
|
+
"--font-weight-regular",
|
|
1192
|
+
"--font-weight-semibold",
|
|
1193
|
+
"--ion-full-card-gap",
|
|
1194
|
+
"--ion-full-card-media-gutter",
|
|
1195
|
+
"--ion-full-card-media-min-height",
|
|
1196
|
+
"--ion-full-card-media-width",
|
|
1197
|
+
"--ion-full-card-padding-x",
|
|
1198
|
+
"--ion-full-card-padding-y",
|
|
1199
|
+
"--radius-5xl",
|
|
1200
|
+
"--radius-6xl",
|
|
1201
|
+
"--radius-none",
|
|
1202
|
+
"--spacing-0",
|
|
1203
|
+
"--spacing-24",
|
|
1204
|
+
"--spacing-32",
|
|
1205
|
+
"--spacing-48",
|
|
1206
|
+
"--spacing-8",
|
|
1207
|
+
"--surface-default",
|
|
1208
|
+
"--surface-page",
|
|
1209
|
+
"--surface-sunken",
|
|
1210
|
+
"--text-default",
|
|
1211
|
+
"--text-secondary",
|
|
1212
|
+
"--type-body-sm",
|
|
1213
|
+
"--type-body-sm-line-height",
|
|
1214
|
+
"--type-h3",
|
|
1215
|
+
"--type-h3-line-height"
|
|
1216
|
+
],
|
|
1217
|
+
"props": {
|
|
1218
|
+
"alignment": {
|
|
1219
|
+
"type": "FullCardAlignment | undefined",
|
|
1220
|
+
"required": false,
|
|
1221
|
+
"origin": "own",
|
|
1222
|
+
"description": "Which side the media panel sits on. Matches Figma's `Alignment` variant,\nwhose `Right` / `Left` name the media, not the text.",
|
|
1223
|
+
"values": [
|
|
1224
|
+
"right",
|
|
1225
|
+
"left"
|
|
1226
|
+
]
|
|
1227
|
+
},
|
|
1228
|
+
"eyebrow": {
|
|
1229
|
+
"type": "React.ReactNode",
|
|
1230
|
+
"required": false,
|
|
1231
|
+
"origin": "own",
|
|
1232
|
+
"description": "Figma's `Eyebrow` slot — a Badge in the design, but any node works."
|
|
1233
|
+
},
|
|
1234
|
+
"headline": {
|
|
1235
|
+
"type": "React.ReactNode",
|
|
1236
|
+
"required": true,
|
|
1237
|
+
"origin": "own",
|
|
1238
|
+
"description": "Figma's `Headline`. Required: a card with no headline has no accessible name."
|
|
1239
|
+
},
|
|
1240
|
+
"description": {
|
|
1241
|
+
"type": "React.ReactNode",
|
|
1242
|
+
"required": false,
|
|
1243
|
+
"origin": "own",
|
|
1244
|
+
"description": "Figma's `Description`."
|
|
1245
|
+
},
|
|
1246
|
+
"actions": {
|
|
1247
|
+
"type": "React.ReactNode",
|
|
1248
|
+
"required": false,
|
|
1249
|
+
"origin": "own",
|
|
1250
|
+
"description": "Figma's `Actions` slot — a secondary Button in the design."
|
|
1251
|
+
},
|
|
1252
|
+
"media": {
|
|
1253
|
+
"type": "React.ReactNode",
|
|
1254
|
+
"required": false,
|
|
1255
|
+
"origin": "own",
|
|
1256
|
+
"description": "Figma's `Media` slot. Rendered inside the framed screen holder, so pass\nthe screenshot or embed itself, not the frame."
|
|
1257
|
+
},
|
|
1258
|
+
"headingLevel": {
|
|
1259
|
+
"type": "FullCardHeadingLevel | undefined",
|
|
1260
|
+
"required": false,
|
|
1261
|
+
"origin": "own",
|
|
1262
|
+
"description": "Heading element for the headline. Defaults to `h3`, matching the `Type/H3`\ntext style Figma applies — but the level is a document-outline decision\nonly the page knows, so it is a prop rather than a constant."
|
|
1263
|
+
},
|
|
1264
|
+
"children": {
|
|
1265
|
+
"type": "React.ReactNode",
|
|
1266
|
+
"required": false,
|
|
1267
|
+
"origin": "own"
|
|
1268
|
+
}
|
|
1269
|
+
},
|
|
1270
|
+
"propCounts": {
|
|
1271
|
+
"own": 8,
|
|
1272
|
+
"aria": 0,
|
|
1273
|
+
"dom": 276,
|
|
1274
|
+
"other": 0
|
|
1275
|
+
}
|
|
1276
|
+
},
|
|
1277
|
+
"Header": {
|
|
1278
|
+
"name": "Header",
|
|
1279
|
+
"source": "src/components/Header.tsx",
|
|
1280
|
+
"propsType": "HeaderProps",
|
|
1281
|
+
"description": "Header renders Figma's four Device variants — Desktop, Tablet,\nMobile-Closed, Mobile-Open — from one DOM tree.\n\nTWO AXES, AND THEY ARE NOT THE SAME KIND OF THING\n\nFigma spells Device as a single four-way variant, but it is really two: a\n*breakpoint* (Desktop / Tablet / Mobile) and a *state* (Closed / Open). They\nare modelled differently here because they are known by different people.\n\n Breakpoint is a media query. It is the one variant axis in the system the\n browser already knows the answer to — a header is Mobile because the\n viewport is narrow — and having React duplicate that judgement is how the\n two drift apart. Breakpoints match the Breakpoint collection's container\n widths: Tablet below 1216, Mobile below 896.\n\n Open/Closed is a prop, because only the caller knows. It follows the\n controlled/uncontrolled pair the rest of the system uses.\n\nONE TREE, TWO LAYOUTS\n\n`center` and `end` sit inline in the bar on Desktop and Tablet, and inside\nthe dropped Menu-Container on Mobile-Open. They are rendered once, in one\nwrapper, which is `display: contents` above the mobile breakpoint and an\nabsolutely positioned panel below it. Rendering them twice — or moving them\nwith JavaScript — would mean the same nav link exists twice in the\naccessibility tree, and would reset any state a caller put in a slot every\ntime the viewport crossed 896px.\n\nThe centre slot is no longer hidden on Tablet. Figma's Tablet variant ships\nit populated; the previous release collapsed it, which was correct for the\nprevious design and is not for this one.\n\nA `<header>` element with no explicit role: it is a landmark already when it\nis a direct child of body, which is where a page header sits.",
|
|
1282
|
+
"import": "import { Header } from 'ionbase-ui';",
|
|
1283
|
+
"stylesheet": "src/styles/header.css",
|
|
1284
|
+
"tokens": [
|
|
1285
|
+
"--border-default",
|
|
1286
|
+
"--border-strong",
|
|
1287
|
+
"--border-width-default",
|
|
1288
|
+
"--border-width-thick",
|
|
1289
|
+
"--font-family-sans",
|
|
1290
|
+
"--icon-default",
|
|
1291
|
+
"--icon-size-sm",
|
|
1292
|
+
"--ion-header-center-gap",
|
|
1293
|
+
"--ion-header-end-gap",
|
|
1294
|
+
"--ion-header-height",
|
|
1295
|
+
"--ion-header-padding-x",
|
|
1296
|
+
"--ion-header-padding-y",
|
|
1297
|
+
"--ion-shadow-raised-lifted-xs",
|
|
1298
|
+
"--radius-md",
|
|
1299
|
+
"--radius-sm",
|
|
1300
|
+
"--ring-focus",
|
|
1301
|
+
"--spacing-12",
|
|
1302
|
+
"--spacing-16",
|
|
1303
|
+
"--spacing-2",
|
|
1304
|
+
"--spacing-24",
|
|
1305
|
+
"--spacing-32",
|
|
1306
|
+
"--spacing-4",
|
|
1307
|
+
"--spacing-48",
|
|
1308
|
+
"--spacing-64",
|
|
1309
|
+
"--spacing-8",
|
|
1310
|
+
"--surface-default"
|
|
1311
|
+
],
|
|
1312
|
+
"props": {
|
|
1313
|
+
"brand": {
|
|
1314
|
+
"type": "React.ReactNode",
|
|
1315
|
+
"required": false,
|
|
1316
|
+
"origin": "own",
|
|
1317
|
+
"description": "Figma's Logo slot. Rendered at the start, never shrinks."
|
|
1318
|
+
},
|
|
1319
|
+
"center": {
|
|
1320
|
+
"type": "React.ReactNode",
|
|
1321
|
+
"required": false,
|
|
1322
|
+
"origin": "own",
|
|
1323
|
+
"description": "Figma's `Center Slot` — nav items. Inline on Desktop and Tablet; moves\ninto the Mobile-Open menu below the mobile breakpoint."
|
|
1324
|
+
},
|
|
1325
|
+
"end": {
|
|
1326
|
+
"type": "React.ReactNode",
|
|
1327
|
+
"required": false,
|
|
1328
|
+
"origin": "own",
|
|
1329
|
+
"description": "Figma's `End Slot` — buttons and actions. Same placement rules as `center`."
|
|
1330
|
+
},
|
|
1331
|
+
"open": {
|
|
1332
|
+
"type": "boolean | undefined",
|
|
1333
|
+
"required": false,
|
|
1334
|
+
"origin": "own",
|
|
1335
|
+
"description": "Controlled Mobile-Open state. Pair with `onOpenChange`."
|
|
1336
|
+
},
|
|
1337
|
+
"defaultOpen": {
|
|
1338
|
+
"type": "boolean | undefined",
|
|
1339
|
+
"required": false,
|
|
1340
|
+
"origin": "own",
|
|
1341
|
+
"description": "Initial Mobile-Open state when uncontrolled."
|
|
1342
|
+
},
|
|
1343
|
+
"onOpenChange": {
|
|
1344
|
+
"type": "((open: boolean) => void) | undefined",
|
|
1345
|
+
"required": false,
|
|
1346
|
+
"origin": "own",
|
|
1347
|
+
"description": "Fires whenever the menu toggle changes the state, controlled or not."
|
|
1348
|
+
},
|
|
1349
|
+
"menuLabel": {
|
|
1350
|
+
"type": "string | undefined",
|
|
1351
|
+
"required": false,
|
|
1352
|
+
"origin": "own",
|
|
1353
|
+
"description": "Accessible name for the mobile menu toggle."
|
|
1354
|
+
},
|
|
1355
|
+
"children": {
|
|
1356
|
+
"type": "React.ReactNode",
|
|
1357
|
+
"required": false,
|
|
1358
|
+
"origin": "own"
|
|
1359
|
+
}
|
|
1360
|
+
},
|
|
1361
|
+
"propCounts": {
|
|
1362
|
+
"own": 8,
|
|
1363
|
+
"aria": 0,
|
|
1364
|
+
"dom": 276,
|
|
1365
|
+
"other": 0
|
|
1366
|
+
}
|
|
1367
|
+
},
|
|
1368
|
+
"Icon": {
|
|
1369
|
+
"name": "Icon",
|
|
1370
|
+
"source": "src/Icon.tsx",
|
|
1371
|
+
"propsType": "IconProps",
|
|
1372
|
+
"description": "Wrapper that applies the design system's icon sizing and accessibility\ndefaults to whatever icon component you hand it.\n\n import { Plus } from 'lucide-react';\n <Icon as={Plus} size=\"sm\" />\n <Icon as={Plus} label=\"Add item\" /> // meaningful, gets an a11y name\n\nTakes the icon as a prop rather than re-exporting a set: a barrel of a\nthousand-plus icons defeats tree-shaking in several bundlers, and pinning one\nicon library would force it on every consumer. You import the one icon you\nneed, from whichever library you use, and it is the only one bundled.",
|
|
1373
|
+
"import": "import { Icon } from 'ionbase-ui';",
|
|
1374
|
+
"stylesheet": "src/styles/icon.css",
|
|
1375
|
+
"tokens": [],
|
|
1376
|
+
"props": {
|
|
1377
|
+
"as": {
|
|
1378
|
+
"type": "IconComponent",
|
|
1379
|
+
"required": true,
|
|
1380
|
+
"origin": "own",
|
|
1381
|
+
"description": "The icon component to render, e.g. `import { Plus } from 'lucide-react'`.\nAny SVG component works — the design system does not ship an icon set."
|
|
1382
|
+
},
|
|
1383
|
+
"size": {
|
|
1384
|
+
"type": "\"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xs\" | \"xs\" | (string & {}) | undefined",
|
|
1385
|
+
"required": false,
|
|
1386
|
+
"origin": "own",
|
|
1387
|
+
"description": "A rung on the `icon-size` ladder — `2xs` 12, `xs` 14, `sm` 16, `md` 20,\n`lg` 24, `xl` 32 — or any CSS length for a one-off. Omit to inherit the surrounding\nfont size, which is what lets an icon sit correctly inside a Button without\nthe Button having to know anything about this component."
|
|
1388
|
+
},
|
|
1389
|
+
"label": {
|
|
1390
|
+
"type": "string | undefined",
|
|
1391
|
+
"required": false,
|
|
1392
|
+
"origin": "own",
|
|
1393
|
+
"description": "Accessible name. Provide it when the icon carries meaning on its own — an\nicon-only button, a status marker. Omit it for decoration next to a visible\nlabel, and the icon is hidden from assistive tech instead of read out twice."
|
|
1394
|
+
}
|
|
1395
|
+
},
|
|
1396
|
+
"propCounts": {
|
|
1397
|
+
"own": 3,
|
|
1398
|
+
"aria": 0,
|
|
1399
|
+
"dom": 487,
|
|
1400
|
+
"other": 0
|
|
1401
|
+
}
|
|
1402
|
+
},
|
|
1403
|
+
"Input": {
|
|
1404
|
+
"name": "Input",
|
|
1405
|
+
"source": "src/components/Input.tsx",
|
|
1406
|
+
"propsType": "InputProps",
|
|
1407
|
+
"description": "Input covers both Figma components on the Input page: the field itself\n(`Input`, 80:275) and the label/helper stack around it (`Form Field`,\n80:330). They are separate there because a Figma component cannot make a\nslot optional without a boolean; here the wrapper simply isn't rendered when\nthere is nothing to put in it.\n\n`useTextField` owns the wiring that is tedious and easy to get subtly wrong:\nit generates the ids, points `aria-labelledby` at the label and\n`aria-describedby` at whichever of the helper or error message is actually\nshowing, and sets `aria-invalid`. Hand-rolling that is where form fields\nusually lose their accessibility.\n\nFigma's seven states map to three props and three CSS states. Hover and Focus\nare interaction; Filled is the placeholder distinction, which CSS already\nexpresses; Default, Invalid, Disabled and Read-only are props.",
|
|
1408
|
+
"import": "import { Input } from 'ionbase-ui';",
|
|
1409
|
+
"status": "stable",
|
|
1410
|
+
"summary": "A single-line text field, together with its label, helper text and error message.",
|
|
1411
|
+
"useWhen": [
|
|
1412
|
+
"collecting one line of free text",
|
|
1413
|
+
"the field needs a label, helper text, or validation messaging"
|
|
1414
|
+
],
|
|
1415
|
+
"useInstead": [
|
|
1416
|
+
{
|
|
1417
|
+
"when": "the user picks from a fixed set of options",
|
|
1418
|
+
"use": "Select"
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
"when": "it is a phone number",
|
|
1422
|
+
"use": "PhoneInput",
|
|
1423
|
+
"why": "country code and formatting are handled for you"
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
"when": "it is a single boolean",
|
|
1427
|
+
"use": "Checkbox or Toggle"
|
|
1428
|
+
}
|
|
1429
|
+
],
|
|
1430
|
+
"variants": {
|
|
1431
|
+
"size": {
|
|
1432
|
+
"sm": {
|
|
1433
|
+
"use": "dense forms, table filters, toolbars"
|
|
1434
|
+
},
|
|
1435
|
+
"md": {
|
|
1436
|
+
"use": "the default"
|
|
1437
|
+
},
|
|
1438
|
+
"lg": {
|
|
1439
|
+
"use": "prominent single-field forms — search, sign-in"
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
},
|
|
1443
|
+
"slots": {
|
|
1444
|
+
"leadingIcon": {
|
|
1445
|
+
"accepts": "Icon",
|
|
1446
|
+
"note": "decorative; omit Icon's `label`"
|
|
1447
|
+
},
|
|
1448
|
+
"trailingIcon": {
|
|
1449
|
+
"accepts": "Icon",
|
|
1450
|
+
"note": "decorative unless it is interactive, in which case it needs its own button and name"
|
|
1451
|
+
},
|
|
1452
|
+
"leadingAddon": {
|
|
1453
|
+
"note": "a static prefix such as a protocol or currency; not focusable"
|
|
1454
|
+
}
|
|
1455
|
+
},
|
|
1456
|
+
"a11y": {
|
|
1457
|
+
"guarantees": [
|
|
1458
|
+
"ids are generated and wired — the label points at the input via aria-labelledby",
|
|
1459
|
+
"aria-describedby points at whichever of the helper text or error message is actually showing",
|
|
1460
|
+
"aria-invalid is set from isInvalid"
|
|
1461
|
+
],
|
|
1462
|
+
"requires": [
|
|
1463
|
+
"`label`, or `aria-label` when the field is visually self-evident and no label is rendered"
|
|
1464
|
+
],
|
|
1465
|
+
"notes": [
|
|
1466
|
+
"The label/helper/error wrapper is only rendered when there is something to put in it — Figma models it as a separate `Form Field` component, this does not."
|
|
1467
|
+
]
|
|
1468
|
+
},
|
|
1469
|
+
"antiPatterns": [
|
|
1470
|
+
{
|
|
1471
|
+
"dont": "using `placeholder` as the label",
|
|
1472
|
+
"do": "pass `label`",
|
|
1473
|
+
"why": "the placeholder disappears on focus, so the user loses the field's name exactly when typing"
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
"dont": "rendering your own <label htmlFor>",
|
|
1477
|
+
"do": "pass `label`",
|
|
1478
|
+
"why": "the component generates the id; an external htmlFor will not match it"
|
|
1479
|
+
},
|
|
1480
|
+
{
|
|
1481
|
+
"dont": "showing an error by putting the message in `description`",
|
|
1482
|
+
"do": "set `isInvalid` and pass `errorMessage`",
|
|
1483
|
+
"why": "only errorMessage drives aria-invalid and the described-by wiring"
|
|
1484
|
+
}
|
|
1485
|
+
],
|
|
1486
|
+
"deprecated": [
|
|
1487
|
+
{
|
|
1488
|
+
"prop": "disabled",
|
|
1489
|
+
"replacement": "isDisabled"
|
|
1490
|
+
}
|
|
1491
|
+
],
|
|
1492
|
+
"stylesheet": "src/styles/input.css",
|
|
1493
|
+
"tokens": [
|
|
1494
|
+
"--border-default",
|
|
1495
|
+
"--border-disabled",
|
|
1496
|
+
"--border-error-strong",
|
|
1497
|
+
"--border-focus",
|
|
1498
|
+
"--border-strong",
|
|
1499
|
+
"--border-subtle",
|
|
1500
|
+
"--border-width-default",
|
|
1501
|
+
"--border-width-thick",
|
|
1502
|
+
"--font-family-sans",
|
|
1503
|
+
"--font-weight-medium",
|
|
1504
|
+
"--font-weight-regular",
|
|
1505
|
+
"--icon-disabled",
|
|
1506
|
+
"--icon-interactive",
|
|
1507
|
+
"--icon-size-md",
|
|
1508
|
+
"--icon-size-sm",
|
|
1509
|
+
"--icon-tertiary",
|
|
1510
|
+
"--ion-duration-base",
|
|
1511
|
+
"--ion-ease-out",
|
|
1512
|
+
"--ion-input-border-width",
|
|
1513
|
+
"--ion-input-font-size",
|
|
1514
|
+
"--ion-input-gap",
|
|
1515
|
+
"--ion-input-height",
|
|
1516
|
+
"--ion-input-icon-size",
|
|
1517
|
+
"--ion-input-line-height",
|
|
1518
|
+
"--ion-input-padding-x",
|
|
1519
|
+
"--ion-input-radius",
|
|
1520
|
+
"--radius-md",
|
|
1521
|
+
"--radius-sm",
|
|
1522
|
+
"--spacing-12",
|
|
1523
|
+
"--spacing-16",
|
|
1524
|
+
"--spacing-32",
|
|
1525
|
+
"--spacing-40",
|
|
1526
|
+
"--spacing-48",
|
|
1527
|
+
"--spacing-6",
|
|
1528
|
+
"--spacing-8",
|
|
1529
|
+
"--surface-default",
|
|
1530
|
+
"--surface-disabled",
|
|
1531
|
+
"--surface-page",
|
|
1532
|
+
"--text-disabled",
|
|
1533
|
+
"--text-error",
|
|
1534
|
+
"--text-secondary",
|
|
1535
|
+
"--text-tertiary",
|
|
1536
|
+
"--type-body",
|
|
1537
|
+
"--type-body-line-height",
|
|
1538
|
+
"--type-body-sm",
|
|
1539
|
+
"--type-body-sm-line-height"
|
|
1540
|
+
],
|
|
1541
|
+
"props": {
|
|
1542
|
+
"size": {
|
|
1543
|
+
"type": "InputSize | undefined",
|
|
1544
|
+
"required": false,
|
|
1545
|
+
"origin": "own",
|
|
1546
|
+
"description": "Matches the Figma `Size` variant: Small, Medium, Large.",
|
|
1547
|
+
"values": [
|
|
1548
|
+
"sm",
|
|
1549
|
+
"md",
|
|
1550
|
+
"lg"
|
|
1551
|
+
],
|
|
1552
|
+
"default": "md"
|
|
1553
|
+
},
|
|
1554
|
+
"autoCapitalize": {
|
|
1555
|
+
"type": "\"none\" | \"off\" | \"on\" | \"sentences\" | \"words\" | \"characters\" | undefined",
|
|
1556
|
+
"required": false,
|
|
1557
|
+
"origin": "own",
|
|
1558
|
+
"description": "Narrower than React's own typing, which also allows any `string`.\n`autoCapitalize` is declared on `AriaTextFieldOptions` rather than\n`AriaTextFieldProps`, so `keyof AriaTextFieldProps` above cannot omit it —\nand the wide DOM version does not satisfy what `useTextField` accepts.",
|
|
1559
|
+
"values": [
|
|
1560
|
+
"none",
|
|
1561
|
+
"off",
|
|
1562
|
+
"on",
|
|
1563
|
+
"sentences",
|
|
1564
|
+
"words",
|
|
1565
|
+
"characters"
|
|
1566
|
+
]
|
|
1567
|
+
},
|
|
1568
|
+
"leadingIcon": {
|
|
1569
|
+
"type": "React.ReactNode",
|
|
1570
|
+
"required": false,
|
|
1571
|
+
"origin": "own",
|
|
1572
|
+
"description": "Leading icon. Figma's `Show Leading Icon` + `Leading Icon` swap."
|
|
1573
|
+
},
|
|
1574
|
+
"trailingIcon": {
|
|
1575
|
+
"type": "React.ReactNode",
|
|
1576
|
+
"required": false,
|
|
1577
|
+
"origin": "own",
|
|
1578
|
+
"description": "Trailing icon. Figma's `Show Trailing Icon` + `Trailing Icon` swap."
|
|
1579
|
+
},
|
|
1580
|
+
"leadingAddon": {
|
|
1581
|
+
"type": "React.ReactNode",
|
|
1582
|
+
"required": false,
|
|
1583
|
+
"origin": "own",
|
|
1584
|
+
"description": "A segment butted against the left of the control, sharing its outline —\nFigma's `Input/Phone` (80:372) country-code block.\n\nDistinct from `leadingIcon`, which sits *inside* the box: an addon has its\nown surface and border and is a sibling of the control, so the two cannot\nbe the same slot. It lives here rather than in `PhoneInput` because the\n`.ion-field` wrapper has to enclose the addon and the control together —\nbuilding it outside would put the label above only half the control and\nbreak the `aria-labelledby` wiring `useTextField` sets up.\n\nPhone is the only addon Figma specifies. This is a slot, not a system:\nresist growing a trailing counterpart or an addon variant ladder until a\ndesign actually calls for one."
|
|
1585
|
+
},
|
|
1586
|
+
"disabled": {
|
|
1587
|
+
"type": "boolean | undefined",
|
|
1588
|
+
"required": false,
|
|
1589
|
+
"origin": "own",
|
|
1590
|
+
"tags": {
|
|
1591
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
1592
|
+
}
|
|
1593
|
+
},
|
|
1594
|
+
"className": {
|
|
1595
|
+
"type": "string | undefined",
|
|
1596
|
+
"required": false,
|
|
1597
|
+
"origin": "own",
|
|
1598
|
+
"description": "Class names for the control box (`.ion-input`). Always lands here —\nnever on the form-field wrapper. Use `wrapperClassName` for that."
|
|
1599
|
+
},
|
|
1600
|
+
"wrapperClassName": {
|
|
1601
|
+
"type": "string | undefined",
|
|
1602
|
+
"required": false,
|
|
1603
|
+
"origin": "own",
|
|
1604
|
+
"description": "Class names for the `.ion-field` wrapper when a label or helper is shown."
|
|
1605
|
+
},
|
|
1606
|
+
"aria-activedescendant": {
|
|
1607
|
+
"type": "string | undefined",
|
|
1608
|
+
"required": false,
|
|
1609
|
+
"origin": "aria",
|
|
1610
|
+
"description": "Identifies the currently active element when DOM focus is on a composite widget, textbox,\ngroup, or application."
|
|
1611
|
+
},
|
|
1612
|
+
"aria-autocomplete": {
|
|
1613
|
+
"type": "\"inline\" | \"list\" | \"none\" | \"both\" | undefined",
|
|
1614
|
+
"required": false,
|
|
1615
|
+
"origin": "aria",
|
|
1616
|
+
"description": "Indicates whether inputting text could trigger display of one or more predictions of the user's\nintended value for an input and specifies how predictions would be presented if they are made.",
|
|
1617
|
+
"values": [
|
|
1618
|
+
"inline",
|
|
1619
|
+
"list",
|
|
1620
|
+
"none",
|
|
1621
|
+
"both"
|
|
1622
|
+
]
|
|
1623
|
+
},
|
|
1624
|
+
"aria-haspopup": {
|
|
1625
|
+
"type": "boolean | \"true\" | \"false\" | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\" | undefined",
|
|
1626
|
+
"required": false,
|
|
1627
|
+
"origin": "aria",
|
|
1628
|
+
"description": "Indicates the availability and type of interactive popup element, such as menu or dialog, that\ncan be triggered by an element."
|
|
1629
|
+
},
|
|
1630
|
+
"aria-controls": {
|
|
1631
|
+
"type": "string | undefined",
|
|
1632
|
+
"required": false,
|
|
1633
|
+
"origin": "aria",
|
|
1634
|
+
"description": "Identifies the element (or elements) whose contents or presence are controlled by the current\nelement."
|
|
1635
|
+
},
|
|
1636
|
+
"enterKeyHint": {
|
|
1637
|
+
"type": "\"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
|
|
1638
|
+
"required": false,
|
|
1639
|
+
"origin": "aria",
|
|
1640
|
+
"description": "An enumerated attribute that defines what action label or icon to preset for the enter key on\nvirtual keyboards. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint).",
|
|
1641
|
+
"values": [
|
|
1642
|
+
"enter",
|
|
1643
|
+
"done",
|
|
1644
|
+
"go",
|
|
1645
|
+
"next",
|
|
1646
|
+
"previous",
|
|
1647
|
+
"search",
|
|
1648
|
+
"send"
|
|
1649
|
+
]
|
|
1650
|
+
},
|
|
1651
|
+
"isDisabled": {
|
|
1652
|
+
"type": "boolean | undefined",
|
|
1653
|
+
"required": false,
|
|
1654
|
+
"origin": "aria",
|
|
1655
|
+
"description": "Whether the input is disabled."
|
|
1656
|
+
},
|
|
1657
|
+
"isReadOnly": {
|
|
1658
|
+
"type": "boolean | undefined",
|
|
1659
|
+
"required": false,
|
|
1660
|
+
"origin": "aria",
|
|
1661
|
+
"description": "Whether the input can be selected but not changed by the user."
|
|
1662
|
+
},
|
|
1663
|
+
"isRequired": {
|
|
1664
|
+
"type": "boolean | undefined",
|
|
1665
|
+
"required": false,
|
|
1666
|
+
"origin": "aria",
|
|
1667
|
+
"description": "Whether user input is required on the input before form submission."
|
|
1668
|
+
},
|
|
1669
|
+
"isInvalid": {
|
|
1670
|
+
"type": "boolean | undefined",
|
|
1671
|
+
"required": false,
|
|
1672
|
+
"origin": "aria",
|
|
1673
|
+
"description": "Whether the input value is invalid."
|
|
1674
|
+
},
|
|
1675
|
+
"validationState": {
|
|
1676
|
+
"type": "ValidationState | undefined",
|
|
1677
|
+
"required": false,
|
|
1678
|
+
"origin": "aria",
|
|
1679
|
+
"values": [
|
|
1680
|
+
"valid",
|
|
1681
|
+
"invalid"
|
|
1682
|
+
],
|
|
1683
|
+
"tags": {
|
|
1684
|
+
"deprecated": "Use `isInvalid` instead."
|
|
1685
|
+
}
|
|
1686
|
+
},
|
|
1687
|
+
"validationBehavior": {
|
|
1688
|
+
"type": "\"aria\" | \"native\" | undefined",
|
|
1689
|
+
"required": false,
|
|
1690
|
+
"origin": "aria",
|
|
1691
|
+
"description": "Whether to use native HTML form validation to prevent form submission\nwhen the value is missing or invalid, or mark the field as required\nor invalid via ARIA.",
|
|
1692
|
+
"values": [
|
|
1693
|
+
"aria",
|
|
1694
|
+
"native"
|
|
1695
|
+
],
|
|
1696
|
+
"tags": {
|
|
1697
|
+
"default": "'aria'"
|
|
1698
|
+
}
|
|
1699
|
+
},
|
|
1700
|
+
"validate": {
|
|
1701
|
+
"type": "((value: string) => ValidationError | true | null | undefined) | undefined",
|
|
1702
|
+
"required": false,
|
|
1703
|
+
"origin": "aria",
|
|
1704
|
+
"description": "A function that returns an error message if a given value is invalid.\nValidation errors are displayed to the user when the form is submitted\nif `validationBehavior=\"native\"`. For realtime validation, use the `isInvalid`\nprop instead."
|
|
1705
|
+
},
|
|
1706
|
+
"description": {
|
|
1707
|
+
"type": "ReactNode",
|
|
1708
|
+
"required": false,
|
|
1709
|
+
"origin": "aria",
|
|
1710
|
+
"description": "A description for the field. Provides a hint such as specific requirements for what to choose."
|
|
1711
|
+
},
|
|
1712
|
+
"errorMessage": {
|
|
1713
|
+
"type": "ReactNode | ((v: ValidationResult) => ReactNode)",
|
|
1714
|
+
"required": false,
|
|
1715
|
+
"origin": "aria",
|
|
1716
|
+
"description": "An error message for the field."
|
|
1717
|
+
},
|
|
1718
|
+
"autoFocus": {
|
|
1719
|
+
"type": "boolean | undefined",
|
|
1720
|
+
"required": false,
|
|
1721
|
+
"origin": "aria",
|
|
1722
|
+
"description": "Whether the element should receive focus on render."
|
|
1723
|
+
},
|
|
1724
|
+
"onFocus": {
|
|
1725
|
+
"type": "((e: FocusEvent<HTMLInputElement, Element>) => void) | undefined",
|
|
1726
|
+
"required": false,
|
|
1727
|
+
"origin": "aria",
|
|
1728
|
+
"description": "Handler that is called when the element receives focus."
|
|
1729
|
+
},
|
|
1730
|
+
"onBlur": {
|
|
1731
|
+
"type": "((e: FocusEvent<HTMLInputElement, Element>) => void) | undefined",
|
|
1732
|
+
"required": false,
|
|
1733
|
+
"origin": "aria",
|
|
1734
|
+
"description": "Handler that is called when the element loses focus."
|
|
1735
|
+
},
|
|
1736
|
+
"onFocusChange": {
|
|
1737
|
+
"type": "((isFocused: boolean) => void) | undefined",
|
|
1738
|
+
"required": false,
|
|
1739
|
+
"origin": "aria",
|
|
1740
|
+
"description": "Handler that is called when the element's focus status changes."
|
|
1741
|
+
},
|
|
1742
|
+
"onKeyDown": {
|
|
1743
|
+
"type": "((e: KeyboardEvent) => void) | undefined",
|
|
1744
|
+
"required": false,
|
|
1745
|
+
"origin": "aria",
|
|
1746
|
+
"description": "Handler that is called when a key is pressed."
|
|
1747
|
+
},
|
|
1748
|
+
"onKeyUp": {
|
|
1749
|
+
"type": "((e: KeyboardEvent) => void) | undefined",
|
|
1750
|
+
"required": false,
|
|
1751
|
+
"origin": "aria",
|
|
1752
|
+
"description": "Handler that is called when a key is released."
|
|
1753
|
+
},
|
|
1754
|
+
"placeholder": {
|
|
1755
|
+
"type": "string | undefined",
|
|
1756
|
+
"required": false,
|
|
1757
|
+
"origin": "aria",
|
|
1758
|
+
"description": "Temporary text that occupies the text input when it is empty."
|
|
1759
|
+
},
|
|
1760
|
+
"value": {
|
|
1761
|
+
"type": "string | undefined",
|
|
1762
|
+
"required": false,
|
|
1763
|
+
"origin": "aria",
|
|
1764
|
+
"description": "The current value (controlled)."
|
|
1765
|
+
},
|
|
1766
|
+
"defaultValue": {
|
|
1767
|
+
"type": "string | undefined",
|
|
1768
|
+
"required": false,
|
|
1769
|
+
"origin": "aria",
|
|
1770
|
+
"description": "The default value (uncontrolled)."
|
|
1771
|
+
},
|
|
1772
|
+
"onChange": {
|
|
1773
|
+
"type": "((value: string) => void) | undefined",
|
|
1774
|
+
"required": false,
|
|
1775
|
+
"origin": "aria",
|
|
1776
|
+
"description": "Handler that is called when the value changes."
|
|
1777
|
+
},
|
|
1778
|
+
"label": {
|
|
1779
|
+
"type": "ReactNode",
|
|
1780
|
+
"required": false,
|
|
1781
|
+
"origin": "aria",
|
|
1782
|
+
"description": "The content to display as the label."
|
|
1783
|
+
},
|
|
1784
|
+
"aria-label": {
|
|
1785
|
+
"type": "string | undefined",
|
|
1786
|
+
"required": false,
|
|
1787
|
+
"origin": "aria",
|
|
1788
|
+
"description": "Defines a string value that labels the current element."
|
|
1789
|
+
},
|
|
1790
|
+
"aria-labelledby": {
|
|
1791
|
+
"type": "string | undefined",
|
|
1792
|
+
"required": false,
|
|
1793
|
+
"origin": "aria",
|
|
1794
|
+
"description": "Identifies the element (or elements) that labels the current element."
|
|
1795
|
+
},
|
|
1796
|
+
"aria-describedby": {
|
|
1797
|
+
"type": "string | undefined",
|
|
1798
|
+
"required": false,
|
|
1799
|
+
"origin": "aria",
|
|
1800
|
+
"description": "Identifies the element (or elements) that describes the object."
|
|
1801
|
+
},
|
|
1802
|
+
"aria-details": {
|
|
1803
|
+
"type": "string | undefined",
|
|
1804
|
+
"required": false,
|
|
1805
|
+
"origin": "aria",
|
|
1806
|
+
"description": "Identifies the element (or elements) that provide a detailed, extended description for the\nobject."
|
|
1807
|
+
},
|
|
1808
|
+
"excludeFromTabOrder": {
|
|
1809
|
+
"type": "boolean | undefined",
|
|
1810
|
+
"required": false,
|
|
1811
|
+
"origin": "aria",
|
|
1812
|
+
"description": "Whether to exclude the element from the sequential tab order. If true,\nthe element will not be focusable via the keyboard by tabbing. This should\nbe avoided except in rare scenarios where an alternative means of accessing\nthe element or its functionality via the keyboard is available."
|
|
1813
|
+
},
|
|
1814
|
+
"id": {
|
|
1815
|
+
"type": "string | undefined",
|
|
1816
|
+
"required": false,
|
|
1817
|
+
"origin": "aria",
|
|
1818
|
+
"description": "The element's unique identifier. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)."
|
|
1819
|
+
},
|
|
1820
|
+
"autoComplete": {
|
|
1821
|
+
"type": "string | undefined",
|
|
1822
|
+
"required": false,
|
|
1823
|
+
"origin": "aria",
|
|
1824
|
+
"description": "Describes the type of autocomplete functionality the input should provide if any. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautocomplete)."
|
|
1825
|
+
},
|
|
1826
|
+
"maxLength": {
|
|
1827
|
+
"type": "number | undefined",
|
|
1828
|
+
"required": false,
|
|
1829
|
+
"origin": "aria",
|
|
1830
|
+
"description": "The maximum number of characters supported by the input. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefmaxlength)."
|
|
1831
|
+
},
|
|
1832
|
+
"minLength": {
|
|
1833
|
+
"type": "number | undefined",
|
|
1834
|
+
"required": false,
|
|
1835
|
+
"origin": "aria",
|
|
1836
|
+
"description": "The minimum number of characters required by the input. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefminlength)."
|
|
1837
|
+
},
|
|
1838
|
+
"pattern": {
|
|
1839
|
+
"type": "string | undefined",
|
|
1840
|
+
"required": false,
|
|
1841
|
+
"origin": "aria",
|
|
1842
|
+
"description": "Regex pattern that the value of the input must match to be valid. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefpattern)."
|
|
1843
|
+
},
|
|
1844
|
+
"type": {
|
|
1845
|
+
"type": "(string & {}) | \"search\" | \"text\" | \"url\" | \"tel\" | \"email\" | \"password\" | undefined",
|
|
1846
|
+
"required": false,
|
|
1847
|
+
"origin": "aria",
|
|
1848
|
+
"description": "The type of input to render. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdeftype).",
|
|
1849
|
+
"tags": {
|
|
1850
|
+
"default": "'text'"
|
|
1851
|
+
}
|
|
1852
|
+
},
|
|
1853
|
+
"inputMode": {
|
|
1854
|
+
"type": "\"none\" | \"search\" | \"text\" | \"url\" | \"tel\" | \"email\" | \"numeric\" | \"decimal\" | undefined",
|
|
1855
|
+
"required": false,
|
|
1856
|
+
"origin": "aria",
|
|
1857
|
+
"description": "Hints at the type of data that might be entered by the user while editing the element or its\ncontents. See\n[MDN](https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute).",
|
|
1858
|
+
"values": [
|
|
1859
|
+
"none",
|
|
1860
|
+
"search",
|
|
1861
|
+
"text",
|
|
1862
|
+
"url",
|
|
1863
|
+
"tel",
|
|
1864
|
+
"email",
|
|
1865
|
+
"numeric",
|
|
1866
|
+
"decimal"
|
|
1867
|
+
]
|
|
1868
|
+
},
|
|
1869
|
+
"autoCorrect": {
|
|
1870
|
+
"type": "string | undefined",
|
|
1871
|
+
"required": false,
|
|
1872
|
+
"origin": "aria",
|
|
1873
|
+
"description": "An attribute that takes as its value a space-separated string that describes what, if any, type\nof autocomplete functionality the input should provide. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autocomplete)."
|
|
1874
|
+
},
|
|
1875
|
+
"spellCheck": {
|
|
1876
|
+
"type": "string | undefined",
|
|
1877
|
+
"required": false,
|
|
1878
|
+
"origin": "aria",
|
|
1879
|
+
"description": "An enumerated attribute that defines whether the element may be checked for spelling errors.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck)."
|
|
1880
|
+
},
|
|
1881
|
+
"name": {
|
|
1882
|
+
"type": "string | undefined",
|
|
1883
|
+
"required": false,
|
|
1884
|
+
"origin": "aria",
|
|
1885
|
+
"description": "The name of the input element, used when submitting an HTML form. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname)."
|
|
1886
|
+
},
|
|
1887
|
+
"form": {
|
|
1888
|
+
"type": "string | undefined",
|
|
1889
|
+
"required": false,
|
|
1890
|
+
"origin": "aria",
|
|
1891
|
+
"description": "The `<form>` element to associate the input with.\nThe value of this attribute must be the id of a `<form>` in the same document.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#form)."
|
|
1892
|
+
},
|
|
1893
|
+
"onCopy": {
|
|
1894
|
+
"type": "ClipboardEventHandler<HTMLInputElement> | undefined",
|
|
1895
|
+
"required": false,
|
|
1896
|
+
"origin": "aria",
|
|
1897
|
+
"description": "Handler that is called when the user copies text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncopy)."
|
|
1898
|
+
},
|
|
1899
|
+
"onCut": {
|
|
1900
|
+
"type": "ClipboardEventHandler<HTMLInputElement> | undefined",
|
|
1901
|
+
"required": false,
|
|
1902
|
+
"origin": "aria",
|
|
1903
|
+
"description": "Handler that is called when the user cuts text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncut)."
|
|
1904
|
+
},
|
|
1905
|
+
"onPaste": {
|
|
1906
|
+
"type": "ClipboardEventHandler<HTMLInputElement> | undefined",
|
|
1907
|
+
"required": false,
|
|
1908
|
+
"origin": "aria",
|
|
1909
|
+
"description": "Handler that is called when the user pastes text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/onpaste)."
|
|
1910
|
+
},
|
|
1911
|
+
"onCompositionStart": {
|
|
1912
|
+
"type": "CompositionEventHandler<HTMLInputElement> | undefined",
|
|
1913
|
+
"required": false,
|
|
1914
|
+
"origin": "aria",
|
|
1915
|
+
"description": "Handler that is called when a text composition system starts a new text composition session.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event)."
|
|
1916
|
+
},
|
|
1917
|
+
"onCompositionEnd": {
|
|
1918
|
+
"type": "CompositionEventHandler<HTMLInputElement> | undefined",
|
|
1919
|
+
"required": false,
|
|
1920
|
+
"origin": "aria",
|
|
1921
|
+
"description": "Handler that is called when a text composition system completes or cancels the current text\ncomposition session. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionend_event)."
|
|
1922
|
+
},
|
|
1923
|
+
"onCompositionUpdate": {
|
|
1924
|
+
"type": "CompositionEventHandler<HTMLInputElement> | undefined",
|
|
1925
|
+
"required": false,
|
|
1926
|
+
"origin": "aria",
|
|
1927
|
+
"description": "Handler that is called when a new character is received in the current text composition\nsession. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionupdate_event)."
|
|
1928
|
+
},
|
|
1929
|
+
"onSelect": {
|
|
1930
|
+
"type": "ReactEventHandler<HTMLInputElement> | undefined",
|
|
1931
|
+
"required": false,
|
|
1932
|
+
"origin": "aria",
|
|
1933
|
+
"description": "Handler that is called when text in the input is selected. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event)."
|
|
1934
|
+
},
|
|
1935
|
+
"onBeforeInput": {
|
|
1936
|
+
"type": "FormEventHandler<HTMLInputElement> | undefined",
|
|
1937
|
+
"required": false,
|
|
1938
|
+
"origin": "aria",
|
|
1939
|
+
"description": "Handler that is called when the input value is about to be modified. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/beforeinput_event)."
|
|
1940
|
+
},
|
|
1941
|
+
"onInput": {
|
|
1942
|
+
"type": "FormEventHandler<HTMLInputElement> | undefined",
|
|
1943
|
+
"required": false,
|
|
1944
|
+
"origin": "aria",
|
|
1945
|
+
"description": "Handler that is called when the input value is modified. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event)."
|
|
1946
|
+
},
|
|
1947
|
+
"aria-errormessage": {
|
|
1948
|
+
"type": "string | undefined",
|
|
1949
|
+
"required": false,
|
|
1950
|
+
"origin": "aria",
|
|
1951
|
+
"description": "Identifies the element that provides an error message for the object."
|
|
1952
|
+
}
|
|
1953
|
+
},
|
|
1954
|
+
"propCounts": {
|
|
1955
|
+
"own": 8,
|
|
1956
|
+
"aria": 51,
|
|
1957
|
+
"dom": 265,
|
|
1958
|
+
"other": 0
|
|
1959
|
+
}
|
|
1960
|
+
},
|
|
1961
|
+
"Link": {
|
|
1962
|
+
"name": "Link",
|
|
1963
|
+
"source": "src/components/Link.tsx",
|
|
1964
|
+
"propsType": "LinkProps",
|
|
1965
|
+
"description": "Link — Figma `Link` (774:1516).\n\nRenders an `<a>` when given an `href` and a `<button>` otherwise, the same\njudgment `NavItem` makes: the element follows what the caller is actually\nbuilding rather than a separate `as` prop. A link that does not navigate is\na button, and shipping one as an anchor breaks middle-click, \"open in new\ntab\" and the screen-reader announcement all at once.\n\nNO SIZE PROP, DELIBERATELY. A link is an inline element and inherits its\ntype from the text around it — `font-size: inherit` in the stylesheet, and\nicons sized in `em` so they scale with it. Figma has to draw its variants at\nsome concrete size (16/24, `type/body`), but that is one sample of an\ninheriting element, not a specification. Do not add a size ladder to match\nthe drawing.",
|
|
1966
|
+
"import": "import { Link } from 'ionbase-ui';",
|
|
1967
|
+
"stylesheet": "src/styles/link.css",
|
|
1968
|
+
"tokens": [
|
|
1969
|
+
"--border-width-thick",
|
|
1970
|
+
"--ion-duration-base",
|
|
1971
|
+
"--ion-ease-out",
|
|
1972
|
+
"--radius-xs",
|
|
1973
|
+
"--ring-focus",
|
|
1974
|
+
"--spacing-4",
|
|
1975
|
+
"--text-disabled",
|
|
1976
|
+
"--text-link",
|
|
1977
|
+
"--text-link-hover",
|
|
1978
|
+
"--text-link-visited"
|
|
1979
|
+
],
|
|
1980
|
+
"props": {
|
|
1981
|
+
"variant": {
|
|
1982
|
+
"type": "LinkVariant | undefined",
|
|
1983
|
+
"required": false,
|
|
1984
|
+
"origin": "own",
|
|
1985
|
+
"description": "Matches the Figma `Type` variant.\n\n`inline` is for links inside body copy and is underlined in every state —\na link in a paragraph must not rely on colour alone (WCAG 1.4.1).\n`standalone` is for links that already read as interactive from their\nposition, and underlines on hover only.",
|
|
1986
|
+
"values": [
|
|
1987
|
+
"inline",
|
|
1988
|
+
"standalone"
|
|
1989
|
+
],
|
|
1990
|
+
"default": "inline"
|
|
1991
|
+
},
|
|
1992
|
+
"startIcon": {
|
|
1993
|
+
"type": "React.ReactNode",
|
|
1994
|
+
"required": false,
|
|
1995
|
+
"origin": "own",
|
|
1996
|
+
"description": "Optional icon before the label."
|
|
1997
|
+
},
|
|
1998
|
+
"endIcon": {
|
|
1999
|
+
"type": "React.ReactNode",
|
|
2000
|
+
"required": false,
|
|
2001
|
+
"origin": "own",
|
|
2002
|
+
"description": "Optional icon after the label — the external-link or arrow affordance."
|
|
2003
|
+
},
|
|
2004
|
+
"className": {
|
|
2005
|
+
"type": "string | undefined",
|
|
2006
|
+
"required": false,
|
|
2007
|
+
"origin": "own"
|
|
2008
|
+
},
|
|
2009
|
+
"children": {
|
|
2010
|
+
"type": "React.ReactNode",
|
|
2011
|
+
"required": false,
|
|
2012
|
+
"origin": "own"
|
|
2013
|
+
},
|
|
2014
|
+
"disabled": {
|
|
2015
|
+
"type": "boolean | undefined",
|
|
2016
|
+
"required": false,
|
|
2017
|
+
"origin": "own",
|
|
2018
|
+
"tags": {
|
|
2019
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
2020
|
+
}
|
|
2021
|
+
},
|
|
2022
|
+
"isDisabled": {
|
|
2023
|
+
"type": "boolean | undefined",
|
|
2024
|
+
"required": false,
|
|
2025
|
+
"origin": "aria",
|
|
2026
|
+
"description": "Whether the link is disabled."
|
|
2027
|
+
},
|
|
2028
|
+
"elementType": {
|
|
2029
|
+
"type": "string | undefined",
|
|
2030
|
+
"required": false,
|
|
2031
|
+
"origin": "aria",
|
|
2032
|
+
"description": "The HTML element used to render the link, e.g. 'a', or 'span'.",
|
|
2033
|
+
"tags": {
|
|
2034
|
+
"default": "'a'"
|
|
2035
|
+
}
|
|
2036
|
+
},
|
|
2037
|
+
"onPress": {
|
|
2038
|
+
"type": "((e: PressEvent) => void) | undefined",
|
|
2039
|
+
"required": false,
|
|
2040
|
+
"origin": "aria",
|
|
2041
|
+
"description": "Handler that is called when the press is released over the target."
|
|
2042
|
+
},
|
|
2043
|
+
"onPressStart": {
|
|
2044
|
+
"type": "((e: PressEvent) => void) | undefined",
|
|
2045
|
+
"required": false,
|
|
2046
|
+
"origin": "aria",
|
|
2047
|
+
"description": "Handler that is called when a press interaction starts."
|
|
2048
|
+
},
|
|
2049
|
+
"onPressEnd": {
|
|
2050
|
+
"type": "((e: PressEvent) => void) | undefined",
|
|
2051
|
+
"required": false,
|
|
2052
|
+
"origin": "aria",
|
|
2053
|
+
"description": "Handler that is called when a press interaction ends, either\nover the target or when the pointer leaves the target."
|
|
2054
|
+
},
|
|
2055
|
+
"onPressChange": {
|
|
2056
|
+
"type": "((isPressed: boolean) => void) | undefined",
|
|
2057
|
+
"required": false,
|
|
2058
|
+
"origin": "aria",
|
|
2059
|
+
"description": "Handler that is called when the press state changes."
|
|
2060
|
+
},
|
|
2061
|
+
"onPressUp": {
|
|
2062
|
+
"type": "((e: PressEvent) => void) | undefined",
|
|
2063
|
+
"required": false,
|
|
2064
|
+
"origin": "aria",
|
|
2065
|
+
"description": "Handler that is called when a press is released over the target, regardless of\nwhether it started on the target or not."
|
|
2066
|
+
},
|
|
2067
|
+
"onClick": {
|
|
2068
|
+
"type": "((e: MouseEvent<FocusableElement>) => void) | undefined",
|
|
2069
|
+
"required": false,
|
|
2070
|
+
"origin": "aria",
|
|
2071
|
+
"description": "**Not recommended – use `onPress` instead.** `onClick` is an alias for `onPress`\nprovided for compatibility with other libraries. `onPress` provides\nadditional event details for non-mouse interactions."
|
|
2072
|
+
},
|
|
2073
|
+
"autoFocus": {
|
|
2074
|
+
"type": "boolean | undefined",
|
|
2075
|
+
"required": false,
|
|
2076
|
+
"origin": "aria",
|
|
2077
|
+
"description": "Whether the element should receive focus on render."
|
|
2078
|
+
},
|
|
2079
|
+
"onFocus": {
|
|
2080
|
+
"type": "((e: FocusEvent<Element, Element>) => void) | undefined",
|
|
2081
|
+
"required": false,
|
|
2082
|
+
"origin": "aria",
|
|
2083
|
+
"description": "Handler that is called when the element receives focus."
|
|
2084
|
+
},
|
|
2085
|
+
"onBlur": {
|
|
2086
|
+
"type": "((e: FocusEvent<Element, Element>) => void) | undefined",
|
|
2087
|
+
"required": false,
|
|
2088
|
+
"origin": "aria",
|
|
2089
|
+
"description": "Handler that is called when the element loses focus."
|
|
2090
|
+
},
|
|
2091
|
+
"onFocusChange": {
|
|
2092
|
+
"type": "((isFocused: boolean) => void) | undefined",
|
|
2093
|
+
"required": false,
|
|
2094
|
+
"origin": "aria",
|
|
2095
|
+
"description": "Handler that is called when the element's focus status changes."
|
|
2096
|
+
},
|
|
2097
|
+
"onKeyDown": {
|
|
2098
|
+
"type": "((e: KeyboardEvent) => void) | undefined",
|
|
2099
|
+
"required": false,
|
|
2100
|
+
"origin": "aria",
|
|
2101
|
+
"description": "Handler that is called when a key is pressed."
|
|
2102
|
+
},
|
|
2103
|
+
"onKeyUp": {
|
|
2104
|
+
"type": "((e: KeyboardEvent) => void) | undefined",
|
|
2105
|
+
"required": false,
|
|
2106
|
+
"origin": "aria",
|
|
2107
|
+
"description": "Handler that is called when a key is released."
|
|
2108
|
+
},
|
|
2109
|
+
"href": {
|
|
2110
|
+
"type": "string | undefined",
|
|
2111
|
+
"required": false,
|
|
2112
|
+
"origin": "aria",
|
|
2113
|
+
"description": "A URL to link to. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#href)."
|
|
2114
|
+
},
|
|
2115
|
+
"hrefLang": {
|
|
2116
|
+
"type": "string | undefined",
|
|
2117
|
+
"required": false,
|
|
2118
|
+
"origin": "aria",
|
|
2119
|
+
"description": "Hints at the human language of the linked URL.\nSee[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#hreflang)."
|
|
2120
|
+
},
|
|
2121
|
+
"target": {
|
|
2122
|
+
"type": "HTMLAttributeAnchorTarget | undefined",
|
|
2123
|
+
"required": false,
|
|
2124
|
+
"origin": "aria",
|
|
2125
|
+
"description": "The target window for the link. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target)."
|
|
2126
|
+
},
|
|
2127
|
+
"rel": {
|
|
2128
|
+
"type": "string | undefined",
|
|
2129
|
+
"required": false,
|
|
2130
|
+
"origin": "aria",
|
|
2131
|
+
"description": "The relationship between the linked resource and the current page. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel)."
|
|
2132
|
+
},
|
|
2133
|
+
"download": {
|
|
2134
|
+
"type": "string | boolean | undefined",
|
|
2135
|
+
"required": false,
|
|
2136
|
+
"origin": "aria",
|
|
2137
|
+
"description": "Causes the browser to download the linked URL. A string may be provided to suggest a file name.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download)."
|
|
2138
|
+
},
|
|
2139
|
+
"ping": {
|
|
2140
|
+
"type": "string | undefined",
|
|
2141
|
+
"required": false,
|
|
2142
|
+
"origin": "aria",
|
|
2143
|
+
"description": "A space-separated list of URLs to ping when the link is followed. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#ping)."
|
|
2144
|
+
},
|
|
2145
|
+
"referrerPolicy": {
|
|
2146
|
+
"type": "HTMLAttributeReferrerPolicy | undefined",
|
|
2147
|
+
"required": false,
|
|
2148
|
+
"origin": "aria",
|
|
2149
|
+
"description": "How much of the referrer to send when following the link. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#referrerpolicy).",
|
|
2150
|
+
"values": [
|
|
2151
|
+
"",
|
|
2152
|
+
"origin",
|
|
2153
|
+
"no-referrer",
|
|
2154
|
+
"no-referrer-when-downgrade",
|
|
2155
|
+
"origin-when-cross-origin",
|
|
2156
|
+
"same-origin",
|
|
2157
|
+
"strict-origin",
|
|
2158
|
+
"strict-origin-when-cross-origin",
|
|
2159
|
+
"unsafe-url"
|
|
2160
|
+
]
|
|
2161
|
+
},
|
|
2162
|
+
"routerOptions": {
|
|
2163
|
+
"type": "undefined",
|
|
2164
|
+
"required": false,
|
|
2165
|
+
"origin": "aria",
|
|
2166
|
+
"description": "Options for the configured client side router."
|
|
2167
|
+
},
|
|
2168
|
+
"aria-label": {
|
|
2169
|
+
"type": "string | undefined",
|
|
2170
|
+
"required": false,
|
|
2171
|
+
"origin": "aria",
|
|
2172
|
+
"description": "Defines a string value that labels the current element."
|
|
2173
|
+
},
|
|
2174
|
+
"aria-labelledby": {
|
|
2175
|
+
"type": "string | undefined",
|
|
2176
|
+
"required": false,
|
|
2177
|
+
"origin": "aria",
|
|
2178
|
+
"description": "Identifies the element (or elements) that labels the current element."
|
|
2179
|
+
},
|
|
2180
|
+
"aria-describedby": {
|
|
2181
|
+
"type": "string | undefined",
|
|
2182
|
+
"required": false,
|
|
2183
|
+
"origin": "aria",
|
|
2184
|
+
"description": "Identifies the element (or elements) that describes the object."
|
|
2185
|
+
},
|
|
2186
|
+
"aria-details": {
|
|
2187
|
+
"type": "string | undefined",
|
|
2188
|
+
"required": false,
|
|
2189
|
+
"origin": "aria",
|
|
2190
|
+
"description": "Identifies the element (or elements) that provide a detailed, extended description for the\nobject."
|
|
2191
|
+
}
|
|
2192
|
+
},
|
|
2193
|
+
"propCounts": {
|
|
2194
|
+
"own": 6,
|
|
2195
|
+
"aria": 26,
|
|
2196
|
+
"dom": 266,
|
|
2197
|
+
"other": 0
|
|
2198
|
+
}
|
|
2199
|
+
},
|
|
2200
|
+
"Logo": {
|
|
2201
|
+
"name": "Logo",
|
|
2202
|
+
"source": "src/components/Logo.tsx",
|
|
2203
|
+
"propsType": "LogoProps",
|
|
2204
|
+
"description": "The full lockup: mark + wordmark, matching Figma's `Logo-Ionbase`\n(52:21369).\n\nFigma also has a `Property=Name` axis — wordmark only, no mark — but both\nof its variants currently render the placeholder text \"raza\" rather than\n\"IonBase\", in an unbound raw colour. That is leftover debug content, not a\nreal asset, so it is not implemented here. Reproducing it would ship a\nstranger's name into a design system; extending `LogoMark` alone already\ncovers \"no wordmark\" for the cases that are real.",
|
|
2205
|
+
"import": "import { Logo } from 'ionbase-ui';",
|
|
2206
|
+
"stylesheet": "src/styles/logo.css",
|
|
2207
|
+
"tokens": [
|
|
2208
|
+
"--font-family-sans",
|
|
2209
|
+
"--font-weight-medium",
|
|
2210
|
+
"--icon-default",
|
|
2211
|
+
"--spacing-4",
|
|
2212
|
+
"--spacing-8",
|
|
2213
|
+
"--text-tertiary",
|
|
2214
|
+
"--type-body",
|
|
2215
|
+
"--type-body-line-height"
|
|
2216
|
+
],
|
|
2217
|
+
"props": {
|
|
2218
|
+
"size": {
|
|
2219
|
+
"type": "LogoSize | undefined",
|
|
2220
|
+
"required": false,
|
|
2221
|
+
"origin": "own",
|
|
2222
|
+
"description": "Matches Figma's `Size` variant: Small (24px mark) or Large (32px).",
|
|
2223
|
+
"values": [
|
|
2224
|
+
"sm",
|
|
2225
|
+
"lg"
|
|
2226
|
+
]
|
|
2227
|
+
},
|
|
2228
|
+
"wordmark": {
|
|
2229
|
+
"type": "LogoWordmark | undefined",
|
|
2230
|
+
"required": false,
|
|
2231
|
+
"origin": "own",
|
|
2232
|
+
"description": "Matches Figma's `Type` variant. `vector` is the serif logotype Figma\ncalls \"Logo\" — what `Header` uses, immune to font substitution and\nvisually distinct from the sans-serif UI type everywhere else. `text` is\nwhat Figma calls \"Icon\": a live `Host Grotesk` run, real and selectable,\nat `text/tertiary` rather than the mark's `icon/default`.",
|
|
2233
|
+
"values": [
|
|
2234
|
+
"text",
|
|
2235
|
+
"vector"
|
|
2236
|
+
]
|
|
2237
|
+
}
|
|
2238
|
+
},
|
|
2239
|
+
"propCounts": {
|
|
2240
|
+
"own": 2,
|
|
2241
|
+
"aria": 0,
|
|
2242
|
+
"dom": 278,
|
|
2243
|
+
"other": 0
|
|
2244
|
+
}
|
|
2245
|
+
},
|
|
2246
|
+
"LogoMark": {
|
|
2247
|
+
"name": "LogoMark",
|
|
2248
|
+
"source": "src/components/Logo.tsx",
|
|
2249
|
+
"propsType": "LogoMarkProps",
|
|
2250
|
+
"description": "The bare icon glyph, no wordmark — what `Header` actually uses.\n\nColour comes from the `.ion-logo__mark` class (`icon/default`), not the SVG\nitself, so it themes the same way every other icon in the system does.",
|
|
2251
|
+
"import": "import { LogoMark } from 'ionbase-ui';",
|
|
2252
|
+
"stylesheet": "src/styles/logo.css",
|
|
2253
|
+
"tokens": [
|
|
2254
|
+
"--font-family-sans",
|
|
2255
|
+
"--font-weight-medium",
|
|
2256
|
+
"--icon-default",
|
|
2257
|
+
"--spacing-4",
|
|
2258
|
+
"--spacing-8",
|
|
2259
|
+
"--text-tertiary",
|
|
2260
|
+
"--type-body",
|
|
2261
|
+
"--type-body-line-height"
|
|
2262
|
+
],
|
|
2263
|
+
"props": {
|
|
2264
|
+
"size": {
|
|
2265
|
+
"type": "LogoSize | undefined",
|
|
2266
|
+
"required": false,
|
|
2267
|
+
"origin": "own",
|
|
2268
|
+
"values": [
|
|
2269
|
+
"sm",
|
|
2270
|
+
"lg"
|
|
2271
|
+
]
|
|
2272
|
+
},
|
|
2273
|
+
"label": {
|
|
2274
|
+
"type": "string | undefined",
|
|
2275
|
+
"required": false,
|
|
2276
|
+
"origin": "own",
|
|
2277
|
+
"description": "Accessible name for the mark used standalone. Omit when it sits beside\na visible wordmark, which already carries the name."
|
|
2278
|
+
}
|
|
2279
|
+
},
|
|
2280
|
+
"propCounts": {
|
|
2281
|
+
"own": 2,
|
|
2282
|
+
"aria": 0,
|
|
2283
|
+
"dom": 487,
|
|
2284
|
+
"other": 0
|
|
2285
|
+
}
|
|
2286
|
+
},
|
|
2287
|
+
"Menu": {
|
|
2288
|
+
"name": "Menu",
|
|
2289
|
+
"source": "src/components/Menu.tsx",
|
|
2290
|
+
"propsType": "MenuProps",
|
|
2291
|
+
"description": "Menu is the list surface, not a popover.\n\nFigma models the list alone — there is no trigger, anchor or open state in\nthe design — so this renders the surface and nothing else. Positioning it\nagainst a button is the caller's job until Figma has a component that says\nhow. Building a popover here would be inventing design, and it would be the\nhard half to unpick later.\n\n`role=\"menu\"` is deliberately NOT set. A real ARIA menu owes the user\nroving-tabindex arrow navigation, typeahead and focus containment; claiming\nthe role without them is worse for a screen-reader user than an honest list,\nbecause it promises interactions that are not there. When the popover exists,\nthe role comes with it.",
|
|
2292
|
+
"import": "import { Menu } from 'ionbase-ui';",
|
|
2293
|
+
"stylesheet": "src/styles/menu.css",
|
|
2294
|
+
"tokens": [
|
|
2295
|
+
"--border-focus",
|
|
2296
|
+
"--border-subtle",
|
|
2297
|
+
"--border-width-default",
|
|
2298
|
+
"--border-width-thick",
|
|
2299
|
+
"--font-family-sans",
|
|
2300
|
+
"--font-weight-regular",
|
|
2301
|
+
"--icon-default",
|
|
2302
|
+
"--icon-disabled",
|
|
2303
|
+
"--icon-primary",
|
|
2304
|
+
"--icon-size-sm",
|
|
2305
|
+
"--ion-duration-base",
|
|
2306
|
+
"--ion-ease-out",
|
|
2307
|
+
"--radius-sm",
|
|
2308
|
+
"--radius-xl",
|
|
2309
|
+
"--spacing-12",
|
|
2310
|
+
"--spacing-2",
|
|
2311
|
+
"--spacing-40",
|
|
2312
|
+
"--spacing-6",
|
|
2313
|
+
"--spacing-8",
|
|
2314
|
+
"--surface-default",
|
|
2315
|
+
"--surface-hover",
|
|
2316
|
+
"--surface-primary-subtle",
|
|
2317
|
+
"--text-disabled",
|
|
2318
|
+
"--text-primary",
|
|
2319
|
+
"--text-secondary",
|
|
2320
|
+
"--type-body",
|
|
2321
|
+
"--type-body-line-height"
|
|
2322
|
+
],
|
|
2323
|
+
"props": {
|
|
2324
|
+
"children": {
|
|
2325
|
+
"type": "React.ReactNode",
|
|
2326
|
+
"required": false,
|
|
2327
|
+
"origin": "own"
|
|
2328
|
+
}
|
|
2329
|
+
},
|
|
2330
|
+
"propCounts": {
|
|
2331
|
+
"own": 1,
|
|
2332
|
+
"aria": 0,
|
|
2333
|
+
"dom": 277,
|
|
2334
|
+
"other": 0
|
|
2335
|
+
}
|
|
2336
|
+
},
|
|
2337
|
+
"MenuItem": {
|
|
2338
|
+
"name": "MenuItem",
|
|
2339
|
+
"source": "src/components/Menu.tsx",
|
|
2340
|
+
"propsType": "MenuItemProps",
|
|
2341
|
+
"import": "import { MenuItem } from 'ionbase-ui';",
|
|
2342
|
+
"stylesheet": "src/styles/menu.css",
|
|
2343
|
+
"tokens": [
|
|
2344
|
+
"--border-focus",
|
|
2345
|
+
"--border-subtle",
|
|
2346
|
+
"--border-width-default",
|
|
2347
|
+
"--border-width-thick",
|
|
2348
|
+
"--font-family-sans",
|
|
2349
|
+
"--font-weight-regular",
|
|
2350
|
+
"--icon-default",
|
|
2351
|
+
"--icon-disabled",
|
|
2352
|
+
"--icon-primary",
|
|
2353
|
+
"--icon-size-sm",
|
|
2354
|
+
"--ion-duration-base",
|
|
2355
|
+
"--ion-ease-out",
|
|
2356
|
+
"--radius-sm",
|
|
2357
|
+
"--radius-xl",
|
|
2358
|
+
"--spacing-12",
|
|
2359
|
+
"--spacing-2",
|
|
2360
|
+
"--spacing-40",
|
|
2361
|
+
"--spacing-6",
|
|
2362
|
+
"--spacing-8",
|
|
2363
|
+
"--surface-default",
|
|
2364
|
+
"--surface-hover",
|
|
2365
|
+
"--surface-primary-subtle",
|
|
2366
|
+
"--text-disabled",
|
|
2367
|
+
"--text-primary",
|
|
2368
|
+
"--text-secondary",
|
|
2369
|
+
"--type-body",
|
|
2370
|
+
"--type-body-line-height"
|
|
2371
|
+
],
|
|
2372
|
+
"props": {
|
|
2373
|
+
"isSelected": {
|
|
2374
|
+
"type": "boolean | undefined",
|
|
2375
|
+
"required": false,
|
|
2376
|
+
"origin": "own",
|
|
2377
|
+
"description": "Figma's `Selected` / `Selected-hover` states. Shows the trailing check."
|
|
2378
|
+
},
|
|
2379
|
+
"icon": {
|
|
2380
|
+
"type": "React.ReactNode",
|
|
2381
|
+
"required": false,
|
|
2382
|
+
"origin": "own",
|
|
2383
|
+
"description": "Figma's `Show Leading Icon` + `Leading Icon` swap."
|
|
2384
|
+
},
|
|
2385
|
+
"isDisabled": {
|
|
2386
|
+
"type": "boolean | undefined",
|
|
2387
|
+
"required": false,
|
|
2388
|
+
"origin": "own",
|
|
2389
|
+
"description": "Whether the item is disabled."
|
|
2390
|
+
},
|
|
2391
|
+
"disabled": {
|
|
2392
|
+
"type": "boolean | undefined",
|
|
2393
|
+
"required": false,
|
|
2394
|
+
"origin": "own",
|
|
2395
|
+
"tags": {
|
|
2396
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
2397
|
+
}
|
|
2398
|
+
},
|
|
2399
|
+
"children": {
|
|
2400
|
+
"type": "React.ReactNode",
|
|
2401
|
+
"required": false,
|
|
2402
|
+
"origin": "own"
|
|
2403
|
+
}
|
|
2404
|
+
},
|
|
2405
|
+
"propCounts": {
|
|
2406
|
+
"own": 5,
|
|
2407
|
+
"aria": 0,
|
|
2408
|
+
"dom": 285,
|
|
2409
|
+
"other": 0
|
|
2410
|
+
}
|
|
2411
|
+
},
|
|
2412
|
+
"Modal": {
|
|
2413
|
+
"name": "Modal",
|
|
2414
|
+
"source": "src/components/Modal.tsx",
|
|
2415
|
+
"propsType": "ModalProps",
|
|
2416
|
+
"description": "Modal — Figma `Modal` (792:1537).\n\n`Size` x `Align`, with the sections as props rather than variants. The panel\nhugs its content at every size except `fullscreen`, which fills the viewport\nand pushes the actions to the bottom edge.\n\nRENDERS NOTHING WHEN CLOSED, and mounts into a portal when open. Both come\nfrom React Aria's `Overlay`, and both matter: a modal left in the tree while\nclosed is still focusable by keyboard, and one rendered inline inherits any\n`overflow: hidden` or stacking context from wherever it was written.\n\nThe scrim is part of this component in code, unlike in Figma — see the note\nin modal.css.",
|
|
2417
|
+
"import": "import { Modal } from 'ionbase-ui';",
|
|
2418
|
+
"status": "stable",
|
|
2419
|
+
"since": "0.11.0",
|
|
2420
|
+
"summary": "A focus-trapping dialog. Renders nothing when closed and portals when open.",
|
|
2421
|
+
"useWhen": [
|
|
2422
|
+
"the task must be completed or abandoned before anything else",
|
|
2423
|
+
"confirming a destructive action",
|
|
2424
|
+
"a short focused form that would otherwise need its own page"
|
|
2425
|
+
],
|
|
2426
|
+
"useInstead": [
|
|
2427
|
+
{
|
|
2428
|
+
"when": "the content is supplementary and the page stays usable",
|
|
2429
|
+
"use": "Popover",
|
|
2430
|
+
"why": "a Popover does not trap focus or block the page"
|
|
2431
|
+
},
|
|
2432
|
+
{
|
|
2433
|
+
"when": "it is a short label for a control",
|
|
2434
|
+
"use": "Tooltip"
|
|
2435
|
+
}
|
|
2436
|
+
],
|
|
2437
|
+
"variants": {
|
|
2438
|
+
"size": {
|
|
2439
|
+
"sm": {
|
|
2440
|
+
"use": "confirmations and single-question prompts"
|
|
2441
|
+
},
|
|
2442
|
+
"md": {
|
|
2443
|
+
"use": "the default; short forms"
|
|
2444
|
+
},
|
|
2445
|
+
"lg": {
|
|
2446
|
+
"use": "multi-section forms"
|
|
2447
|
+
},
|
|
2448
|
+
"fullscreen": {
|
|
2449
|
+
"use": "immersive tasks; fills the viewport and pins the actions to the bottom edge"
|
|
2450
|
+
}
|
|
2451
|
+
},
|
|
2452
|
+
"align": {
|
|
2453
|
+
"left": {
|
|
2454
|
+
"use": "the default; forms and anything the user reads"
|
|
2455
|
+
},
|
|
2456
|
+
"center": {
|
|
2457
|
+
"use": "single-message confirmations only"
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
},
|
|
2461
|
+
"slots": {
|
|
2462
|
+
"footer": {
|
|
2463
|
+
"accepts": "Button",
|
|
2464
|
+
"note": "the primary action goes last, at the trailing edge"
|
|
2465
|
+
},
|
|
2466
|
+
"media": {
|
|
2467
|
+
"note": "rendered above the title"
|
|
2468
|
+
}
|
|
2469
|
+
},
|
|
2470
|
+
"a11y": {
|
|
2471
|
+
"role": "dialog",
|
|
2472
|
+
"guarantees": [
|
|
2473
|
+
"focus moves into the panel on open and returns to the trigger on close",
|
|
2474
|
+
"Escape and a scrim click both close it",
|
|
2475
|
+
"focus is trapped while open",
|
|
2476
|
+
"nothing is rendered at all while closed, so no closed-modal content is keyboard reachable"
|
|
2477
|
+
],
|
|
2478
|
+
"requires": [
|
|
2479
|
+
"`title`, which provides the dialog's accessible name"
|
|
2480
|
+
]
|
|
2481
|
+
},
|
|
2482
|
+
"antiPatterns": [
|
|
2483
|
+
{
|
|
2484
|
+
"dont": "rendering <Modal> only when a state flag is true",
|
|
2485
|
+
"do": "render it always and drive `isOpen`",
|
|
2486
|
+
"why": "Modal already renders nothing when closed. Wrapping it in a conditional discards the open/close transition and the focus-return behaviour."
|
|
2487
|
+
},
|
|
2488
|
+
{
|
|
2489
|
+
"dont": "opening a Modal from inside another Modal",
|
|
2490
|
+
"why": "two focus traps compete and Escape becomes ambiguous"
|
|
2491
|
+
},
|
|
2492
|
+
{
|
|
2493
|
+
"dont": "a destructive action as the only button, with no cancel",
|
|
2494
|
+
"why": "a confirmation with no way out is not a confirmation"
|
|
2495
|
+
}
|
|
2496
|
+
],
|
|
2497
|
+
"stylesheet": "src/styles/modal.css",
|
|
2498
|
+
"tokens": [
|
|
2499
|
+
"--border-subtle",
|
|
2500
|
+
"--border-width-default",
|
|
2501
|
+
"--border-width-thick",
|
|
2502
|
+
"--font-family-sans",
|
|
2503
|
+
"--font-weight-regular",
|
|
2504
|
+
"--font-weight-semibold",
|
|
2505
|
+
"--icon-primary",
|
|
2506
|
+
"--icon-secondary",
|
|
2507
|
+
"--icon-size-lg",
|
|
2508
|
+
"--icon-size-md",
|
|
2509
|
+
"--ion-duration-base",
|
|
2510
|
+
"--ion-ease-out",
|
|
2511
|
+
"--ion-modal-width",
|
|
2512
|
+
"--ion-shadow-shadow-xl",
|
|
2513
|
+
"--radius-full",
|
|
2514
|
+
"--radius-sm",
|
|
2515
|
+
"--radius-xl",
|
|
2516
|
+
"--ring-focus",
|
|
2517
|
+
"--spacing-12",
|
|
2518
|
+
"--spacing-16",
|
|
2519
|
+
"--spacing-20",
|
|
2520
|
+
"--spacing-24",
|
|
2521
|
+
"--spacing-32",
|
|
2522
|
+
"--spacing-48",
|
|
2523
|
+
"--spacing-8",
|
|
2524
|
+
"--surface-hover",
|
|
2525
|
+
"--surface-overlay",
|
|
2526
|
+
"--surface-primary-subtle",
|
|
2527
|
+
"--surface-scrim",
|
|
2528
|
+
"--text-default",
|
|
2529
|
+
"--text-secondary",
|
|
2530
|
+
"--type-body",
|
|
2531
|
+
"--type-body-line-height",
|
|
2532
|
+
"--type-h5",
|
|
2533
|
+
"--type-h5-line-height"
|
|
2534
|
+
],
|
|
2535
|
+
"props": {
|
|
2536
|
+
"isOpen": {
|
|
2537
|
+
"type": "boolean | undefined",
|
|
2538
|
+
"required": false,
|
|
2539
|
+
"origin": "own",
|
|
2540
|
+
"description": "Whether the modal is shown."
|
|
2541
|
+
},
|
|
2542
|
+
"onOpenChange": {
|
|
2543
|
+
"type": "((isOpen: boolean) => void) | undefined",
|
|
2544
|
+
"required": false,
|
|
2545
|
+
"origin": "own",
|
|
2546
|
+
"description": "Called with the next open state — `false` when the modal asks to close."
|
|
2547
|
+
},
|
|
2548
|
+
"size": {
|
|
2549
|
+
"type": "ModalSize | undefined",
|
|
2550
|
+
"required": false,
|
|
2551
|
+
"origin": "own",
|
|
2552
|
+
"description": "Matches the Figma `Size` variant.",
|
|
2553
|
+
"values": [
|
|
2554
|
+
"sm",
|
|
2555
|
+
"md",
|
|
2556
|
+
"lg",
|
|
2557
|
+
"fullscreen"
|
|
2558
|
+
],
|
|
2559
|
+
"default": "md"
|
|
2560
|
+
},
|
|
2561
|
+
"align": {
|
|
2562
|
+
"type": "ModalAlign | undefined",
|
|
2563
|
+
"required": false,
|
|
2564
|
+
"origin": "own",
|
|
2565
|
+
"description": "Matches the Figma `Align` variant.",
|
|
2566
|
+
"values": [
|
|
2567
|
+
"left",
|
|
2568
|
+
"center"
|
|
2569
|
+
],
|
|
2570
|
+
"default": "left"
|
|
2571
|
+
},
|
|
2572
|
+
"title": {
|
|
2573
|
+
"type": "React.ReactNode",
|
|
2574
|
+
"required": true,
|
|
2575
|
+
"origin": "own",
|
|
2576
|
+
"description": "Required: the dialog's accessible name, wired via `aria-labelledby`."
|
|
2577
|
+
},
|
|
2578
|
+
"description": {
|
|
2579
|
+
"type": "React.ReactNode",
|
|
2580
|
+
"required": false,
|
|
2581
|
+
"origin": "own",
|
|
2582
|
+
"description": "Supporting copy under the title."
|
|
2583
|
+
},
|
|
2584
|
+
"media": {
|
|
2585
|
+
"type": "React.ReactNode",
|
|
2586
|
+
"required": false,
|
|
2587
|
+
"origin": "own",
|
|
2588
|
+
"description": "The featured slot above the title — an icon or an illustration. Rendered\ninside a circular container that hugs it."
|
|
2589
|
+
},
|
|
2590
|
+
"footer": {
|
|
2591
|
+
"type": "React.ReactNode",
|
|
2592
|
+
"required": false,
|
|
2593
|
+
"origin": "own",
|
|
2594
|
+
"description": "Action row. Right-aligned when `align=\"left\"`, centred when `\"center\"`."
|
|
2595
|
+
},
|
|
2596
|
+
"showClose": {
|
|
2597
|
+
"type": "boolean | undefined",
|
|
2598
|
+
"required": false,
|
|
2599
|
+
"origin": "own",
|
|
2600
|
+
"description": "Show the close button. Defaults to `true`.",
|
|
2601
|
+
"default": true
|
|
2602
|
+
},
|
|
2603
|
+
"closeLabel": {
|
|
2604
|
+
"type": "string | undefined",
|
|
2605
|
+
"required": false,
|
|
2606
|
+
"origin": "own",
|
|
2607
|
+
"description": "Accessible name for the close button.",
|
|
2608
|
+
"default": "Close dialog"
|
|
2609
|
+
},
|
|
2610
|
+
"children": {
|
|
2611
|
+
"type": "React.ReactNode",
|
|
2612
|
+
"required": false,
|
|
2613
|
+
"origin": "own",
|
|
2614
|
+
"description": "Body content."
|
|
2615
|
+
},
|
|
2616
|
+
"className": {
|
|
2617
|
+
"type": "string | undefined",
|
|
2618
|
+
"required": false,
|
|
2619
|
+
"origin": "own"
|
|
2620
|
+
},
|
|
2621
|
+
"isDismissable": {
|
|
2622
|
+
"type": "boolean | undefined",
|
|
2623
|
+
"required": false,
|
|
2624
|
+
"origin": "aria",
|
|
2625
|
+
"description": "Whether to close the modal when the user interacts outside it.",
|
|
2626
|
+
"tags": {
|
|
2627
|
+
"default": "false"
|
|
2628
|
+
}
|
|
2629
|
+
},
|
|
2630
|
+
"isKeyboardDismissDisabled": {
|
|
2631
|
+
"type": "boolean | undefined",
|
|
2632
|
+
"required": false,
|
|
2633
|
+
"origin": "aria",
|
|
2634
|
+
"description": "Whether pressing the escape key to close the modal should be disabled.",
|
|
2635
|
+
"tags": {
|
|
2636
|
+
"default": "false"
|
|
2637
|
+
}
|
|
2638
|
+
},
|
|
2639
|
+
"shouldCloseOnInteractOutside": {
|
|
2640
|
+
"type": "((element: Element) => boolean) | undefined",
|
|
2641
|
+
"required": false,
|
|
2642
|
+
"origin": "aria",
|
|
2643
|
+
"description": "When user interacts with the argument element outside of the overlay ref,\nreturn true if onClose should be called. This gives you a chance to filter\nout interaction with elements that should not dismiss the overlay.\nBy default, onClose will always be called on interaction outside the overlay ref."
|
|
2644
|
+
}
|
|
2645
|
+
},
|
|
2646
|
+
"propCounts": {
|
|
2647
|
+
"own": 12,
|
|
2648
|
+
"aria": 3,
|
|
2649
|
+
"dom": 0,
|
|
2650
|
+
"other": 0
|
|
2651
|
+
}
|
|
2652
|
+
},
|
|
2653
|
+
"NavItem": {
|
|
2654
|
+
"name": "NavItem",
|
|
2655
|
+
"source": "src/components/NavItem.tsx",
|
|
2656
|
+
"propsType": "NavItemProps",
|
|
2657
|
+
"description": "Nav Item renders an `<a>` when given `href`, a `<button>` otherwise —\nchosen by what the caller is actually building, the same judgment call\nMenu and Select make. A primary nav bar is links; a nav item with\n`showChevron` that opens a menu (no `href` of its own) is a button.\n\nInteraction state comes from React Aria rather than CSS pseudo-classes,\nmatching Button: `useHover` is pointer-aware so a tap does not stay\n\"hovered\" until the next tap elsewhere, and `useFocusRing` shows the ring\nonly for keyboard navigation. The CSS keeps its own `:hover` /\n`:focus-visible` rules so the stylesheet still works without React.",
|
|
2658
|
+
"import": "import { NavItem } from 'ionbase-ui';",
|
|
2659
|
+
"stylesheet": "src/styles/nav-item.css",
|
|
2660
|
+
"tokens": [
|
|
2661
|
+
"--border-focus",
|
|
2662
|
+
"--border-width-thick",
|
|
2663
|
+
"--font-family-sans",
|
|
2664
|
+
"--font-weight-regular",
|
|
2665
|
+
"--icon-disabled",
|
|
2666
|
+
"--icon-interactive-hover",
|
|
2667
|
+
"--icon-size-sm",
|
|
2668
|
+
"--icon-tertiary",
|
|
2669
|
+
"--ion-duration-base",
|
|
2670
|
+
"--ion-ease-out",
|
|
2671
|
+
"--radius-sm",
|
|
2672
|
+
"--spacing-4",
|
|
2673
|
+
"--spacing-8",
|
|
2674
|
+
"--text-disabled",
|
|
2675
|
+
"--text-interactive-hover",
|
|
2676
|
+
"--text-secondary",
|
|
2677
|
+
"--type-body-sm",
|
|
2678
|
+
"--type-body-sm-line-height"
|
|
2679
|
+
],
|
|
2680
|
+
"props": {
|
|
2681
|
+
"icon": {
|
|
2682
|
+
"type": "React.ReactNode",
|
|
2683
|
+
"required": false,
|
|
2684
|
+
"origin": "own",
|
|
2685
|
+
"description": "Figma's `Icon` slot — an optional leading icon."
|
|
2686
|
+
},
|
|
2687
|
+
"showChevron": {
|
|
2688
|
+
"type": "boolean | undefined",
|
|
2689
|
+
"required": false,
|
|
2690
|
+
"origin": "own",
|
|
2691
|
+
"description": "Figma's `Show Chevron`. Set on a nav item that opens a menu, not a plain link."
|
|
2692
|
+
},
|
|
2693
|
+
"isDisabled": {
|
|
2694
|
+
"type": "boolean | undefined",
|
|
2695
|
+
"required": false,
|
|
2696
|
+
"origin": "own"
|
|
2697
|
+
},
|
|
2698
|
+
"disabled": {
|
|
2699
|
+
"type": "boolean | undefined",
|
|
2700
|
+
"required": false,
|
|
2701
|
+
"origin": "own",
|
|
2702
|
+
"tags": {
|
|
2703
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
2704
|
+
}
|
|
2705
|
+
},
|
|
2706
|
+
"children": {
|
|
2707
|
+
"type": "React.ReactNode",
|
|
2708
|
+
"required": false,
|
|
2709
|
+
"origin": "own"
|
|
2710
|
+
},
|
|
2711
|
+
"className": {
|
|
2712
|
+
"type": "string | undefined",
|
|
2713
|
+
"required": false,
|
|
2714
|
+
"origin": "own"
|
|
2715
|
+
},
|
|
2716
|
+
"href": {
|
|
2717
|
+
"type": "string | undefined",
|
|
2718
|
+
"required": false,
|
|
2719
|
+
"origin": "own"
|
|
2720
|
+
}
|
|
2721
|
+
},
|
|
2722
|
+
"propCounts": {
|
|
2723
|
+
"own": 7,
|
|
2724
|
+
"aria": 0,
|
|
2725
|
+
"dom": 276,
|
|
2726
|
+
"other": 0
|
|
2727
|
+
}
|
|
2728
|
+
},
|
|
2729
|
+
"PhoneInput": {
|
|
2730
|
+
"name": "PhoneInput",
|
|
2731
|
+
"source": "src/components/PhoneInput.tsx",
|
|
2732
|
+
"propsType": "PhoneInputProps",
|
|
2733
|
+
"description": "PhoneInput — Figma `Input/Phone` (80:372).\n\nA dial-code block butted against an Input, sharing one outline: the block\ncarries the left radii and the control the right, so the seam is square on\nboth sides and reads as a single control. Both keep their full 1px border,\nwhich is what Figma draws — the 2px seam is the two strokes meeting, not an\naccident.\n\nThree sizes, no State axis. Every interaction state is the Input's, reached\nthrough the ordinary props, because Figma composes this from the same `Input`\ninstance rather than redrawing it.\n\nWHAT THIS DELIBERATELY DOES NOT DO\n\nIt does not pick countries. The chevron implies a menu and Figma specifies no\nopen state for it — no list, no flags, no search, no selected state. Country\ndata and the picker are application concerns with real editorial weight (which\nterritories, which names, which order), and inventing them here would be\ndesigning rather than implementing.\n\nSo the trigger is a real `<button>` with an accessible name, and\n`countryButtonProps` is how you wire it to a `Menu`, a popover or your own\nlistbox — including the `aria-haspopup` and `aria-expanded` that only the\nthing owning the popup can set honestly.",
|
|
2734
|
+
"import": "import { PhoneInput } from 'ionbase-ui';",
|
|
2735
|
+
"stylesheet": "src/styles/phone-input.css",
|
|
2736
|
+
"tokens": [
|
|
2737
|
+
"--border-default",
|
|
2738
|
+
"--border-disabled",
|
|
2739
|
+
"--border-focus",
|
|
2740
|
+
"--border-strong",
|
|
2741
|
+
"--border-width-default",
|
|
2742
|
+
"--border-width-thick",
|
|
2743
|
+
"--font-family-sans",
|
|
2744
|
+
"--font-weight-regular",
|
|
2745
|
+
"--icon-disabled",
|
|
2746
|
+
"--icon-size-md",
|
|
2747
|
+
"--icon-size-sm",
|
|
2748
|
+
"--icon-tertiary",
|
|
2749
|
+
"--ion-duration-base",
|
|
2750
|
+
"--ion-ease-out",
|
|
2751
|
+
"--ion-phone-input-border-width",
|
|
2752
|
+
"--ion-phone-input-font-size",
|
|
2753
|
+
"--ion-phone-input-gap",
|
|
2754
|
+
"--ion-phone-input-icon-size",
|
|
2755
|
+
"--ion-phone-input-line-height",
|
|
2756
|
+
"--ion-phone-input-padding-x",
|
|
2757
|
+
"--ion-phone-input-radius",
|
|
2758
|
+
"--radius-md",
|
|
2759
|
+
"--radius-sm",
|
|
2760
|
+
"--spacing-12",
|
|
2761
|
+
"--spacing-16",
|
|
2762
|
+
"--spacing-4",
|
|
2763
|
+
"--surface-disabled",
|
|
2764
|
+
"--surface-page",
|
|
2765
|
+
"--text-disabled",
|
|
2766
|
+
"--text-secondary",
|
|
2767
|
+
"--type-body",
|
|
2768
|
+
"--type-body-line-height",
|
|
2769
|
+
"--type-body-sm",
|
|
2770
|
+
"--type-body-sm-line-height"
|
|
2771
|
+
],
|
|
2772
|
+
"props": {
|
|
2773
|
+
"dialCode": {
|
|
2774
|
+
"type": "string | undefined",
|
|
2775
|
+
"required": false,
|
|
2776
|
+
"origin": "own",
|
|
2777
|
+
"description": "The dial code shown in the leading block, e.g. `+1`.",
|
|
2778
|
+
"default": "+1"
|
|
2779
|
+
},
|
|
2780
|
+
"countryLabel": {
|
|
2781
|
+
"type": "string | undefined",
|
|
2782
|
+
"required": false,
|
|
2783
|
+
"origin": "own",
|
|
2784
|
+
"description": "Accessible name for the dial-code trigger. It shows only `+1`, which names\na value rather than an action, so the button needs a label of its own.",
|
|
2785
|
+
"default": "Select country calling code"
|
|
2786
|
+
},
|
|
2787
|
+
"countryButtonProps": {
|
|
2788
|
+
"type": "React.ButtonHTMLAttributes<HTMLButtonElement> | undefined",
|
|
2789
|
+
"required": false,
|
|
2790
|
+
"origin": "own",
|
|
2791
|
+
"description": "Spread onto the dial-code `<button>`. This is how a country picker gets\nattached — see the note on scope below."
|
|
2792
|
+
},
|
|
2793
|
+
"defaultValue": {
|
|
2794
|
+
"type": "string | undefined",
|
|
2795
|
+
"required": false,
|
|
2796
|
+
"origin": "aria",
|
|
2797
|
+
"description": "The default value (uncontrolled)."
|
|
2798
|
+
},
|
|
2799
|
+
"autoCapitalize": {
|
|
2800
|
+
"type": "\"none\" | \"off\" | \"on\" | \"sentences\" | \"words\" | \"characters\" | undefined",
|
|
2801
|
+
"required": false,
|
|
2802
|
+
"origin": "own",
|
|
2803
|
+
"description": "Narrower than React's own typing, which also allows any `string`.\n`autoCapitalize` is declared on `AriaTextFieldOptions` rather than\n`AriaTextFieldProps`, so `keyof AriaTextFieldProps` above cannot omit it —\nand the wide DOM version does not satisfy what `useTextField` accepts.",
|
|
2804
|
+
"values": [
|
|
2805
|
+
"none",
|
|
2806
|
+
"off",
|
|
2807
|
+
"on",
|
|
2808
|
+
"sentences",
|
|
2809
|
+
"words",
|
|
2810
|
+
"characters"
|
|
2811
|
+
]
|
|
2812
|
+
},
|
|
2813
|
+
"autoFocus": {
|
|
2814
|
+
"type": "boolean | undefined",
|
|
2815
|
+
"required": false,
|
|
2816
|
+
"origin": "aria",
|
|
2817
|
+
"description": "Whether the element should receive focus on render."
|
|
2818
|
+
},
|
|
2819
|
+
"className": {
|
|
2820
|
+
"type": "string | undefined",
|
|
2821
|
+
"required": false,
|
|
2822
|
+
"origin": "own",
|
|
2823
|
+
"description": "Class names for the control box (`.ion-input`). Always lands here —\nnever on the form-field wrapper. Use `wrapperClassName` for that."
|
|
2824
|
+
},
|
|
2825
|
+
"enterKeyHint": {
|
|
2826
|
+
"type": "\"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
|
|
2827
|
+
"required": false,
|
|
2828
|
+
"origin": "aria",
|
|
2829
|
+
"description": "An enumerated attribute that defines what action label or icon to preset for the enter key on\nvirtual keyboards. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint).",
|
|
2830
|
+
"values": [
|
|
2831
|
+
"enter",
|
|
2832
|
+
"done",
|
|
2833
|
+
"go",
|
|
2834
|
+
"next",
|
|
2835
|
+
"previous",
|
|
2836
|
+
"search",
|
|
2837
|
+
"send"
|
|
2838
|
+
]
|
|
2839
|
+
},
|
|
2840
|
+
"id": {
|
|
2841
|
+
"type": "string | undefined",
|
|
2842
|
+
"required": false,
|
|
2843
|
+
"origin": "aria",
|
|
2844
|
+
"description": "The element's unique identifier. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)."
|
|
2845
|
+
},
|
|
2846
|
+
"spellCheck": {
|
|
2847
|
+
"type": "string | undefined",
|
|
2848
|
+
"required": false,
|
|
2849
|
+
"origin": "aria",
|
|
2850
|
+
"description": "An enumerated attribute that defines whether the element may be checked for spelling errors.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck)."
|
|
2851
|
+
},
|
|
2852
|
+
"autoCorrect": {
|
|
2853
|
+
"type": "string | undefined",
|
|
2854
|
+
"required": false,
|
|
2855
|
+
"origin": "aria",
|
|
2856
|
+
"description": "An attribute that takes as its value a space-separated string that describes what, if any, type\nof autocomplete functionality the input should provide. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autocomplete)."
|
|
2857
|
+
},
|
|
2858
|
+
"inputMode": {
|
|
2859
|
+
"type": "\"none\" | \"search\" | \"text\" | \"url\" | \"tel\" | \"email\" | \"numeric\" | \"decimal\" | undefined",
|
|
2860
|
+
"required": false,
|
|
2861
|
+
"origin": "aria",
|
|
2862
|
+
"description": "Hints at the type of data that might be entered by the user while editing the element or its\ncontents. See\n[MDN](https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute).",
|
|
2863
|
+
"values": [
|
|
2864
|
+
"none",
|
|
2865
|
+
"search",
|
|
2866
|
+
"text",
|
|
2867
|
+
"url",
|
|
2868
|
+
"tel",
|
|
2869
|
+
"email",
|
|
2870
|
+
"numeric",
|
|
2871
|
+
"decimal"
|
|
2872
|
+
]
|
|
2873
|
+
},
|
|
2874
|
+
"aria-activedescendant": {
|
|
2875
|
+
"type": "string | undefined",
|
|
2876
|
+
"required": false,
|
|
2877
|
+
"origin": "aria",
|
|
2878
|
+
"description": "Identifies the currently active element when DOM focus is on a composite widget, textbox,\ngroup, or application."
|
|
2879
|
+
},
|
|
2880
|
+
"aria-autocomplete": {
|
|
2881
|
+
"type": "\"inline\" | \"list\" | \"none\" | \"both\" | undefined",
|
|
2882
|
+
"required": false,
|
|
2883
|
+
"origin": "aria",
|
|
2884
|
+
"description": "Indicates whether inputting text could trigger display of one or more predictions of the user's\nintended value for an input and specifies how predictions would be presented if they are made.",
|
|
2885
|
+
"values": [
|
|
2886
|
+
"inline",
|
|
2887
|
+
"list",
|
|
2888
|
+
"none",
|
|
2889
|
+
"both"
|
|
2890
|
+
]
|
|
2891
|
+
},
|
|
2892
|
+
"aria-controls": {
|
|
2893
|
+
"type": "string | undefined",
|
|
2894
|
+
"required": false,
|
|
2895
|
+
"origin": "aria",
|
|
2896
|
+
"description": "Identifies the element (or elements) whose contents or presence are controlled by the current\nelement."
|
|
2897
|
+
},
|
|
2898
|
+
"aria-describedby": {
|
|
2899
|
+
"type": "string | undefined",
|
|
2900
|
+
"required": false,
|
|
2901
|
+
"origin": "aria",
|
|
2902
|
+
"description": "Identifies the element (or elements) that describes the object."
|
|
2903
|
+
},
|
|
2904
|
+
"aria-details": {
|
|
2905
|
+
"type": "string | undefined",
|
|
2906
|
+
"required": false,
|
|
2907
|
+
"origin": "aria",
|
|
2908
|
+
"description": "Identifies the element (or elements) that provide a detailed, extended description for the\nobject."
|
|
2909
|
+
},
|
|
2910
|
+
"aria-errormessage": {
|
|
2911
|
+
"type": "string | undefined",
|
|
2912
|
+
"required": false,
|
|
2913
|
+
"origin": "aria",
|
|
2914
|
+
"description": "Identifies the element that provides an error message for the object."
|
|
2915
|
+
},
|
|
2916
|
+
"aria-haspopup": {
|
|
2917
|
+
"type": "boolean | \"true\" | \"false\" | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\" | undefined",
|
|
2918
|
+
"required": false,
|
|
2919
|
+
"origin": "aria",
|
|
2920
|
+
"description": "Indicates the availability and type of interactive popup element, such as menu or dialog, that\ncan be triggered by an element."
|
|
2921
|
+
},
|
|
2922
|
+
"aria-label": {
|
|
2923
|
+
"type": "string | undefined",
|
|
2924
|
+
"required": false,
|
|
2925
|
+
"origin": "aria",
|
|
2926
|
+
"description": "Defines a string value that labels the current element."
|
|
2927
|
+
},
|
|
2928
|
+
"aria-labelledby": {
|
|
2929
|
+
"type": "string | undefined",
|
|
2930
|
+
"required": false,
|
|
2931
|
+
"origin": "aria",
|
|
2932
|
+
"description": "Identifies the element (or elements) that labels the current element."
|
|
2933
|
+
},
|
|
2934
|
+
"onCopy": {
|
|
2935
|
+
"type": "ClipboardEventHandler<HTMLInputElement> | undefined",
|
|
2936
|
+
"required": false,
|
|
2937
|
+
"origin": "aria",
|
|
2938
|
+
"description": "Handler that is called when the user copies text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncopy)."
|
|
2939
|
+
},
|
|
2940
|
+
"onCut": {
|
|
2941
|
+
"type": "ClipboardEventHandler<HTMLInputElement> | undefined",
|
|
2942
|
+
"required": false,
|
|
2943
|
+
"origin": "aria",
|
|
2944
|
+
"description": "Handler that is called when the user cuts text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncut)."
|
|
2945
|
+
},
|
|
2946
|
+
"onPaste": {
|
|
2947
|
+
"type": "ClipboardEventHandler<HTMLInputElement> | undefined",
|
|
2948
|
+
"required": false,
|
|
2949
|
+
"origin": "aria",
|
|
2950
|
+
"description": "Handler that is called when the user pastes text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/onpaste)."
|
|
2951
|
+
},
|
|
2952
|
+
"onCompositionEnd": {
|
|
2953
|
+
"type": "CompositionEventHandler<HTMLInputElement> | undefined",
|
|
2954
|
+
"required": false,
|
|
2955
|
+
"origin": "aria",
|
|
2956
|
+
"description": "Handler that is called when a text composition system completes or cancels the current text\ncomposition session. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionend_event)."
|
|
2957
|
+
},
|
|
2958
|
+
"onCompositionStart": {
|
|
2959
|
+
"type": "CompositionEventHandler<HTMLInputElement> | undefined",
|
|
2960
|
+
"required": false,
|
|
2961
|
+
"origin": "aria",
|
|
2962
|
+
"description": "Handler that is called when a text composition system starts a new text composition session.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event)."
|
|
2963
|
+
},
|
|
2964
|
+
"onCompositionUpdate": {
|
|
2965
|
+
"type": "CompositionEventHandler<HTMLInputElement> | undefined",
|
|
2966
|
+
"required": false,
|
|
2967
|
+
"origin": "aria",
|
|
2968
|
+
"description": "Handler that is called when a new character is received in the current text composition\nsession. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionupdate_event)."
|
|
2969
|
+
},
|
|
2970
|
+
"onFocus": {
|
|
2971
|
+
"type": "((e: FocusEvent<HTMLInputElement, Element>) => void) | undefined",
|
|
2972
|
+
"required": false,
|
|
2973
|
+
"origin": "aria",
|
|
2974
|
+
"description": "Handler that is called when the element receives focus."
|
|
2975
|
+
},
|
|
2976
|
+
"onBlur": {
|
|
2977
|
+
"type": "((e: FocusEvent<HTMLInputElement, Element>) => void) | undefined",
|
|
2978
|
+
"required": false,
|
|
2979
|
+
"origin": "aria",
|
|
2980
|
+
"description": "Handler that is called when the element loses focus."
|
|
2981
|
+
},
|
|
2982
|
+
"onChange": {
|
|
2983
|
+
"type": "((value: string) => void) | undefined",
|
|
2984
|
+
"required": false,
|
|
2985
|
+
"origin": "aria",
|
|
2986
|
+
"description": "Handler that is called when the value changes."
|
|
2987
|
+
},
|
|
2988
|
+
"onBeforeInput": {
|
|
2989
|
+
"type": "FormEventHandler<HTMLInputElement> | undefined",
|
|
2990
|
+
"required": false,
|
|
2991
|
+
"origin": "aria",
|
|
2992
|
+
"description": "Handler that is called when the input value is about to be modified. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/beforeinput_event)."
|
|
2993
|
+
},
|
|
2994
|
+
"onInput": {
|
|
2995
|
+
"type": "FormEventHandler<HTMLInputElement> | undefined",
|
|
2996
|
+
"required": false,
|
|
2997
|
+
"origin": "aria",
|
|
2998
|
+
"description": "Handler that is called when the input value is modified. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event)."
|
|
2999
|
+
},
|
|
3000
|
+
"onKeyDown": {
|
|
3001
|
+
"type": "((e: KeyboardEvent) => void) | undefined",
|
|
3002
|
+
"required": false,
|
|
3003
|
+
"origin": "aria",
|
|
3004
|
+
"description": "Handler that is called when a key is pressed."
|
|
3005
|
+
},
|
|
3006
|
+
"onKeyUp": {
|
|
3007
|
+
"type": "((e: KeyboardEvent) => void) | undefined",
|
|
3008
|
+
"required": false,
|
|
3009
|
+
"origin": "aria",
|
|
3010
|
+
"description": "Handler that is called when a key is released."
|
|
3011
|
+
},
|
|
3012
|
+
"onSelect": {
|
|
3013
|
+
"type": "ReactEventHandler<HTMLInputElement> | undefined",
|
|
3014
|
+
"required": false,
|
|
3015
|
+
"origin": "aria",
|
|
3016
|
+
"description": "Handler that is called when text in the input is selected. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event)."
|
|
3017
|
+
},
|
|
3018
|
+
"size": {
|
|
3019
|
+
"type": "InputSize | undefined",
|
|
3020
|
+
"required": false,
|
|
3021
|
+
"origin": "own",
|
|
3022
|
+
"description": "Matches the Figma `Size` variant: Small, Medium, Large.",
|
|
3023
|
+
"values": [
|
|
3024
|
+
"sm",
|
|
3025
|
+
"md",
|
|
3026
|
+
"lg"
|
|
3027
|
+
],
|
|
3028
|
+
"default": "md"
|
|
3029
|
+
},
|
|
3030
|
+
"type": {
|
|
3031
|
+
"type": "(string & {}) | \"search\" | \"text\" | \"url\" | \"tel\" | \"email\" | \"password\" | undefined",
|
|
3032
|
+
"required": false,
|
|
3033
|
+
"origin": "aria",
|
|
3034
|
+
"description": "The type of input to render. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdeftype).",
|
|
3035
|
+
"tags": {
|
|
3036
|
+
"default": "'text'"
|
|
3037
|
+
},
|
|
3038
|
+
"default": "tel"
|
|
3039
|
+
},
|
|
3040
|
+
"autoComplete": {
|
|
3041
|
+
"type": "string | undefined",
|
|
3042
|
+
"required": false,
|
|
3043
|
+
"origin": "aria",
|
|
3044
|
+
"description": "Describes the type of autocomplete functionality the input should provide if any. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautocomplete)."
|
|
3045
|
+
},
|
|
3046
|
+
"disabled": {
|
|
3047
|
+
"type": "boolean | undefined",
|
|
3048
|
+
"required": false,
|
|
3049
|
+
"origin": "own",
|
|
3050
|
+
"tags": {
|
|
3051
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
3052
|
+
}
|
|
3053
|
+
},
|
|
3054
|
+
"form": {
|
|
3055
|
+
"type": "string | undefined",
|
|
3056
|
+
"required": false,
|
|
3057
|
+
"origin": "aria",
|
|
3058
|
+
"description": "The `<form>` element to associate the input with.\nThe value of this attribute must be the id of a `<form>` in the same document.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#form)."
|
|
3059
|
+
},
|
|
3060
|
+
"maxLength": {
|
|
3061
|
+
"type": "number | undefined",
|
|
3062
|
+
"required": false,
|
|
3063
|
+
"origin": "aria",
|
|
3064
|
+
"description": "The maximum number of characters supported by the input. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefmaxlength)."
|
|
3065
|
+
},
|
|
3066
|
+
"minLength": {
|
|
3067
|
+
"type": "number | undefined",
|
|
3068
|
+
"required": false,
|
|
3069
|
+
"origin": "aria",
|
|
3070
|
+
"description": "The minimum number of characters required by the input. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefminlength)."
|
|
3071
|
+
},
|
|
3072
|
+
"name": {
|
|
3073
|
+
"type": "string | undefined",
|
|
3074
|
+
"required": false,
|
|
3075
|
+
"origin": "aria",
|
|
3076
|
+
"description": "The name of the input element, used when submitting an HTML form. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname)."
|
|
3077
|
+
},
|
|
3078
|
+
"pattern": {
|
|
3079
|
+
"type": "string | undefined",
|
|
3080
|
+
"required": false,
|
|
3081
|
+
"origin": "aria",
|
|
3082
|
+
"description": "Regex pattern that the value of the input must match to be valid. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefpattern)."
|
|
3083
|
+
},
|
|
3084
|
+
"placeholder": {
|
|
3085
|
+
"type": "string | undefined",
|
|
3086
|
+
"required": false,
|
|
3087
|
+
"origin": "aria",
|
|
3088
|
+
"description": "Temporary text that occupies the text input when it is empty."
|
|
3089
|
+
},
|
|
3090
|
+
"value": {
|
|
3091
|
+
"type": "string | undefined",
|
|
3092
|
+
"required": false,
|
|
3093
|
+
"origin": "aria",
|
|
3094
|
+
"description": "The current value (controlled)."
|
|
3095
|
+
},
|
|
3096
|
+
"isDisabled": {
|
|
3097
|
+
"type": "boolean | undefined",
|
|
3098
|
+
"required": false,
|
|
3099
|
+
"origin": "aria",
|
|
3100
|
+
"description": "Whether the input is disabled."
|
|
3101
|
+
},
|
|
3102
|
+
"isReadOnly": {
|
|
3103
|
+
"type": "boolean | undefined",
|
|
3104
|
+
"required": false,
|
|
3105
|
+
"origin": "aria",
|
|
3106
|
+
"description": "Whether the input can be selected but not changed by the user."
|
|
3107
|
+
},
|
|
3108
|
+
"isRequired": {
|
|
3109
|
+
"type": "boolean | undefined",
|
|
3110
|
+
"required": false,
|
|
3111
|
+
"origin": "aria",
|
|
3112
|
+
"description": "Whether user input is required on the input before form submission."
|
|
3113
|
+
},
|
|
3114
|
+
"isInvalid": {
|
|
3115
|
+
"type": "boolean | undefined",
|
|
3116
|
+
"required": false,
|
|
3117
|
+
"origin": "aria",
|
|
3118
|
+
"description": "Whether the input value is invalid."
|
|
3119
|
+
},
|
|
3120
|
+
"validationState": {
|
|
3121
|
+
"type": "ValidationState | undefined",
|
|
3122
|
+
"required": false,
|
|
3123
|
+
"origin": "aria",
|
|
3124
|
+
"values": [
|
|
3125
|
+
"valid",
|
|
3126
|
+
"invalid"
|
|
3127
|
+
],
|
|
3128
|
+
"tags": {
|
|
3129
|
+
"deprecated": "Use `isInvalid` instead."
|
|
3130
|
+
}
|
|
3131
|
+
},
|
|
3132
|
+
"validationBehavior": {
|
|
3133
|
+
"type": "\"aria\" | \"native\" | undefined",
|
|
3134
|
+
"required": false,
|
|
3135
|
+
"origin": "aria",
|
|
3136
|
+
"description": "Whether to use native HTML form validation to prevent form submission\nwhen the value is missing or invalid, or mark the field as required\nor invalid via ARIA.",
|
|
3137
|
+
"values": [
|
|
3138
|
+
"aria",
|
|
3139
|
+
"native"
|
|
3140
|
+
],
|
|
3141
|
+
"tags": {
|
|
3142
|
+
"default": "'aria'"
|
|
3143
|
+
}
|
|
3144
|
+
},
|
|
3145
|
+
"validate": {
|
|
3146
|
+
"type": "((value: string) => ValidationError | true | null | undefined) | undefined",
|
|
3147
|
+
"required": false,
|
|
3148
|
+
"origin": "aria",
|
|
3149
|
+
"description": "A function that returns an error message if a given value is invalid.\nValidation errors are displayed to the user when the form is submitted\nif `validationBehavior=\"native\"`. For realtime validation, use the `isInvalid`\nprop instead."
|
|
3150
|
+
},
|
|
3151
|
+
"description": {
|
|
3152
|
+
"type": "ReactNode",
|
|
3153
|
+
"required": false,
|
|
3154
|
+
"origin": "aria",
|
|
3155
|
+
"description": "A description for the field. Provides a hint such as specific requirements for what to choose."
|
|
3156
|
+
},
|
|
3157
|
+
"errorMessage": {
|
|
3158
|
+
"type": "ReactNode | ((v: ValidationResult) => ReactNode)",
|
|
3159
|
+
"required": false,
|
|
3160
|
+
"origin": "aria",
|
|
3161
|
+
"description": "An error message for the field."
|
|
3162
|
+
},
|
|
3163
|
+
"onFocusChange": {
|
|
3164
|
+
"type": "((isFocused: boolean) => void) | undefined",
|
|
3165
|
+
"required": false,
|
|
3166
|
+
"origin": "aria",
|
|
3167
|
+
"description": "Handler that is called when the element's focus status changes."
|
|
3168
|
+
},
|
|
3169
|
+
"label": {
|
|
3170
|
+
"type": "ReactNode",
|
|
3171
|
+
"required": false,
|
|
3172
|
+
"origin": "aria",
|
|
3173
|
+
"description": "The content to display as the label."
|
|
3174
|
+
},
|
|
3175
|
+
"excludeFromTabOrder": {
|
|
3176
|
+
"type": "boolean | undefined",
|
|
3177
|
+
"required": false,
|
|
3178
|
+
"origin": "aria",
|
|
3179
|
+
"description": "Whether to exclude the element from the sequential tab order. If true,\nthe element will not be focusable via the keyboard by tabbing. This should\nbe avoided except in rare scenarios where an alternative means of accessing\nthe element or its functionality via the keyboard is available."
|
|
3180
|
+
},
|
|
3181
|
+
"trailingIcon": {
|
|
3182
|
+
"type": "React.ReactNode",
|
|
3183
|
+
"required": false,
|
|
3184
|
+
"origin": "own",
|
|
3185
|
+
"description": "Trailing icon. Figma's `Show Trailing Icon` + `Trailing Icon` swap."
|
|
3186
|
+
},
|
|
3187
|
+
"wrapperClassName": {
|
|
3188
|
+
"type": "string | undefined",
|
|
3189
|
+
"required": false,
|
|
3190
|
+
"origin": "own",
|
|
3191
|
+
"description": "Class names for the `.ion-field` wrapper when a label or helper is shown."
|
|
3192
|
+
}
|
|
3193
|
+
},
|
|
3194
|
+
"propCounts": {
|
|
3195
|
+
"own": 9,
|
|
3196
|
+
"aria": 51,
|
|
3197
|
+
"dom": 265,
|
|
3198
|
+
"other": 0
|
|
3199
|
+
}
|
|
3200
|
+
},
|
|
3201
|
+
"Popover": {
|
|
3202
|
+
"name": "Popover",
|
|
3203
|
+
"source": "src/components/Popover.tsx",
|
|
3204
|
+
"propsType": "PopoverProps",
|
|
3205
|
+
"description": "Popover — Figma `Popover` (825:1853).\n\nSITS BETWEEN TOOLTIP AND MODAL. A tooltip is a hint that cannot hold\nfocusable content; a modal is a task that takes over the page. A popover\nholds interactive content but stays attached to the control that opened it.\n\n`usePopover` contains focus, closes on Escape or an outside click, and hides\nthe rest of the page from assistive tech while open — the same guarantees\nModal gives. What differs is the framing, and it is deliberate: no visible\nscrim, anchored to its trigger, and `surface/raised` rather than Modal's\n`surface/overlay`. It reads as attached to the page rather than replacing it.",
|
|
3206
|
+
"import": "import { Popover } from 'ionbase-ui';",
|
|
3207
|
+
"stylesheet": "src/styles/popover.css",
|
|
3208
|
+
"tokens": [
|
|
3209
|
+
"--border-subtle",
|
|
3210
|
+
"--border-width-default",
|
|
3211
|
+
"--border-width-thick",
|
|
3212
|
+
"--font-family-sans",
|
|
3213
|
+
"--font-weight-medium",
|
|
3214
|
+
"--font-weight-regular",
|
|
3215
|
+
"--icon-secondary",
|
|
3216
|
+
"--icon-size-md",
|
|
3217
|
+
"--ion-duration-base",
|
|
3218
|
+
"--ion-ease-out",
|
|
3219
|
+
"--ion-popover-width",
|
|
3220
|
+
"--ion-shadow-shadow-lg",
|
|
3221
|
+
"--radius-md",
|
|
3222
|
+
"--radius-sm",
|
|
3223
|
+
"--ring-focus",
|
|
3224
|
+
"--spacing-12",
|
|
3225
|
+
"--spacing-16",
|
|
3226
|
+
"--spacing-32",
|
|
3227
|
+
"--spacing-8",
|
|
3228
|
+
"--surface-hover",
|
|
3229
|
+
"--surface-raised",
|
|
3230
|
+
"--text-default",
|
|
3231
|
+
"--text-secondary",
|
|
3232
|
+
"--type-body",
|
|
3233
|
+
"--type-body-line-height",
|
|
3234
|
+
"--type-body-sm",
|
|
3235
|
+
"--type-body-sm-line-height"
|
|
3236
|
+
],
|
|
3237
|
+
"props": {
|
|
3238
|
+
"children": {
|
|
3239
|
+
"type": "React.ReactElement<unknown, string | React.JSXElementConstructor<any>>",
|
|
3240
|
+
"required": true,
|
|
3241
|
+
"origin": "own",
|
|
3242
|
+
"description": "The element that opens it. Must accept a ref and DOM props."
|
|
3243
|
+
},
|
|
3244
|
+
"content": {
|
|
3245
|
+
"type": "React.ReactNode",
|
|
3246
|
+
"required": false,
|
|
3247
|
+
"origin": "own",
|
|
3248
|
+
"description": "Panel contents."
|
|
3249
|
+
},
|
|
3250
|
+
"title": {
|
|
3251
|
+
"type": "React.ReactNode",
|
|
3252
|
+
"required": false,
|
|
3253
|
+
"origin": "own",
|
|
3254
|
+
"description": "Heading. Also gives the dialog its accessible name."
|
|
3255
|
+
},
|
|
3256
|
+
"footer": {
|
|
3257
|
+
"type": "React.ReactNode",
|
|
3258
|
+
"required": false,
|
|
3259
|
+
"origin": "own",
|
|
3260
|
+
"description": "Action row, right-aligned."
|
|
3261
|
+
},
|
|
3262
|
+
"placement": {
|
|
3263
|
+
"type": "PopoverPlacement | undefined",
|
|
3264
|
+
"required": false,
|
|
3265
|
+
"origin": "own",
|
|
3266
|
+
"description": "Matches the Figma `Placement` variant, and names where the POPOVER sits —\nnot where the arrow points. A preference, not a guarantee: it flips when\nthere is no room, and the arrow follows.",
|
|
3267
|
+
"values": [
|
|
3268
|
+
"right",
|
|
3269
|
+
"left",
|
|
3270
|
+
"top",
|
|
3271
|
+
"bottom"
|
|
3272
|
+
]
|
|
3273
|
+
},
|
|
3274
|
+
"size": {
|
|
3275
|
+
"type": "PopoverSize | undefined",
|
|
3276
|
+
"required": false,
|
|
3277
|
+
"origin": "own",
|
|
3278
|
+
"description": "Matches the Figma `Size` variant. Widths only; height always hugs.",
|
|
3279
|
+
"values": [
|
|
3280
|
+
"sm",
|
|
3281
|
+
"md",
|
|
3282
|
+
"lg"
|
|
3283
|
+
]
|
|
3284
|
+
},
|
|
3285
|
+
"showClose": {
|
|
3286
|
+
"type": "boolean | undefined",
|
|
3287
|
+
"required": false,
|
|
3288
|
+
"origin": "own",
|
|
3289
|
+
"description": "Show the close button. Defaults to `true`."
|
|
3290
|
+
},
|
|
3291
|
+
"hideArrow": {
|
|
3292
|
+
"type": "boolean | undefined",
|
|
3293
|
+
"required": false,
|
|
3294
|
+
"origin": "own",
|
|
3295
|
+
"description": "Hide the caret."
|
|
3296
|
+
},
|
|
3297
|
+
"closeLabel": {
|
|
3298
|
+
"type": "string | undefined",
|
|
3299
|
+
"required": false,
|
|
3300
|
+
"origin": "own"
|
|
3301
|
+
},
|
|
3302
|
+
"isOpen": {
|
|
3303
|
+
"type": "boolean | undefined",
|
|
3304
|
+
"required": false,
|
|
3305
|
+
"origin": "own"
|
|
3306
|
+
},
|
|
3307
|
+
"onOpenChange": {
|
|
3308
|
+
"type": "((isOpen: boolean) => void) | undefined",
|
|
3309
|
+
"required": false,
|
|
3310
|
+
"origin": "own"
|
|
3311
|
+
},
|
|
3312
|
+
"className": {
|
|
3313
|
+
"type": "string | undefined",
|
|
3314
|
+
"required": false,
|
|
3315
|
+
"origin": "own"
|
|
3316
|
+
}
|
|
3317
|
+
},
|
|
3318
|
+
"propCounts": {
|
|
3319
|
+
"own": 12,
|
|
3320
|
+
"aria": 0,
|
|
3321
|
+
"dom": 0,
|
|
3322
|
+
"other": 0
|
|
3323
|
+
}
|
|
3324
|
+
},
|
|
3325
|
+
"Radio": {
|
|
3326
|
+
"name": "Radio",
|
|
3327
|
+
"source": "src/components/Radio.tsx",
|
|
3328
|
+
"propsType": "RadioProps",
|
|
3329
|
+
"import": "import { Radio } from 'ionbase-ui';",
|
|
3330
|
+
"stylesheet": "src/styles/radio.css",
|
|
3331
|
+
"tokens": [
|
|
3332
|
+
"--border-disabled",
|
|
3333
|
+
"--border-error-strong",
|
|
3334
|
+
"--border-focus",
|
|
3335
|
+
"--border-inverse",
|
|
3336
|
+
"--border-primary-strong",
|
|
3337
|
+
"--border-stronger",
|
|
3338
|
+
"--border-width-default",
|
|
3339
|
+
"--border-width-thick",
|
|
3340
|
+
"--font-family-sans",
|
|
3341
|
+
"--font-weight-medium",
|
|
3342
|
+
"--icon-disabled",
|
|
3343
|
+
"--icon-on-color",
|
|
3344
|
+
"--ion-duration-base",
|
|
3345
|
+
"--ion-ease-out",
|
|
3346
|
+
"--ion-radio-border",
|
|
3347
|
+
"--ion-radio-dot",
|
|
3348
|
+
"--ion-radio-fill",
|
|
3349
|
+
"--ion-radio-font-size",
|
|
3350
|
+
"--ion-radio-gap",
|
|
3351
|
+
"--ion-radio-line-height",
|
|
3352
|
+
"--ion-radio-raised",
|
|
3353
|
+
"--ion-radio-size",
|
|
3354
|
+
"--ion-shadow-raised-flush-lg",
|
|
3355
|
+
"--ion-shadow-raised-flush-sm",
|
|
3356
|
+
"--ion-shadow-raised-flush-xs",
|
|
3357
|
+
"--radius-full",
|
|
3358
|
+
"--spacing-12",
|
|
3359
|
+
"--spacing-16",
|
|
3360
|
+
"--spacing-2",
|
|
3361
|
+
"--spacing-20",
|
|
3362
|
+
"--spacing-24",
|
|
3363
|
+
"--spacing-8",
|
|
3364
|
+
"--surface-default",
|
|
3365
|
+
"--surface-disabled",
|
|
3366
|
+
"--surface-error",
|
|
3367
|
+
"--surface-inverse",
|
|
3368
|
+
"--surface-primary",
|
|
3369
|
+
"--text-disabled",
|
|
3370
|
+
"--text-secondary",
|
|
3371
|
+
"--type-body",
|
|
3372
|
+
"--type-body-line-height",
|
|
3373
|
+
"--type-body-sm",
|
|
3374
|
+
"--type-body-sm-line-height"
|
|
3375
|
+
],
|
|
3376
|
+
"props": {
|
|
3377
|
+
"value": {
|
|
3378
|
+
"type": "string",
|
|
3379
|
+
"required": true,
|
|
3380
|
+
"origin": "own"
|
|
3381
|
+
},
|
|
3382
|
+
"size": {
|
|
3383
|
+
"type": "RadioSize | undefined",
|
|
3384
|
+
"required": false,
|
|
3385
|
+
"origin": "own",
|
|
3386
|
+
"values": [
|
|
3387
|
+
"sm",
|
|
3388
|
+
"md",
|
|
3389
|
+
"lg"
|
|
3390
|
+
]
|
|
3391
|
+
},
|
|
3392
|
+
"intent": {
|
|
3393
|
+
"type": "RadioIntent | undefined",
|
|
3394
|
+
"required": false,
|
|
3395
|
+
"origin": "own",
|
|
3396
|
+
"values": [
|
|
3397
|
+
"neutral",
|
|
3398
|
+
"brand",
|
|
3399
|
+
"danger"
|
|
3400
|
+
]
|
|
3401
|
+
},
|
|
3402
|
+
"isDisabled": {
|
|
3403
|
+
"type": "boolean | undefined",
|
|
3404
|
+
"required": false,
|
|
3405
|
+
"origin": "own",
|
|
3406
|
+
"description": "Whether this radio is disabled. Falls back to the group's `isDisabled`."
|
|
3407
|
+
},
|
|
3408
|
+
"disabled": {
|
|
3409
|
+
"type": "boolean | undefined",
|
|
3410
|
+
"required": false,
|
|
3411
|
+
"origin": "own",
|
|
3412
|
+
"tags": {
|
|
3413
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
3414
|
+
}
|
|
3415
|
+
},
|
|
3416
|
+
"children": {
|
|
3417
|
+
"type": "React.ReactNode",
|
|
3418
|
+
"required": false,
|
|
3419
|
+
"origin": "own"
|
|
3420
|
+
}
|
|
3421
|
+
},
|
|
3422
|
+
"propCounts": {
|
|
3423
|
+
"own": 6,
|
|
3424
|
+
"aria": 0,
|
|
3425
|
+
"dom": 303,
|
|
3426
|
+
"other": 0
|
|
3427
|
+
}
|
|
3428
|
+
},
|
|
3429
|
+
"RadioGroup": {
|
|
3430
|
+
"name": "RadioGroup",
|
|
3431
|
+
"source": "src/components/Radio.tsx",
|
|
3432
|
+
"propsType": "RadioGroupProps",
|
|
3433
|
+
"description": "Renders a `<fieldset>` with a `<legend>` rather than a div with\n`role=\"radiogroup\"`. Both are announced correctly, but a fieldset also groups\nthe inputs for form submission and native validation, which the ARIA version\ndoes not.",
|
|
3434
|
+
"import": "import { RadioGroup } from 'ionbase-ui';",
|
|
3435
|
+
"stylesheet": "src/styles/radio.css",
|
|
3436
|
+
"tokens": [
|
|
3437
|
+
"--border-disabled",
|
|
3438
|
+
"--border-error-strong",
|
|
3439
|
+
"--border-focus",
|
|
3440
|
+
"--border-inverse",
|
|
3441
|
+
"--border-primary-strong",
|
|
3442
|
+
"--border-stronger",
|
|
3443
|
+
"--border-width-default",
|
|
3444
|
+
"--border-width-thick",
|
|
3445
|
+
"--font-family-sans",
|
|
3446
|
+
"--font-weight-medium",
|
|
3447
|
+
"--icon-disabled",
|
|
3448
|
+
"--icon-on-color",
|
|
3449
|
+
"--ion-duration-base",
|
|
3450
|
+
"--ion-ease-out",
|
|
3451
|
+
"--ion-radio-border",
|
|
3452
|
+
"--ion-radio-dot",
|
|
3453
|
+
"--ion-radio-fill",
|
|
3454
|
+
"--ion-radio-font-size",
|
|
3455
|
+
"--ion-radio-gap",
|
|
3456
|
+
"--ion-radio-line-height",
|
|
3457
|
+
"--ion-radio-raised",
|
|
3458
|
+
"--ion-radio-size",
|
|
3459
|
+
"--ion-shadow-raised-flush-lg",
|
|
3460
|
+
"--ion-shadow-raised-flush-sm",
|
|
3461
|
+
"--ion-shadow-raised-flush-xs",
|
|
3462
|
+
"--radius-full",
|
|
3463
|
+
"--spacing-12",
|
|
3464
|
+
"--spacing-16",
|
|
3465
|
+
"--spacing-2",
|
|
3466
|
+
"--spacing-20",
|
|
3467
|
+
"--spacing-24",
|
|
3468
|
+
"--spacing-8",
|
|
3469
|
+
"--surface-default",
|
|
3470
|
+
"--surface-disabled",
|
|
3471
|
+
"--surface-error",
|
|
3472
|
+
"--surface-inverse",
|
|
3473
|
+
"--surface-primary",
|
|
3474
|
+
"--text-disabled",
|
|
3475
|
+
"--text-secondary",
|
|
3476
|
+
"--type-body",
|
|
3477
|
+
"--type-body-line-height",
|
|
3478
|
+
"--type-body-sm",
|
|
3479
|
+
"--type-body-sm-line-height"
|
|
3480
|
+
],
|
|
3481
|
+
"props": {
|
|
3482
|
+
"name": {
|
|
3483
|
+
"type": "string | undefined",
|
|
3484
|
+
"required": false,
|
|
3485
|
+
"origin": "own",
|
|
3486
|
+
"description": "Shared input name. Generated when omitted."
|
|
3487
|
+
},
|
|
3488
|
+
"value": {
|
|
3489
|
+
"type": "string | undefined",
|
|
3490
|
+
"required": false,
|
|
3491
|
+
"origin": "own"
|
|
3492
|
+
},
|
|
3493
|
+
"defaultValue": {
|
|
3494
|
+
"type": "string | undefined",
|
|
3495
|
+
"required": false,
|
|
3496
|
+
"origin": "own"
|
|
3497
|
+
},
|
|
3498
|
+
"onChange": {
|
|
3499
|
+
"type": "((value: string) => void) | undefined",
|
|
3500
|
+
"required": false,
|
|
3501
|
+
"origin": "own"
|
|
3502
|
+
},
|
|
3503
|
+
"label": {
|
|
3504
|
+
"type": "React.ReactNode",
|
|
3505
|
+
"required": false,
|
|
3506
|
+
"origin": "own"
|
|
3507
|
+
},
|
|
3508
|
+
"size": {
|
|
3509
|
+
"type": "RadioSize | undefined",
|
|
3510
|
+
"required": false,
|
|
3511
|
+
"origin": "own",
|
|
3512
|
+
"values": [
|
|
3513
|
+
"sm",
|
|
3514
|
+
"md",
|
|
3515
|
+
"lg"
|
|
3516
|
+
]
|
|
3517
|
+
},
|
|
3518
|
+
"intent": {
|
|
3519
|
+
"type": "RadioIntent | undefined",
|
|
3520
|
+
"required": false,
|
|
3521
|
+
"origin": "own",
|
|
3522
|
+
"values": [
|
|
3523
|
+
"neutral",
|
|
3524
|
+
"brand",
|
|
3525
|
+
"danger"
|
|
3526
|
+
]
|
|
3527
|
+
},
|
|
3528
|
+
"isDisabled": {
|
|
3529
|
+
"type": "boolean | undefined",
|
|
3530
|
+
"required": false,
|
|
3531
|
+
"origin": "own",
|
|
3532
|
+
"description": "Whether every radio in the group is disabled."
|
|
3533
|
+
},
|
|
3534
|
+
"disabled": {
|
|
3535
|
+
"type": "boolean | undefined",
|
|
3536
|
+
"required": false,
|
|
3537
|
+
"origin": "own",
|
|
3538
|
+
"tags": {
|
|
3539
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
3540
|
+
}
|
|
3541
|
+
},
|
|
3542
|
+
"children": {
|
|
3543
|
+
"type": "React.ReactNode",
|
|
3544
|
+
"required": false,
|
|
3545
|
+
"origin": "own"
|
|
3546
|
+
}
|
|
3547
|
+
},
|
|
3548
|
+
"propCounts": {
|
|
3549
|
+
"own": 10,
|
|
3550
|
+
"aria": 0,
|
|
3551
|
+
"dom": 276,
|
|
3552
|
+
"other": 0
|
|
3553
|
+
}
|
|
3554
|
+
},
|
|
3555
|
+
"ScrollProgress": {
|
|
3556
|
+
"name": "ScrollProgress",
|
|
3557
|
+
"source": "src/components/ScrollProgress.tsx",
|
|
3558
|
+
"propsType": "ScrollProgressProps",
|
|
3559
|
+
"description": "The compact rail is the disclosure trigger. It is a real `<button>`, so a\nkeyboard user reaches it by Tab and opens it the same way as any button —\nEnter or Space — no `:focus-within` trick required; a mouse user can also\njust hover it. Built as a WAI-ARIA Disclosure (`aria-expanded` +\n`aria-controls`) rather than a menu: see the CSS header for why\n`role=\"menu\"` is deliberately not used here.\n\nCloses on outside pointerdown and on Escape — the minimum a disclosure\nneeds to not trap the page once opened, not a full popover/focus-trap\nimplementation.",
|
|
3560
|
+
"import": "import { ScrollProgress } from 'ionbase-ui';",
|
|
3561
|
+
"stylesheet": "src/styles/scroll-progress.css",
|
|
3562
|
+
"tokens": [
|
|
3563
|
+
"--border-default",
|
|
3564
|
+
"--border-focus",
|
|
3565
|
+
"--border-strong",
|
|
3566
|
+
"--border-stronger",
|
|
3567
|
+
"--border-width-default",
|
|
3568
|
+
"--border-width-thick",
|
|
3569
|
+
"--font-family-sans",
|
|
3570
|
+
"--font-weight-regular",
|
|
3571
|
+
"--ion-duration-base",
|
|
3572
|
+
"--ion-ease-out",
|
|
3573
|
+
"--radius-md",
|
|
3574
|
+
"--radius-sm",
|
|
3575
|
+
"--spacing-12",
|
|
3576
|
+
"--spacing-2",
|
|
3577
|
+
"--spacing-32",
|
|
3578
|
+
"--spacing-8",
|
|
3579
|
+
"--surface-default",
|
|
3580
|
+
"--surface-muted",
|
|
3581
|
+
"--text-secondary",
|
|
3582
|
+
"--text-tertiary",
|
|
3583
|
+
"--type-body-sm",
|
|
3584
|
+
"--type-body-sm-line-height"
|
|
3585
|
+
],
|
|
3586
|
+
"props": {
|
|
3587
|
+
"progress": {
|
|
3588
|
+
"type": "number",
|
|
3589
|
+
"required": true,
|
|
3590
|
+
"origin": "own",
|
|
3591
|
+
"description": "0-100. The caller computes this from whatever it is tracking — a\nwindow scroll fraction, a custom scroll container, a reading-time\nestimate. This component has no opinion on the source."
|
|
3592
|
+
},
|
|
3593
|
+
"sections": {
|
|
3594
|
+
"type": "ScrollProgressSection[]",
|
|
3595
|
+
"required": true,
|
|
3596
|
+
"origin": "own"
|
|
3597
|
+
},
|
|
3598
|
+
"activeId": {
|
|
3599
|
+
"type": "string | undefined",
|
|
3600
|
+
"required": false,
|
|
3601
|
+
"origin": "own",
|
|
3602
|
+
"description": "The section the rail's heavier tick and the panel's selected row point\nto. Also the caller's to compute — see `progress`."
|
|
3603
|
+
},
|
|
3604
|
+
"onSelect": {
|
|
3605
|
+
"type": "((id: string) => void) | undefined",
|
|
3606
|
+
"required": false,
|
|
3607
|
+
"origin": "own",
|
|
3608
|
+
"description": "Fired when a row is chosen. The component does not scroll anywhere\nitself; matching Menu, it reports the choice and lets the caller decide\nwhat \"select this section\" means for their page."
|
|
3609
|
+
}
|
|
3610
|
+
},
|
|
3611
|
+
"propCounts": {
|
|
3612
|
+
"own": 4,
|
|
3613
|
+
"aria": 0,
|
|
3614
|
+
"dom": 277,
|
|
3615
|
+
"other": 0
|
|
3616
|
+
}
|
|
3617
|
+
},
|
|
3618
|
+
"Select": {
|
|
3619
|
+
"name": "Select",
|
|
3620
|
+
"source": "src/components/Select.tsx",
|
|
3621
|
+
"propsType": "SelectProps",
|
|
3622
|
+
"description": "Select wraps a native `<select>` rather than rebuilding one.\n\nReact Aria's `useSelect` builds a listbox in a popover, which is the right\nanswer when the menu needs custom rows — but Figma models only the trigger\nhere, and the dropdown list is a separate component on the Menu page. Until\nthat is built, the native control is the honest match: it brings keyboard\nhandling, type-ahead and the platform picker on mobile for free, and it is\naccessible without any of it being reimplemented.\n\nFigma's six states map the same way Input's do — Hover and Focus from\ninteraction, Filled from whether a value is set, the rest from props.",
|
|
3623
|
+
"import": "import { Select } from 'ionbase-ui';",
|
|
3624
|
+
"status": "stable",
|
|
3625
|
+
"summary": "A dropdown over a native <select>, with the same label and error wiring as Input.",
|
|
3626
|
+
"useWhen": [
|
|
3627
|
+
"the user picks exactly one value from a known, modest list",
|
|
3628
|
+
"the native platform picker is acceptable — and on mobile it usually is the best option"
|
|
3629
|
+
],
|
|
3630
|
+
"useInstead": [
|
|
3631
|
+
{
|
|
3632
|
+
"when": "the list is long enough to need search or type-ahead beyond the native behaviour",
|
|
3633
|
+
"use": "a combobox — not yet in this system"
|
|
3634
|
+
},
|
|
3635
|
+
{
|
|
3636
|
+
"when": "the rows need icons, avatars or two lines of text",
|
|
3637
|
+
"use": "Menu",
|
|
3638
|
+
"why": "Select wraps a native <select>, whose options can only be text"
|
|
3639
|
+
},
|
|
3640
|
+
{
|
|
3641
|
+
"when": "there are two or three mutually exclusive choices worth showing at once",
|
|
3642
|
+
"use": "RadioGroup"
|
|
3643
|
+
},
|
|
3644
|
+
{
|
|
3645
|
+
"when": "the user may pick more than one",
|
|
3646
|
+
"use": "Checkbox"
|
|
3647
|
+
}
|
|
3648
|
+
],
|
|
3649
|
+
"variants": {
|
|
3650
|
+
"size": {
|
|
3651
|
+
"sm": {
|
|
3652
|
+
"use": "dense forms, table filters"
|
|
3653
|
+
},
|
|
3654
|
+
"md": {
|
|
3655
|
+
"use": "the default"
|
|
3656
|
+
},
|
|
3657
|
+
"lg": {
|
|
3658
|
+
"use": "prominent single-field forms"
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
},
|
|
3662
|
+
"a11y": {
|
|
3663
|
+
"guarantees": [
|
|
3664
|
+
"keyboard handling, type-ahead and the mobile platform picker come from the native <select> rather than being reimplemented",
|
|
3665
|
+
"label, helper and error wiring match Input"
|
|
3666
|
+
],
|
|
3667
|
+
"requires": [
|
|
3668
|
+
"`label`, or `aria-label` when no visible label is rendered"
|
|
3669
|
+
]
|
|
3670
|
+
},
|
|
3671
|
+
"antiPatterns": [
|
|
3672
|
+
{
|
|
3673
|
+
"dont": "passing rich React nodes as option content",
|
|
3674
|
+
"why": "this renders a native <select>; options are text only"
|
|
3675
|
+
},
|
|
3676
|
+
{
|
|
3677
|
+
"dont": "using a Select with two options for an on/off setting",
|
|
3678
|
+
"do": "Toggle",
|
|
3679
|
+
"why": "a two-item dropdown costs two interactions to do what one control does in one"
|
|
3680
|
+
}
|
|
3681
|
+
],
|
|
3682
|
+
"deprecated": [
|
|
3683
|
+
{
|
|
3684
|
+
"prop": "disabled",
|
|
3685
|
+
"replacement": "isDisabled"
|
|
3686
|
+
}
|
|
3687
|
+
],
|
|
3688
|
+
"stylesheet": "src/styles/select.css",
|
|
3689
|
+
"tokens": [
|
|
3690
|
+
"--border-default",
|
|
3691
|
+
"--border-disabled",
|
|
3692
|
+
"--border-error-strong",
|
|
3693
|
+
"--border-focus",
|
|
3694
|
+
"--border-strong",
|
|
3695
|
+
"--border-width-default",
|
|
3696
|
+
"--border-width-thick",
|
|
3697
|
+
"--font-family-sans",
|
|
3698
|
+
"--font-weight-regular",
|
|
3699
|
+
"--icon-disabled",
|
|
3700
|
+
"--icon-size-md",
|
|
3701
|
+
"--icon-size-sm",
|
|
3702
|
+
"--icon-tertiary",
|
|
3703
|
+
"--ion-duration-base",
|
|
3704
|
+
"--ion-ease-out",
|
|
3705
|
+
"--ion-select-border-width",
|
|
3706
|
+
"--ion-select-font-size",
|
|
3707
|
+
"--ion-select-gap",
|
|
3708
|
+
"--ion-select-height",
|
|
3709
|
+
"--ion-select-icon-size",
|
|
3710
|
+
"--ion-select-line-height",
|
|
3711
|
+
"--ion-select-padding-x",
|
|
3712
|
+
"--ion-select-radius",
|
|
3713
|
+
"--radius-md",
|
|
3714
|
+
"--radius-sm",
|
|
3715
|
+
"--spacing-12",
|
|
3716
|
+
"--spacing-16",
|
|
3717
|
+
"--spacing-32",
|
|
3718
|
+
"--spacing-40",
|
|
3719
|
+
"--spacing-48",
|
|
3720
|
+
"--spacing-6",
|
|
3721
|
+
"--spacing-8",
|
|
3722
|
+
"--surface-default",
|
|
3723
|
+
"--surface-disabled",
|
|
3724
|
+
"--text-disabled",
|
|
3725
|
+
"--text-secondary",
|
|
3726
|
+
"--text-tertiary",
|
|
3727
|
+
"--type-body",
|
|
3728
|
+
"--type-body-line-height",
|
|
3729
|
+
"--type-body-sm",
|
|
3730
|
+
"--type-body-sm-line-height"
|
|
3731
|
+
],
|
|
3732
|
+
"props": {
|
|
3733
|
+
"size": {
|
|
3734
|
+
"type": "SelectSize | undefined",
|
|
3735
|
+
"required": false,
|
|
3736
|
+
"origin": "own",
|
|
3737
|
+
"description": "Matches the Figma `Size` variant: Small, Medium, Large.",
|
|
3738
|
+
"values": [
|
|
3739
|
+
"sm",
|
|
3740
|
+
"md",
|
|
3741
|
+
"lg"
|
|
3742
|
+
],
|
|
3743
|
+
"default": "md"
|
|
3744
|
+
},
|
|
3745
|
+
"options": {
|
|
3746
|
+
"type": "SelectOption[] | undefined",
|
|
3747
|
+
"required": false,
|
|
3748
|
+
"origin": "own",
|
|
3749
|
+
"description": "The options to render. Omit and pass `children` for grouped options."
|
|
3750
|
+
},
|
|
3751
|
+
"placeholder": {
|
|
3752
|
+
"type": "string | undefined",
|
|
3753
|
+
"required": false,
|
|
3754
|
+
"origin": "own",
|
|
3755
|
+
"description": "Text shown when nothing is selected. Renders as a disabled option so the\nfield can start empty without that being a valid choice."
|
|
3756
|
+
},
|
|
3757
|
+
"label": {
|
|
3758
|
+
"type": "React.ReactNode",
|
|
3759
|
+
"required": false,
|
|
3760
|
+
"origin": "own",
|
|
3761
|
+
"description": "Field label. Renders the Figma `Form Field` wrapper around the control."
|
|
3762
|
+
},
|
|
3763
|
+
"description": {
|
|
3764
|
+
"type": "React.ReactNode",
|
|
3765
|
+
"required": false,
|
|
3766
|
+
"origin": "own",
|
|
3767
|
+
"description": "Helper text below the field."
|
|
3768
|
+
},
|
|
3769
|
+
"errorMessage": {
|
|
3770
|
+
"type": "React.ReactNode",
|
|
3771
|
+
"required": false,
|
|
3772
|
+
"origin": "own",
|
|
3773
|
+
"description": "Replaces the helper text when `isInvalid` is set."
|
|
3774
|
+
},
|
|
3775
|
+
"isInvalid": {
|
|
3776
|
+
"type": "boolean | undefined",
|
|
3777
|
+
"required": false,
|
|
3778
|
+
"origin": "own"
|
|
3779
|
+
},
|
|
3780
|
+
"isDisabled": {
|
|
3781
|
+
"type": "boolean | undefined",
|
|
3782
|
+
"required": false,
|
|
3783
|
+
"origin": "own"
|
|
3784
|
+
},
|
|
3785
|
+
"disabled": {
|
|
3786
|
+
"type": "boolean | undefined",
|
|
3787
|
+
"required": false,
|
|
3788
|
+
"origin": "own",
|
|
3789
|
+
"tags": {
|
|
3790
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
3791
|
+
}
|
|
3792
|
+
},
|
|
3793
|
+
"className": {
|
|
3794
|
+
"type": "string | undefined",
|
|
3795
|
+
"required": false,
|
|
3796
|
+
"origin": "own",
|
|
3797
|
+
"description": "Class names for the control box (`.ion-select`). Always lands here —\nnever on the form-field wrapper. Use `wrapperClassName` for that."
|
|
3798
|
+
},
|
|
3799
|
+
"wrapperClassName": {
|
|
3800
|
+
"type": "string | undefined",
|
|
3801
|
+
"required": false,
|
|
3802
|
+
"origin": "own",
|
|
3803
|
+
"description": "Class names for the `.ion-field` wrapper when a label or helper is shown."
|
|
3804
|
+
}
|
|
3805
|
+
},
|
|
3806
|
+
"propCounts": {
|
|
3807
|
+
"own": 11,
|
|
3808
|
+
"aria": 0,
|
|
3809
|
+
"dom": 283,
|
|
3810
|
+
"other": 0
|
|
3811
|
+
}
|
|
3812
|
+
},
|
|
3813
|
+
"TabItem": {
|
|
3814
|
+
"name": "TabItem",
|
|
3815
|
+
"source": "../../node_modules/.pnpm/react-stately@3.48.0_react@19.2.8/node_modules/react-stately/dist/types/src/collections/Item.d.ts",
|
|
3816
|
+
"propsType": null,
|
|
3817
|
+
"import": "import { TabItem } from 'ionbase-ui';",
|
|
3818
|
+
"stylesheet": null,
|
|
3819
|
+
"tokens": [],
|
|
3820
|
+
"props": {},
|
|
3821
|
+
"propCounts": {
|
|
3822
|
+
"own": 0,
|
|
3823
|
+
"aria": 0,
|
|
3824
|
+
"dom": 0,
|
|
3825
|
+
"other": 0
|
|
3826
|
+
}
|
|
3827
|
+
},
|
|
3828
|
+
"Table": {
|
|
3829
|
+
"name": "Table",
|
|
3830
|
+
"source": "src/components/Table.tsx",
|
|
3831
|
+
"propsType": "TableProps",
|
|
3832
|
+
"description": "`Table` owns the scroll container and the density class; everything else\nis composed from `TableHead` / `TableBody` / `TableRow` / `TableCell`,\nmatching how Figma actually layers `Table Row` > `Table Cell` > `Cell Text`\nrather than one component with a wall of props.\n\nDensity has no React state to thread: it only ever changes vertical cell\npadding, which `.ion-table--compact td` and friends apply through the CSS\ncascade from this one class. A context provider for a value nothing in JS\never reads would be infrastructure with no consumer.\n\nThe scroll container is a keyboard-reachable region (WCAG 2.1.1): overflow\nalone is not enough. `aria-label` / `aria-labelledby` on `Table` name that\nregion — the container accepts no props of its own, so the table's name is\nthe only place the label can live. Prefer a `<caption>` via\n`aria-labelledby` when the name should also be visible.",
|
|
3833
|
+
"import": "import { Table } from 'ionbase-ui';",
|
|
3834
|
+
"status": "stable",
|
|
3835
|
+
"summary": "A data table. Table owns the scroll container and density; rows and cells are composed.",
|
|
3836
|
+
"useWhen": [
|
|
3837
|
+
"showing records with more than one attribute worth comparing across rows"
|
|
3838
|
+
],
|
|
3839
|
+
"useInstead": [
|
|
3840
|
+
{
|
|
3841
|
+
"when": "each item is a self-contained summary rather than a row of fields",
|
|
3842
|
+
"use": "FullCard"
|
|
3843
|
+
},
|
|
3844
|
+
{
|
|
3845
|
+
"when": "it is a layout grid rather than data",
|
|
3846
|
+
"use": "CSS grid",
|
|
3847
|
+
"why": "a <table> announces row and column semantics that a layout does not have"
|
|
3848
|
+
}
|
|
3849
|
+
],
|
|
3850
|
+
"composition": {
|
|
3851
|
+
"order": [
|
|
3852
|
+
"Table",
|
|
3853
|
+
"TableHead",
|
|
3854
|
+
"TableRow",
|
|
3855
|
+
"TableCell"
|
|
3856
|
+
],
|
|
3857
|
+
"note": "Table > TableHead/TableBody > TableRow > TableCell, matching how Figma layers Table Row > Table Cell > Cell Text. TableHead and TableBody take no props of their own; they place the rows and give TableCell its head-or-body context.",
|
|
3858
|
+
"example": "<Table aria-label=\"Users\"><TableHead><TableRow><TableCell scope=\"col\">Name</TableCell></TableRow></TableHead><TableBody><TableRow><TableCell>Ada</TableCell></TableRow></TableBody></Table>"
|
|
3859
|
+
},
|
|
3860
|
+
"variants": {
|
|
3861
|
+
"density": {
|
|
3862
|
+
"compact": {
|
|
3863
|
+
"use": "dense operational tables where row count matters more than comfort"
|
|
3864
|
+
},
|
|
3865
|
+
"default": {
|
|
3866
|
+
"use": "the default"
|
|
3867
|
+
},
|
|
3868
|
+
"relaxed": {
|
|
3869
|
+
"use": "short tables where each row deserves attention"
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
},
|
|
3873
|
+
"a11y": {
|
|
3874
|
+
"guarantees": [
|
|
3875
|
+
"the scroll container is keyboard reachable, which overflow alone does not provide (WCAG 2.1.1)"
|
|
3876
|
+
],
|
|
3877
|
+
"requires": [
|
|
3878
|
+
"`aria-label` or `aria-labelledby` on Table — it names the scroll region, and the container takes no props of its own, so this is the only place the name can live",
|
|
3879
|
+
"`scope=\"col\"` on header cells",
|
|
3880
|
+
"an accessible name on every row-selection Checkbox — those have no visible label by design"
|
|
3881
|
+
],
|
|
3882
|
+
"notes": [
|
|
3883
|
+
"Prefer a visible <caption> referenced by aria-labelledby when the table's name should also be seen."
|
|
3884
|
+
]
|
|
3885
|
+
},
|
|
3886
|
+
"antiPatterns": [
|
|
3887
|
+
{
|
|
3888
|
+
"dont": "<Table> with no aria-label",
|
|
3889
|
+
"why": "the scroll region is announced with no name, and a keyboard user reaching it is told nothing about what they have entered"
|
|
3890
|
+
},
|
|
3891
|
+
{
|
|
3892
|
+
"dont": "header cells without scope",
|
|
3893
|
+
"why": "screen readers cannot associate data cells with their column"
|
|
3894
|
+
},
|
|
3895
|
+
{
|
|
3896
|
+
"dont": "wrapping Table in your own overflow container",
|
|
3897
|
+
"why": "Table already owns the scroll container and makes it focusable; a second one is unreachable by keyboard"
|
|
3898
|
+
},
|
|
3899
|
+
{
|
|
3900
|
+
"dont": "row-selection checkboxes with no aria-label",
|
|
3901
|
+
"why": "every row announces an unnamed checkbox"
|
|
3902
|
+
}
|
|
3903
|
+
],
|
|
3904
|
+
"missingStates": {
|
|
3905
|
+
"note": "Table has no empty, loading or error state of its own — those are the caller's, and they are the states most often forgotten. Pattern coverage is planned; see docs/agent-readiness-plan.md phase 4a."
|
|
3906
|
+
},
|
|
3907
|
+
"stylesheet": "src/styles/table.css",
|
|
3908
|
+
"tokens": [
|
|
3909
|
+
"--border-default",
|
|
3910
|
+
"--border-focus",
|
|
3911
|
+
"--border-width-default",
|
|
3912
|
+
"--border-width-thick",
|
|
3913
|
+
"--font-family-sans",
|
|
3914
|
+
"--font-weight-medium",
|
|
3915
|
+
"--font-weight-regular",
|
|
3916
|
+
"--icon-interactive",
|
|
3917
|
+
"--icon-secondary",
|
|
3918
|
+
"--icon-size-sm",
|
|
3919
|
+
"--icon-tertiary",
|
|
3920
|
+
"--ion-duration-base",
|
|
3921
|
+
"--ion-ease-out",
|
|
3922
|
+
"--radius-md",
|
|
3923
|
+
"--spacing-16",
|
|
3924
|
+
"--spacing-20",
|
|
3925
|
+
"--spacing-6",
|
|
3926
|
+
"--spacing-8",
|
|
3927
|
+
"--surface-default",
|
|
3928
|
+
"--surface-hover",
|
|
3929
|
+
"--surface-page",
|
|
3930
|
+
"--surface-primary-subtle",
|
|
3931
|
+
"--text-default",
|
|
3932
|
+
"--text-link",
|
|
3933
|
+
"--text-secondary",
|
|
3934
|
+
"--type-body-sm",
|
|
3935
|
+
"--type-body-sm-line-height"
|
|
3936
|
+
],
|
|
3937
|
+
"props": {
|
|
3938
|
+
"density": {
|
|
3939
|
+
"type": "TableDensity | undefined",
|
|
3940
|
+
"required": false,
|
|
3941
|
+
"origin": "own",
|
|
3942
|
+
"description": "Matches Figma's `Density` variant on `Table Cell` / `Table Row`.",
|
|
3943
|
+
"values": [
|
|
3944
|
+
"compact",
|
|
3945
|
+
"default",
|
|
3946
|
+
"relaxed"
|
|
3947
|
+
]
|
|
3948
|
+
},
|
|
3949
|
+
"isStriped": {
|
|
3950
|
+
"type": "boolean | undefined",
|
|
3951
|
+
"required": false,
|
|
3952
|
+
"origin": "own",
|
|
3953
|
+
"description": "Alternating row background, read from the row's position, not a prop\nrepeated on every `TableRow`."
|
|
3954
|
+
}
|
|
3955
|
+
},
|
|
3956
|
+
"propCounts": {
|
|
3957
|
+
"own": 2,
|
|
3958
|
+
"aria": 0,
|
|
3959
|
+
"dom": 287,
|
|
3960
|
+
"other": 0
|
|
3961
|
+
}
|
|
3962
|
+
},
|
|
3963
|
+
"TableBody": {
|
|
3964
|
+
"name": "TableBody",
|
|
3965
|
+
"source": "src/components/Table.tsx",
|
|
3966
|
+
"propsType": null,
|
|
3967
|
+
"import": "import { TableBody } from 'ionbase-ui';",
|
|
3968
|
+
"stylesheet": "src/styles/table.css",
|
|
3969
|
+
"tokens": [
|
|
3970
|
+
"--border-default",
|
|
3971
|
+
"--border-focus",
|
|
3972
|
+
"--border-width-default",
|
|
3973
|
+
"--border-width-thick",
|
|
3974
|
+
"--font-family-sans",
|
|
3975
|
+
"--font-weight-medium",
|
|
3976
|
+
"--font-weight-regular",
|
|
3977
|
+
"--icon-interactive",
|
|
3978
|
+
"--icon-secondary",
|
|
3979
|
+
"--icon-size-sm",
|
|
3980
|
+
"--icon-tertiary",
|
|
3981
|
+
"--ion-duration-base",
|
|
3982
|
+
"--ion-ease-out",
|
|
3983
|
+
"--radius-md",
|
|
3984
|
+
"--spacing-16",
|
|
3985
|
+
"--spacing-20",
|
|
3986
|
+
"--spacing-6",
|
|
3987
|
+
"--spacing-8",
|
|
3988
|
+
"--surface-default",
|
|
3989
|
+
"--surface-hover",
|
|
3990
|
+
"--surface-page",
|
|
3991
|
+
"--surface-primary-subtle",
|
|
3992
|
+
"--text-default",
|
|
3993
|
+
"--text-link",
|
|
3994
|
+
"--text-secondary",
|
|
3995
|
+
"--type-body-sm",
|
|
3996
|
+
"--type-body-sm-line-height"
|
|
3997
|
+
],
|
|
3998
|
+
"props": {},
|
|
3999
|
+
"propCounts": {
|
|
4000
|
+
"own": 0,
|
|
4001
|
+
"aria": 0,
|
|
4002
|
+
"dom": 0,
|
|
4003
|
+
"other": 0
|
|
4004
|
+
}
|
|
4005
|
+
},
|
|
4006
|
+
"TableCell": {
|
|
4007
|
+
"name": "TableCell",
|
|
4008
|
+
"source": "src/components/Table.tsx",
|
|
4009
|
+
"propsType": "TableCellProps",
|
|
4010
|
+
"description": "One component covers Figma's `Table Cell` + `Cell Text`: the two are never\nused apart in the design (`Table Cell` always wraps exactly one `Cell\nText`), so splitting them into two exported components would only add API\nsurface for a composition nothing ever varies independently.\n\n`header` decides `<th>` vs `<td>` directly rather than a `type` prop that\ncould disagree with where the cell actually sits — a `<th>` rendered inside\n`<tbody>` is still a header cell to the browser and to CSS either way.",
|
|
4011
|
+
"import": "import { TableCell } from 'ionbase-ui';",
|
|
4012
|
+
"stylesheet": "src/styles/table.css",
|
|
4013
|
+
"tokens": [
|
|
4014
|
+
"--border-default",
|
|
4015
|
+
"--border-focus",
|
|
4016
|
+
"--border-width-default",
|
|
4017
|
+
"--border-width-thick",
|
|
4018
|
+
"--font-family-sans",
|
|
4019
|
+
"--font-weight-medium",
|
|
4020
|
+
"--font-weight-regular",
|
|
4021
|
+
"--icon-interactive",
|
|
4022
|
+
"--icon-secondary",
|
|
4023
|
+
"--icon-size-sm",
|
|
4024
|
+
"--icon-tertiary",
|
|
4025
|
+
"--ion-duration-base",
|
|
4026
|
+
"--ion-ease-out",
|
|
4027
|
+
"--radius-md",
|
|
4028
|
+
"--spacing-16",
|
|
4029
|
+
"--spacing-20",
|
|
4030
|
+
"--spacing-6",
|
|
4031
|
+
"--spacing-8",
|
|
4032
|
+
"--surface-default",
|
|
4033
|
+
"--surface-hover",
|
|
4034
|
+
"--surface-page",
|
|
4035
|
+
"--surface-primary-subtle",
|
|
4036
|
+
"--text-default",
|
|
4037
|
+
"--text-link",
|
|
4038
|
+
"--text-secondary",
|
|
4039
|
+
"--type-body-sm",
|
|
4040
|
+
"--type-body-sm-line-height"
|
|
4041
|
+
],
|
|
4042
|
+
"props": {
|
|
4043
|
+
"header": {
|
|
4044
|
+
"type": "boolean | undefined",
|
|
4045
|
+
"required": false,
|
|
4046
|
+
"origin": "own",
|
|
4047
|
+
"description": "Renders `<th>` instead of `<td>` — Figma's header cell, `surface/page`\nfill included."
|
|
4048
|
+
},
|
|
4049
|
+
"scope": {
|
|
4050
|
+
"type": "TableCellScope | undefined",
|
|
4051
|
+
"required": false,
|
|
4052
|
+
"origin": "own",
|
|
4053
|
+
"description": "`<th>` scope. Inferred when omitted: `col` in `<thead>`, `row` in\n`<tbody>`. Pass explicitly when the inference is wrong (e.g. a column\nheader rendered outside `<thead>`).",
|
|
4054
|
+
"values": [
|
|
4055
|
+
"row",
|
|
4056
|
+
"rowgroup",
|
|
4057
|
+
"col",
|
|
4058
|
+
"colgroup"
|
|
4059
|
+
]
|
|
4060
|
+
},
|
|
4061
|
+
"align": {
|
|
4062
|
+
"type": "TableCellAlign | undefined",
|
|
4063
|
+
"required": false,
|
|
4064
|
+
"origin": "own",
|
|
4065
|
+
"values": [
|
|
4066
|
+
"center",
|
|
4067
|
+
"leading",
|
|
4068
|
+
"trailing"
|
|
4069
|
+
]
|
|
4070
|
+
},
|
|
4071
|
+
"variant": {
|
|
4072
|
+
"type": "\"link\" | \"default\" | undefined",
|
|
4073
|
+
"required": false,
|
|
4074
|
+
"origin": "own",
|
|
4075
|
+
"description": "Figma's `Type=Link` — recolours the content to `text/link` /\n`icon/primary` rather than the body defaults.",
|
|
4076
|
+
"values": [
|
|
4077
|
+
"link",
|
|
4078
|
+
"default"
|
|
4079
|
+
]
|
|
4080
|
+
},
|
|
4081
|
+
"showDivider": {
|
|
4082
|
+
"type": "boolean | undefined",
|
|
4083
|
+
"required": false,
|
|
4084
|
+
"origin": "own",
|
|
4085
|
+
"description": "Figma's per-cell `Show Divider` — a column rule, not a row rule."
|
|
4086
|
+
},
|
|
4087
|
+
"icon": {
|
|
4088
|
+
"type": "React.ReactNode",
|
|
4089
|
+
"required": false,
|
|
4090
|
+
"origin": "own",
|
|
4091
|
+
"description": "Figma's `Leading Icon` / `Trailing Icon` slots on `Cell Text`."
|
|
4092
|
+
},
|
|
4093
|
+
"trailingIcon": {
|
|
4094
|
+
"type": "React.ReactNode",
|
|
4095
|
+
"required": false,
|
|
4096
|
+
"origin": "own"
|
|
4097
|
+
},
|
|
4098
|
+
"children": {
|
|
4099
|
+
"type": "React.ReactNode",
|
|
4100
|
+
"required": false,
|
|
4101
|
+
"origin": "own"
|
|
4102
|
+
}
|
|
4103
|
+
},
|
|
4104
|
+
"propCounts": {
|
|
4105
|
+
"own": 8,
|
|
4106
|
+
"aria": 0,
|
|
4107
|
+
"dom": 284,
|
|
4108
|
+
"other": 0
|
|
4109
|
+
}
|
|
4110
|
+
},
|
|
4111
|
+
"TableHead": {
|
|
4112
|
+
"name": "TableHead",
|
|
4113
|
+
"source": "src/components/Table.tsx",
|
|
4114
|
+
"propsType": null,
|
|
4115
|
+
"import": "import { TableHead } from 'ionbase-ui';",
|
|
4116
|
+
"stylesheet": "src/styles/table.css",
|
|
4117
|
+
"tokens": [
|
|
4118
|
+
"--border-default",
|
|
4119
|
+
"--border-focus",
|
|
4120
|
+
"--border-width-default",
|
|
4121
|
+
"--border-width-thick",
|
|
4122
|
+
"--font-family-sans",
|
|
4123
|
+
"--font-weight-medium",
|
|
4124
|
+
"--font-weight-regular",
|
|
4125
|
+
"--icon-interactive",
|
|
4126
|
+
"--icon-secondary",
|
|
4127
|
+
"--icon-size-sm",
|
|
4128
|
+
"--icon-tertiary",
|
|
4129
|
+
"--ion-duration-base",
|
|
4130
|
+
"--ion-ease-out",
|
|
4131
|
+
"--radius-md",
|
|
4132
|
+
"--spacing-16",
|
|
4133
|
+
"--spacing-20",
|
|
4134
|
+
"--spacing-6",
|
|
4135
|
+
"--spacing-8",
|
|
4136
|
+
"--surface-default",
|
|
4137
|
+
"--surface-hover",
|
|
4138
|
+
"--surface-page",
|
|
4139
|
+
"--surface-primary-subtle",
|
|
4140
|
+
"--text-default",
|
|
4141
|
+
"--text-link",
|
|
4142
|
+
"--text-secondary",
|
|
4143
|
+
"--type-body-sm",
|
|
4144
|
+
"--type-body-sm-line-height"
|
|
4145
|
+
],
|
|
4146
|
+
"props": {},
|
|
4147
|
+
"propCounts": {
|
|
4148
|
+
"own": 0,
|
|
4149
|
+
"aria": 0,
|
|
4150
|
+
"dom": 0,
|
|
4151
|
+
"other": 0
|
|
4152
|
+
}
|
|
4153
|
+
},
|
|
4154
|
+
"TableRow": {
|
|
4155
|
+
"name": "TableRow",
|
|
4156
|
+
"source": "src/components/Table.tsx",
|
|
4157
|
+
"propsType": "TableRowProps",
|
|
4158
|
+
"description": "A plain `<tr>`. Hover is CSS-only (`:hover` plus a `data-hovered` escape\nhatch, matching the rest of the system) rather than React Aria's\n`useHover`: a row is not itself an interactive element — nothing about it\ntakes focus or fires a click — so there is no keyboard-vs-pointer\ndistinction to track. A clickable row is a link or button inside a cell,\nthe same accessible pattern Menu and Table Cell's own link variant use;\nnesting an interactive role on `<tr>` itself is not valid HTML.",
|
|
4159
|
+
"import": "import { TableRow } from 'ionbase-ui';",
|
|
4160
|
+
"stylesheet": "src/styles/table.css",
|
|
4161
|
+
"tokens": [
|
|
4162
|
+
"--border-default",
|
|
4163
|
+
"--border-focus",
|
|
4164
|
+
"--border-width-default",
|
|
4165
|
+
"--border-width-thick",
|
|
4166
|
+
"--font-family-sans",
|
|
4167
|
+
"--font-weight-medium",
|
|
4168
|
+
"--font-weight-regular",
|
|
4169
|
+
"--icon-interactive",
|
|
4170
|
+
"--icon-secondary",
|
|
4171
|
+
"--icon-size-sm",
|
|
4172
|
+
"--icon-tertiary",
|
|
4173
|
+
"--ion-duration-base",
|
|
4174
|
+
"--ion-ease-out",
|
|
4175
|
+
"--radius-md",
|
|
4176
|
+
"--spacing-16",
|
|
4177
|
+
"--spacing-20",
|
|
4178
|
+
"--spacing-6",
|
|
4179
|
+
"--spacing-8",
|
|
4180
|
+
"--surface-default",
|
|
4181
|
+
"--surface-hover",
|
|
4182
|
+
"--surface-page",
|
|
4183
|
+
"--surface-primary-subtle",
|
|
4184
|
+
"--text-default",
|
|
4185
|
+
"--text-link",
|
|
4186
|
+
"--text-secondary",
|
|
4187
|
+
"--type-body-sm",
|
|
4188
|
+
"--type-body-sm-line-height"
|
|
4189
|
+
],
|
|
4190
|
+
"props": {
|
|
4191
|
+
"isSelected": {
|
|
4192
|
+
"type": "boolean | undefined",
|
|
4193
|
+
"required": false,
|
|
4194
|
+
"origin": "own"
|
|
4195
|
+
},
|
|
4196
|
+
"selection": {
|
|
4197
|
+
"type": "TableRowSelection | undefined",
|
|
4198
|
+
"required": false,
|
|
4199
|
+
"origin": "own",
|
|
4200
|
+
"description": "Renders a leading `Checkbox` cell — Figma's `Show Selection`. Takes the\ncheckbox's own props directly rather than a boolean, since a selectable\nrow needs `checked`/`onChange` wiring, not just a decorative box.\n\nInside `<thead>` the cell is a `<th scope=\"col\">` (select-all). Inside\n`<tbody>` it is a `<td>`."
|
|
4201
|
+
}
|
|
4202
|
+
},
|
|
4203
|
+
"propCounts": {
|
|
4204
|
+
"own": 2,
|
|
4205
|
+
"aria": 0,
|
|
4206
|
+
"dom": 278,
|
|
4207
|
+
"other": 0
|
|
4208
|
+
}
|
|
4209
|
+
},
|
|
4210
|
+
"Tabs": {
|
|
4211
|
+
"name": "Tabs",
|
|
4212
|
+
"source": "src/components/Tabs.tsx",
|
|
4213
|
+
"propsType": "TabsProps",
|
|
4214
|
+
"import": "import { Tabs } from 'ionbase-ui';",
|
|
4215
|
+
"stylesheet": "src/styles/tabs.css",
|
|
4216
|
+
"tokens": [
|
|
4217
|
+
"--border-default",
|
|
4218
|
+
"--border-primary",
|
|
4219
|
+
"--border-width-default",
|
|
4220
|
+
"--border-width-thick",
|
|
4221
|
+
"--font-family-sans",
|
|
4222
|
+
"--font-weight-medium",
|
|
4223
|
+
"--icon-size-sm",
|
|
4224
|
+
"--ion-duration-base",
|
|
4225
|
+
"--ion-ease-out",
|
|
4226
|
+
"--ion-tabs-icon-size",
|
|
4227
|
+
"--ion-tabs-item-font-size",
|
|
4228
|
+
"--ion-tabs-item-gap",
|
|
4229
|
+
"--ion-tabs-item-line-height",
|
|
4230
|
+
"--ion-tabs-item-padding-x",
|
|
4231
|
+
"--ion-tabs-item-padding-y",
|
|
4232
|
+
"--ion-tabs-item-size",
|
|
4233
|
+
"--radius-full",
|
|
4234
|
+
"--radius-md",
|
|
4235
|
+
"--ring-focus",
|
|
4236
|
+
"--spacing-12",
|
|
4237
|
+
"--spacing-16",
|
|
4238
|
+
"--spacing-2",
|
|
4239
|
+
"--spacing-20",
|
|
4240
|
+
"--spacing-32",
|
|
4241
|
+
"--spacing-4",
|
|
4242
|
+
"--spacing-40",
|
|
4243
|
+
"--spacing-48",
|
|
4244
|
+
"--spacing-6",
|
|
4245
|
+
"--spacing-8",
|
|
4246
|
+
"--surface-default",
|
|
4247
|
+
"--surface-hover",
|
|
4248
|
+
"--surface-muted",
|
|
4249
|
+
"--surface-page",
|
|
4250
|
+
"--text-default",
|
|
4251
|
+
"--text-disabled",
|
|
4252
|
+
"--text-tertiary",
|
|
4253
|
+
"--type-body",
|
|
4254
|
+
"--type-body-lg",
|
|
4255
|
+
"--type-body-lg-line-height",
|
|
4256
|
+
"--type-body-line-height",
|
|
4257
|
+
"--type-body-sm",
|
|
4258
|
+
"--type-body-sm-line-height"
|
|
4259
|
+
],
|
|
4260
|
+
"props": {
|
|
4261
|
+
"type": {
|
|
4262
|
+
"type": "TabsType | undefined",
|
|
4263
|
+
"required": false,
|
|
4264
|
+
"origin": "own",
|
|
4265
|
+
"description": "Visual style. Matches the Figma `Type` variant.",
|
|
4266
|
+
"values": [
|
|
4267
|
+
"pill",
|
|
4268
|
+
"underline"
|
|
4269
|
+
],
|
|
4270
|
+
"default": "pill"
|
|
4271
|
+
},
|
|
4272
|
+
"size": {
|
|
4273
|
+
"type": "TabsSize | undefined",
|
|
4274
|
+
"required": false,
|
|
4275
|
+
"origin": "own",
|
|
4276
|
+
"description": "Matches the Figma `Size` variant.",
|
|
4277
|
+
"values": [
|
|
4278
|
+
"sm",
|
|
4279
|
+
"md",
|
|
4280
|
+
"lg"
|
|
4281
|
+
],
|
|
4282
|
+
"default": "md"
|
|
4283
|
+
},
|
|
4284
|
+
"orientation": {
|
|
4285
|
+
"type": "\"horizontal\" | \"vertical\" | undefined",
|
|
4286
|
+
"required": false,
|
|
4287
|
+
"origin": "own",
|
|
4288
|
+
"description": "Drives both the arrow-key axis and the track layout.\n\n`vertical` is keyboard- and ARIA-complete — up/down move between tabs, and\nthe track stacks — but its *decoration* is not: the underline rule and the\npill track's padding are still written for the horizontal axis only. Those\nare Figma's to specify, not this file's to invent. See tabs.css.",
|
|
4289
|
+
"values": [
|
|
4290
|
+
"horizontal",
|
|
4291
|
+
"vertical"
|
|
4292
|
+
],
|
|
4293
|
+
"tags": {
|
|
4294
|
+
"default": "'horizontal'"
|
|
4295
|
+
},
|
|
4296
|
+
"default": "horizontal"
|
|
4297
|
+
},
|
|
4298
|
+
"className": {
|
|
4299
|
+
"type": "string | undefined",
|
|
4300
|
+
"required": false,
|
|
4301
|
+
"origin": "own"
|
|
4302
|
+
},
|
|
4303
|
+
"keyboardActivation": {
|
|
4304
|
+
"type": "\"manual\" | \"automatic\" | undefined",
|
|
4305
|
+
"required": false,
|
|
4306
|
+
"origin": "aria",
|
|
4307
|
+
"description": "Whether tabs are activated automatically on focus or manually.",
|
|
4308
|
+
"values": [
|
|
4309
|
+
"manual",
|
|
4310
|
+
"automatic"
|
|
4311
|
+
],
|
|
4312
|
+
"tags": {
|
|
4313
|
+
"default": "'automatic'"
|
|
4314
|
+
}
|
|
4315
|
+
},
|
|
4316
|
+
"isDisabled": {
|
|
4317
|
+
"type": "boolean | undefined",
|
|
4318
|
+
"required": false,
|
|
4319
|
+
"origin": "other",
|
|
4320
|
+
"description": "Whether the TabList is disabled.\nShows that a selection exists, but is not available in that circumstance."
|
|
4321
|
+
},
|
|
4322
|
+
"selectedKey": {
|
|
4323
|
+
"type": "Key | undefined",
|
|
4324
|
+
"required": false,
|
|
4325
|
+
"origin": "other",
|
|
4326
|
+
"description": "The currently selected key in the collection (controlled)."
|
|
4327
|
+
},
|
|
4328
|
+
"defaultSelectedKey": {
|
|
4329
|
+
"type": "Key | undefined",
|
|
4330
|
+
"required": false,
|
|
4331
|
+
"origin": "other",
|
|
4332
|
+
"description": "The initial selected keys in the collection (uncontrolled)."
|
|
4333
|
+
},
|
|
4334
|
+
"onSelectionChange": {
|
|
4335
|
+
"type": "((key: Key) => void) | undefined",
|
|
4336
|
+
"required": false,
|
|
4337
|
+
"origin": "other",
|
|
4338
|
+
"description": "Handler that is called when the selection changes."
|
|
4339
|
+
},
|
|
4340
|
+
"children": {
|
|
4341
|
+
"type": "CollectionChildren<T>",
|
|
4342
|
+
"required": true,
|
|
4343
|
+
"origin": "aria",
|
|
4344
|
+
"description": "The contents of the collection."
|
|
4345
|
+
},
|
|
4346
|
+
"items": {
|
|
4347
|
+
"type": "Iterable<T> | undefined",
|
|
4348
|
+
"required": false,
|
|
4349
|
+
"origin": "aria",
|
|
4350
|
+
"description": "Item objects in the collection."
|
|
4351
|
+
},
|
|
4352
|
+
"disabledKeys": {
|
|
4353
|
+
"type": "Iterable<Key> | undefined",
|
|
4354
|
+
"required": false,
|
|
4355
|
+
"origin": "aria",
|
|
4356
|
+
"description": "The item keys that are disabled. These items cannot be selected, focused, or otherwise\ninteracted with."
|
|
4357
|
+
},
|
|
4358
|
+
"id": {
|
|
4359
|
+
"type": "string | undefined",
|
|
4360
|
+
"required": false,
|
|
4361
|
+
"origin": "aria",
|
|
4362
|
+
"description": "The element's unique identifier. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)."
|
|
4363
|
+
},
|
|
4364
|
+
"aria-label": {
|
|
4365
|
+
"type": "string | undefined",
|
|
4366
|
+
"required": false,
|
|
4367
|
+
"origin": "aria",
|
|
4368
|
+
"description": "Defines a string value that labels the current element."
|
|
4369
|
+
},
|
|
4370
|
+
"aria-labelledby": {
|
|
4371
|
+
"type": "string | undefined",
|
|
4372
|
+
"required": false,
|
|
4373
|
+
"origin": "aria",
|
|
4374
|
+
"description": "Identifies the element (or elements) that labels the current element."
|
|
4375
|
+
},
|
|
4376
|
+
"aria-describedby": {
|
|
4377
|
+
"type": "string | undefined",
|
|
4378
|
+
"required": false,
|
|
4379
|
+
"origin": "aria",
|
|
4380
|
+
"description": "Identifies the element (or elements) that describes the object."
|
|
4381
|
+
},
|
|
4382
|
+
"aria-details": {
|
|
4383
|
+
"type": "string | undefined",
|
|
4384
|
+
"required": false,
|
|
4385
|
+
"origin": "aria",
|
|
4386
|
+
"description": "Identifies the element (or elements) that provide a detailed, extended description for the\nobject."
|
|
4387
|
+
}
|
|
4388
|
+
},
|
|
4389
|
+
"propCounts": {
|
|
4390
|
+
"own": 4,
|
|
4391
|
+
"aria": 9,
|
|
4392
|
+
"dom": 0,
|
|
4393
|
+
"other": 4
|
|
4394
|
+
}
|
|
4395
|
+
},
|
|
4396
|
+
"Toast": {
|
|
4397
|
+
"name": "Toast",
|
|
4398
|
+
"source": "src/components/Toast.tsx",
|
|
4399
|
+
"propsType": "ToastProps",
|
|
4400
|
+
"description": "Toast — Figma `Toast` (820:1655).\n\nNeutral chrome on `surface/raised`; the intent is carried by the icon alone.\nA tinted panel floating over unknown content competes with whatever is\nbehind it, and makes Toast and Alert indistinguishable at a glance.\n\nAUTO-DISMISS PAUSES ON HOVER AND FOCUS. A toast that keeps counting down\nwhile being read or while its action has keyboard focus takes the action\naway mid-reach — WCAG 2.2.1 asks for exactly this. The timer restarts rather\nthan resumes, which is the forgiving direction.",
|
|
4401
|
+
"import": "import { Toast } from 'ionbase-ui';",
|
|
4402
|
+
"stylesheet": "src/styles/toast.css",
|
|
4403
|
+
"tokens": [
|
|
4404
|
+
"--border-subtle",
|
|
4405
|
+
"--border-width-default",
|
|
4406
|
+
"--border-width-thick",
|
|
4407
|
+
"--font-family-sans",
|
|
4408
|
+
"--font-weight-medium",
|
|
4409
|
+
"--font-weight-regular",
|
|
4410
|
+
"--icon-error",
|
|
4411
|
+
"--icon-information",
|
|
4412
|
+
"--icon-primary",
|
|
4413
|
+
"--icon-secondary",
|
|
4414
|
+
"--icon-size-md",
|
|
4415
|
+
"--icon-success",
|
|
4416
|
+
"--icon-warning",
|
|
4417
|
+
"--ion-duration-base",
|
|
4418
|
+
"--ion-ease-out",
|
|
4419
|
+
"--ion-shadow-shadow-lg",
|
|
4420
|
+
"--ion-toast-icon",
|
|
4421
|
+
"--radius-md",
|
|
4422
|
+
"--radius-sm",
|
|
4423
|
+
"--ring-focus",
|
|
4424
|
+
"--spacing-12",
|
|
4425
|
+
"--spacing-16",
|
|
4426
|
+
"--spacing-32",
|
|
4427
|
+
"--spacing-4",
|
|
4428
|
+
"--surface-hover",
|
|
4429
|
+
"--surface-raised",
|
|
4430
|
+
"--text-default",
|
|
4431
|
+
"--text-link",
|
|
4432
|
+
"--text-link-hover",
|
|
4433
|
+
"--text-secondary",
|
|
4434
|
+
"--type-body",
|
|
4435
|
+
"--type-body-line-height",
|
|
4436
|
+
"--type-body-sm",
|
|
4437
|
+
"--type-body-sm-line-height"
|
|
4438
|
+
],
|
|
4439
|
+
"props": {
|
|
4440
|
+
"onDismiss": {
|
|
4441
|
+
"type": "(id: string) => void",
|
|
4442
|
+
"required": true,
|
|
4443
|
+
"origin": "own"
|
|
4444
|
+
},
|
|
4445
|
+
"id": {
|
|
4446
|
+
"type": "string",
|
|
4447
|
+
"required": true,
|
|
4448
|
+
"origin": "own"
|
|
4449
|
+
},
|
|
4450
|
+
"intent": {
|
|
4451
|
+
"type": "ToastIntent | undefined",
|
|
4452
|
+
"required": false,
|
|
4453
|
+
"origin": "own",
|
|
4454
|
+
"values": [
|
|
4455
|
+
"neutral",
|
|
4456
|
+
"primary",
|
|
4457
|
+
"success",
|
|
4458
|
+
"warning",
|
|
4459
|
+
"error",
|
|
4460
|
+
"information"
|
|
4461
|
+
],
|
|
4462
|
+
"default": "information"
|
|
4463
|
+
},
|
|
4464
|
+
"title": {
|
|
4465
|
+
"type": "React.ReactNode",
|
|
4466
|
+
"required": false,
|
|
4467
|
+
"origin": "own"
|
|
4468
|
+
},
|
|
4469
|
+
"message": {
|
|
4470
|
+
"type": "React.ReactNode",
|
|
4471
|
+
"required": false,
|
|
4472
|
+
"origin": "own"
|
|
4473
|
+
},
|
|
4474
|
+
"action": {
|
|
4475
|
+
"type": "{ label: string; onPress: () => void; } | undefined",
|
|
4476
|
+
"required": false,
|
|
4477
|
+
"origin": "own",
|
|
4478
|
+
"description": "One action. A second choice belongs in a dialog, which will still be there."
|
|
4479
|
+
},
|
|
4480
|
+
"duration": {
|
|
4481
|
+
"type": "number | null | undefined",
|
|
4482
|
+
"required": false,
|
|
4483
|
+
"origin": "own",
|
|
4484
|
+
"description": "Milliseconds before auto-dismiss. `null` keeps it until dismissed.",
|
|
4485
|
+
"default": 5000
|
|
4486
|
+
},
|
|
4487
|
+
"dismissLabel": {
|
|
4488
|
+
"type": "string | undefined",
|
|
4489
|
+
"required": false,
|
|
4490
|
+
"origin": "own",
|
|
4491
|
+
"default": "Dismiss"
|
|
4492
|
+
}
|
|
4493
|
+
},
|
|
4494
|
+
"propCounts": {
|
|
4495
|
+
"own": 8,
|
|
4496
|
+
"aria": 0,
|
|
4497
|
+
"dom": 0,
|
|
4498
|
+
"other": 0
|
|
4499
|
+
}
|
|
4500
|
+
},
|
|
4501
|
+
"ToastProvider": {
|
|
4502
|
+
"name": "ToastProvider",
|
|
4503
|
+
"source": "src/components/Toast.tsx",
|
|
4504
|
+
"propsType": "ToastProviderProps",
|
|
4505
|
+
"description": "Renders the queue and supplies `useToast`.\n\nThe live region is the CONTAINER, declared once and always present. A region\nthat appears at the same moment as its content is not reliably announced —\nassistive tech has to be watching the node before the text lands in it.",
|
|
4506
|
+
"import": "import { ToastProvider } from 'ionbase-ui';",
|
|
4507
|
+
"stylesheet": "src/styles/toast.css",
|
|
4508
|
+
"tokens": [
|
|
4509
|
+
"--border-subtle",
|
|
4510
|
+
"--border-width-default",
|
|
4511
|
+
"--border-width-thick",
|
|
4512
|
+
"--font-family-sans",
|
|
4513
|
+
"--font-weight-medium",
|
|
4514
|
+
"--font-weight-regular",
|
|
4515
|
+
"--icon-error",
|
|
4516
|
+
"--icon-information",
|
|
4517
|
+
"--icon-primary",
|
|
4518
|
+
"--icon-secondary",
|
|
4519
|
+
"--icon-size-md",
|
|
4520
|
+
"--icon-success",
|
|
4521
|
+
"--icon-warning",
|
|
4522
|
+
"--ion-duration-base",
|
|
4523
|
+
"--ion-ease-out",
|
|
4524
|
+
"--ion-shadow-shadow-lg",
|
|
4525
|
+
"--ion-toast-icon",
|
|
4526
|
+
"--radius-md",
|
|
4527
|
+
"--radius-sm",
|
|
4528
|
+
"--ring-focus",
|
|
4529
|
+
"--spacing-12",
|
|
4530
|
+
"--spacing-16",
|
|
4531
|
+
"--spacing-32",
|
|
4532
|
+
"--spacing-4",
|
|
4533
|
+
"--surface-hover",
|
|
4534
|
+
"--surface-raised",
|
|
4535
|
+
"--text-default",
|
|
4536
|
+
"--text-link",
|
|
4537
|
+
"--text-link-hover",
|
|
4538
|
+
"--text-secondary",
|
|
4539
|
+
"--type-body",
|
|
4540
|
+
"--type-body-line-height",
|
|
4541
|
+
"--type-body-sm",
|
|
4542
|
+
"--type-body-sm-line-height"
|
|
4543
|
+
],
|
|
4544
|
+
"props": {
|
|
4545
|
+
"children": {
|
|
4546
|
+
"type": "React.ReactNode",
|
|
4547
|
+
"required": false,
|
|
4548
|
+
"origin": "own"
|
|
4549
|
+
},
|
|
4550
|
+
"placement": {
|
|
4551
|
+
"type": "ToastPlacement | undefined",
|
|
4552
|
+
"required": false,
|
|
4553
|
+
"origin": "own",
|
|
4554
|
+
"description": "Where the stack sits. Not a Figma variant — position is the queue's concern.",
|
|
4555
|
+
"values": [
|
|
4556
|
+
"top-left",
|
|
4557
|
+
"top-right",
|
|
4558
|
+
"bottom-left",
|
|
4559
|
+
"bottom-right"
|
|
4560
|
+
]
|
|
4561
|
+
},
|
|
4562
|
+
"limit": {
|
|
4563
|
+
"type": "number | undefined",
|
|
4564
|
+
"required": false,
|
|
4565
|
+
"origin": "own",
|
|
4566
|
+
"description": "Oldest are dropped past this. Prevents an unbounded stack covering the page."
|
|
4567
|
+
}
|
|
4568
|
+
},
|
|
4569
|
+
"propCounts": {
|
|
4570
|
+
"own": 3,
|
|
4571
|
+
"aria": 0,
|
|
4572
|
+
"dom": 0,
|
|
4573
|
+
"other": 0
|
|
4574
|
+
}
|
|
4575
|
+
},
|
|
4576
|
+
"Toggle": {
|
|
4577
|
+
"name": "Toggle",
|
|
4578
|
+
"source": "src/components/Toggle.tsx",
|
|
4579
|
+
"propsType": "ToggleProps",
|
|
4580
|
+
"description": "Toggle is a checkbox with `role=\"switch\"`.\n\nNot a button with aria-pressed: a switch is a form value, and the checkbox\ngives form association and `:checked` for free. `role=\"switch\"` changes only\nhow it is announced — \"on/off\" rather than \"checked/unchecked\" — which is\nwhat Figma's On/Off states describe.\n\nThe visual difference from Checkbox is entirely in CSS; this component and\nCheckbox are near-identical by design rather than by accident, and are kept\napart because Figma models them as separate components with separate size\nramps.",
|
|
4581
|
+
"import": "import { Toggle } from 'ionbase-ui';",
|
|
4582
|
+
"stylesheet": "src/styles/toggle.css",
|
|
4583
|
+
"tokens": [
|
|
4584
|
+
"--border-disabled",
|
|
4585
|
+
"--border-focus",
|
|
4586
|
+
"--border-strong",
|
|
4587
|
+
"--border-width-default",
|
|
4588
|
+
"--border-width-thick",
|
|
4589
|
+
"--font-family-sans",
|
|
4590
|
+
"--ion-duration-base",
|
|
4591
|
+
"--ion-ease-in-out",
|
|
4592
|
+
"--ion-ease-out",
|
|
4593
|
+
"--ion-shadow-raised-flush-lg",
|
|
4594
|
+
"--ion-shadow-raised-flush-sm",
|
|
4595
|
+
"--ion-shadow-raised-flush-xs",
|
|
4596
|
+
"--ion-shadow-shadow-xs",
|
|
4597
|
+
"--ion-toggle-font-size",
|
|
4598
|
+
"--ion-toggle-gap",
|
|
4599
|
+
"--ion-toggle-inset",
|
|
4600
|
+
"--ion-toggle-line-height",
|
|
4601
|
+
"--ion-toggle-on",
|
|
4602
|
+
"--ion-toggle-raised",
|
|
4603
|
+
"--ion-toggle-thumb",
|
|
4604
|
+
"--ion-toggle-track-h",
|
|
4605
|
+
"--ion-toggle-track-w",
|
|
4606
|
+
"--radius-full",
|
|
4607
|
+
"--spacing-12",
|
|
4608
|
+
"--spacing-16",
|
|
4609
|
+
"--spacing-2",
|
|
4610
|
+
"--spacing-20",
|
|
4611
|
+
"--spacing-24",
|
|
4612
|
+
"--spacing-8",
|
|
4613
|
+
"--surface-default",
|
|
4614
|
+
"--surface-disabled",
|
|
4615
|
+
"--surface-error",
|
|
4616
|
+
"--surface-inverse",
|
|
4617
|
+
"--surface-muted",
|
|
4618
|
+
"--surface-primary",
|
|
4619
|
+
"--text-disabled",
|
|
4620
|
+
"--text-secondary",
|
|
4621
|
+
"--type-body",
|
|
4622
|
+
"--type-body-line-height",
|
|
4623
|
+
"--type-body-sm",
|
|
4624
|
+
"--type-body-sm-line-height"
|
|
4625
|
+
],
|
|
4626
|
+
"props": {
|
|
4627
|
+
"size": {
|
|
4628
|
+
"type": "ToggleSize | undefined",
|
|
4629
|
+
"required": false,
|
|
4630
|
+
"origin": "own",
|
|
4631
|
+
"description": "Matches the Figma `Size` variant: Small, Medium, Large.",
|
|
4632
|
+
"values": [
|
|
4633
|
+
"sm",
|
|
4634
|
+
"md",
|
|
4635
|
+
"lg"
|
|
4636
|
+
],
|
|
4637
|
+
"default": "md"
|
|
4638
|
+
},
|
|
4639
|
+
"intent": {
|
|
4640
|
+
"type": "ToggleIntent | undefined",
|
|
4641
|
+
"required": false,
|
|
4642
|
+
"origin": "own",
|
|
4643
|
+
"description": "Matches the Figma `Color` variant: Brand, Neutral, Danger.",
|
|
4644
|
+
"values": [
|
|
4645
|
+
"neutral",
|
|
4646
|
+
"brand",
|
|
4647
|
+
"danger"
|
|
4648
|
+
],
|
|
4649
|
+
"default": "brand"
|
|
4650
|
+
},
|
|
4651
|
+
"isDisabled": {
|
|
4652
|
+
"type": "boolean | undefined",
|
|
4653
|
+
"required": false,
|
|
4654
|
+
"origin": "own",
|
|
4655
|
+
"description": "Whether the toggle is disabled."
|
|
4656
|
+
},
|
|
4657
|
+
"disabled": {
|
|
4658
|
+
"type": "boolean | undefined",
|
|
4659
|
+
"required": false,
|
|
4660
|
+
"origin": "own",
|
|
4661
|
+
"tags": {
|
|
4662
|
+
"deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
|
|
4663
|
+
}
|
|
4664
|
+
},
|
|
4665
|
+
"children": {
|
|
4666
|
+
"type": "React.ReactNode",
|
|
4667
|
+
"required": false,
|
|
4668
|
+
"origin": "own"
|
|
4669
|
+
}
|
|
4670
|
+
},
|
|
4671
|
+
"propCounts": {
|
|
4672
|
+
"own": 5,
|
|
4673
|
+
"aria": 0,
|
|
4674
|
+
"dom": 304,
|
|
4675
|
+
"other": 0
|
|
4676
|
+
}
|
|
4677
|
+
},
|
|
4678
|
+
"Tooltip": {
|
|
4679
|
+
"name": "Tooltip",
|
|
4680
|
+
"source": "src/components/Tooltip.tsx",
|
|
4681
|
+
"propsType": "TooltipProps",
|
|
4682
|
+
"description": "Tooltip — Figma `Tooltip` (801:1568).\n\nWraps its trigger rather than taking a ref, so the common case is one\nelement deep: `<Tooltip label=\"...\"><Button/></Tooltip>`.\n\nFOCUS OPENS IT, NOT JUST HOVER. A hover-only tooltip is invisible to keyboard\nand switch users, and `useTooltipTrigger` wires both plus Escape to dismiss.\nIt also enforces one open tooltip at a time and a shared warmup, so moving\nalong a row of icon buttons does not flash a tooltip per button.\n\nThe trigger is cloned with the interaction props and a ref, which means it\nmust forward both. Every component in this library does; a bare `<div>` does\ntoo. A function component that drops its ref will render, but the tooltip\nwill have nothing to position against.",
|
|
4683
|
+
"import": "import { Tooltip } from 'ionbase-ui';",
|
|
4684
|
+
"stylesheet": "src/styles/tooltip.css",
|
|
4685
|
+
"tokens": [
|
|
4686
|
+
"--font-family-sans",
|
|
4687
|
+
"--font-weight-medium",
|
|
4688
|
+
"--font-weight-regular",
|
|
4689
|
+
"--ion-shadow-shadow-md",
|
|
4690
|
+
"--ion-tooltip-arrow",
|
|
4691
|
+
"--radius-sm",
|
|
4692
|
+
"--spacing-12",
|
|
4693
|
+
"--spacing-4",
|
|
4694
|
+
"--spacing-8",
|
|
4695
|
+
"--surface-inverse",
|
|
4696
|
+
"--text-inverse",
|
|
4697
|
+
"--type-body-sm",
|
|
4698
|
+
"--type-body-sm-line-height"
|
|
4699
|
+
],
|
|
4700
|
+
"props": {
|
|
4701
|
+
"label": {
|
|
4702
|
+
"type": "React.ReactNode",
|
|
4703
|
+
"required": true,
|
|
4704
|
+
"origin": "own",
|
|
4705
|
+
"description": "The hint. A tooltip is text only — anything interactive or focusable\nbelongs in a popover, because a tooltip cannot be focused, cannot be\nscrolled, and closes the moment the pointer leaves."
|
|
4706
|
+
},
|
|
4707
|
+
"title": {
|
|
4708
|
+
"type": "React.ReactNode",
|
|
4709
|
+
"required": false,
|
|
4710
|
+
"origin": "own",
|
|
4711
|
+
"description": "Optional heading above the label."
|
|
4712
|
+
},
|
|
4713
|
+
"placement": {
|
|
4714
|
+
"type": "TooltipPlacement | undefined",
|
|
4715
|
+
"required": false,
|
|
4716
|
+
"origin": "own",
|
|
4717
|
+
"description": "Matches the Figma `Placement` variant, and names where the TOOLTIP sits —\nnot where the arrow points. `top` is above the trigger, with the arrow on\nthe tooltip's bottom edge.\n\nTreated as a preference, not a guarantee: it flips to the opposite side\nwhen there is no room, which is the behaviour Figma cannot draw.",
|
|
4718
|
+
"values": [
|
|
4719
|
+
"right",
|
|
4720
|
+
"left",
|
|
4721
|
+
"top",
|
|
4722
|
+
"bottom"
|
|
4723
|
+
]
|
|
4724
|
+
},
|
|
4725
|
+
"delay": {
|
|
4726
|
+
"type": "number | undefined",
|
|
4727
|
+
"required": false,
|
|
4728
|
+
"origin": "own",
|
|
4729
|
+
"description": "Milliseconds before it opens on hover. Focus always opens immediately."
|
|
4730
|
+
},
|
|
4731
|
+
"isDisabled": {
|
|
4732
|
+
"type": "boolean | undefined",
|
|
4733
|
+
"required": false,
|
|
4734
|
+
"origin": "own",
|
|
4735
|
+
"description": "Disable the tooltip without unmounting the trigger."
|
|
4736
|
+
},
|
|
4737
|
+
"children": {
|
|
4738
|
+
"type": "React.ReactElement<unknown, string | React.JSXElementConstructor<any>>",
|
|
4739
|
+
"required": true,
|
|
4740
|
+
"origin": "own",
|
|
4741
|
+
"description": "The element the tooltip describes. Must accept a ref and DOM props."
|
|
4742
|
+
},
|
|
4743
|
+
"className": {
|
|
4744
|
+
"type": "string | undefined",
|
|
4745
|
+
"required": false,
|
|
4746
|
+
"origin": "own"
|
|
4747
|
+
}
|
|
4748
|
+
},
|
|
4749
|
+
"propCounts": {
|
|
4750
|
+
"own": 7,
|
|
4751
|
+
"aria": 0,
|
|
4752
|
+
"dom": 0,
|
|
4753
|
+
"other": 0
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4756
|
+
}
|
|
4757
|
+
}
|