@duro-app/cli 5.6.0 → 5.8.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/dist/commands/doctor.js +2 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/registry-types.d.ts +1 -1
- package/dist/registry-types.d.ts.map +1 -1
- package/package.json +5 -5
- package/registry.json +916 -30
package/registry.json
CHANGED
|
@@ -173,6 +173,167 @@
|
|
|
173
173
|
],
|
|
174
174
|
"sourcePath": "packages/ui/src/components/Alert/Alert.tsx"
|
|
175
175
|
},
|
|
176
|
+
"AppShell": {
|
|
177
|
+
"importPath": "@duro-app/ui",
|
|
178
|
+
"kind": "compound",
|
|
179
|
+
"meta": {
|
|
180
|
+
"anatomy": {
|
|
181
|
+
"optional": [
|
|
182
|
+
"Rail",
|
|
183
|
+
"Header"
|
|
184
|
+
],
|
|
185
|
+
"required": [
|
|
186
|
+
"Root",
|
|
187
|
+
"Main"
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
"description": "An application's frame: a navigation rail (a labelled nav, the brand at its top, an optional footer at its foot) beside the main content (main), with an optional Header. Below collapseBelow (sm default, md or lg), measured on the shell's own width, the rail is hidden and one sticky bar (a banner, appBarH tall) holds a Menu button that opens the same navigation in a left Drawer, the brand, and the Header's content when there is one — a shell without a Header still has its navigation on a phone. Above it the Header is a row that scrolls with the page and the rail stays sticky. CSS makes the switch: the server renders one HTML for every width with the brand in both places, and display: none hides the inactive copy, so nothing moves after hydration. A skip link (the first tab stop) focuses Main; an Aside inside Main sticks below the bar. Labels come from props. Compound component — Root is required.",
|
|
191
|
+
"example": "<AppShell.Root\n menuLabel=\"Menu\"\n closeLabel=\"Close navigation\"\n skipLabel=\"Skip to content\"\n brand={<TextLink href=\"/\">Acme</TextLink>}\n collapseBelow=\"md\"\n>\n <AppShell.Rail aria-label=\"Navigation\" footer={<Text variant=\"bodySm\">{user.name}</Text>}>\n {({close}) => (\n <SideNav.Root value={pathname} onValueChange={(v) => { close(); navigate(v) }}>\n <SideNav.Item value=\"/docs\">Docs</SideNav.Item>\n </SideNav.Root>\n )}\n </AppShell.Rail>\n <AppShell.Header>{search}</AppShell.Header>\n <AppShell.Main>{children}</AppShell.Main>\n</AppShell.Root>",
|
|
192
|
+
"relatedTo": [
|
|
193
|
+
{
|
|
194
|
+
"component": "SideNav",
|
|
195
|
+
"kind": "composition",
|
|
196
|
+
"relationship": "The usual content of AppShell.Rail; call the render function close() in its onValueChange so the drawer shuts after a pick"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"component": "PageShell",
|
|
200
|
+
"kind": "contrast",
|
|
201
|
+
"relationship": "PageShell centres one page under a header; AppShell frames the whole app around a rail"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"component": "Drawer",
|
|
205
|
+
"kind": "composition",
|
|
206
|
+
"relationship": "AppShell opens the rail in a Drawer below collapseBelow; do not add a second one for it"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"component": "Aside",
|
|
210
|
+
"kind": "composition",
|
|
211
|
+
"relationship": "An Aside inside AppShell.Main sticks below the shell's bar (appBarH) below collapseBelow, and at its own offset above"
|
|
212
|
+
}
|
|
213
|
+
],
|
|
214
|
+
"whenNotToUse": [
|
|
215
|
+
"A single page with a header and no rail — use PageShell",
|
|
216
|
+
"A rail beside one region inside a page — use Grid layout=\"split-wide\" with a SideNav"
|
|
217
|
+
],
|
|
218
|
+
"whenToUse": [
|
|
219
|
+
"The frame of an app with a persistent navigation rail: an admin, a docs site, a dashboard",
|
|
220
|
+
"A layout whose navigation must collapse into a drawer on a phone",
|
|
221
|
+
"An app with no header at all: the bar still gives the Menu button and the brand below collapseBelow"
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
"name": "AppShell",
|
|
225
|
+
"parts": {
|
|
226
|
+
"Header": {
|
|
227
|
+
"name": "Header",
|
|
228
|
+
"props": [
|
|
229
|
+
{
|
|
230
|
+
"description": "The header's content: a search form, the account menu. Below `collapseBelow` it joins the Menu button and the brand in the sticky bar; above, it is a row over Main that scrolls with the page.",
|
|
231
|
+
"name": "children",
|
|
232
|
+
"required": false,
|
|
233
|
+
"type": "ReactNode"
|
|
234
|
+
}
|
|
235
|
+
],
|
|
236
|
+
"sourcePath": "packages/ui/src/components/AppShell/AppShell.tsx"
|
|
237
|
+
},
|
|
238
|
+
"Main": {
|
|
239
|
+
"name": "Main",
|
|
240
|
+
"props": [
|
|
241
|
+
{
|
|
242
|
+
"name": "children",
|
|
243
|
+
"required": true,
|
|
244
|
+
"type": "ReactNode"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"description": "The skip link's target; Root makes one with `useId` when it is left out.",
|
|
248
|
+
"name": "id",
|
|
249
|
+
"required": false,
|
|
250
|
+
"type": "string"
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"description": "The `main` element: the container to hand `useContainerBelow`.",
|
|
254
|
+
"name": "ref",
|
|
255
|
+
"required": false,
|
|
256
|
+
"type": "Ref<HTMLElement>"
|
|
257
|
+
}
|
|
258
|
+
],
|
|
259
|
+
"sourcePath": "packages/ui/src/components/AppShell/AppShell.tsx"
|
|
260
|
+
},
|
|
261
|
+
"Rail": {
|
|
262
|
+
"name": "Rail",
|
|
263
|
+
"props": [
|
|
264
|
+
{
|
|
265
|
+
"description": "Names the navigation landmark and the drawer (\"Navigation\"); required.",
|
|
266
|
+
"name": "aria-label",
|
|
267
|
+
"required": true,
|
|
268
|
+
"type": "string"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"description": "The navigation (a SideNav, a Tree). Rendered in the rail, or in the drawer while it is open (never both); a function receives `close`.",
|
|
272
|
+
"name": "children",
|
|
273
|
+
"required": true,
|
|
274
|
+
"type": "RailContent"
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"description": "What sits at the rail's foot — the signed-in user, a licence line — and at the end of the drawer. A function receives `close`.",
|
|
278
|
+
"name": "footer",
|
|
279
|
+
"required": false,
|
|
280
|
+
"type": "RailContent"
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
"sourcePath": "packages/ui/src/components/AppShell/AppShell.tsx"
|
|
284
|
+
},
|
|
285
|
+
"Root": {
|
|
286
|
+
"name": "Root",
|
|
287
|
+
"props": [
|
|
288
|
+
{
|
|
289
|
+
"description": "The narrow-width button that opens the navigation (\"Menu\"), from your text catalog.",
|
|
290
|
+
"name": "menuLabel",
|
|
291
|
+
"required": true,
|
|
292
|
+
"type": "string"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"description": "The accessible name of the drawer's close button (\"Close navigation\").",
|
|
296
|
+
"name": "closeLabel",
|
|
297
|
+
"required": true,
|
|
298
|
+
"type": "string"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"description": "The skip link's text (\"Skip to content\"): the first tab stop, it moves focus to Main.",
|
|
302
|
+
"name": "skipLabel",
|
|
303
|
+
"required": true,
|
|
304
|
+
"type": "string"
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"description": "The app's name or logo — usually a link home. Shown at the top of the rail and, below `collapseBelow`, in the bar beside the Menu button.",
|
|
308
|
+
"name": "brand",
|
|
309
|
+
"required": false,
|
|
310
|
+
"type": "ReactNode"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"default": "'sm'",
|
|
314
|
+
"description": "Below this breakpoint, measured on the shell's own width, the rail becomes a Drawer behind the Menu button. Default `sm`.",
|
|
315
|
+
"name": "collapseBelow",
|
|
316
|
+
"required": false,
|
|
317
|
+
"type": "AppShellCollapse",
|
|
318
|
+
"union": [
|
|
319
|
+
"sm",
|
|
320
|
+
"md",
|
|
321
|
+
"lg"
|
|
322
|
+
]
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"description": "`AppShell.Rail`, `AppShell.Main` and an optional `AppShell.Header`, as direct children (Root places the Header's content in its bar).",
|
|
326
|
+
"name": "children",
|
|
327
|
+
"required": true,
|
|
328
|
+
"type": "ReactNode"
|
|
329
|
+
}
|
|
330
|
+
],
|
|
331
|
+
"sourcePath": "packages/ui/src/components/AppShell/AppShell.tsx"
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
"props": null,
|
|
335
|
+
"sourcePath": "packages/ui/src/components/AppShell/AppShell.tsx"
|
|
336
|
+
},
|
|
176
337
|
"Arrow": {
|
|
177
338
|
"importPath": "@duro-app/diagrams",
|
|
178
339
|
"kind": "component",
|
|
@@ -223,6 +384,72 @@
|
|
|
223
384
|
],
|
|
224
385
|
"sourcePath": "packages/diagrams/src/components/Arrow/Arrow.tsx"
|
|
225
386
|
},
|
|
387
|
+
"Aside": {
|
|
388
|
+
"importPath": "@duro-app/ui",
|
|
389
|
+
"kind": "component",
|
|
390
|
+
"meta": {
|
|
391
|
+
"description": "Content beside the main reading column — a table of contents, related pages: a labelled aside landmark that sticks within the viewport while the page scrolls and scrolls on its own when taller (offset from a spacing token, the raised layer). Forwards ref to the aside element.",
|
|
392
|
+
"example": "<Grid layout=\"content-aside\" gap=\"xl\">\n <Prose>{body}</Prose>\n <Aside aria-label=\"Page outline\">\n <TableOfContents.Root aria-label=\"On this page\" title=\"On this page\">…</TableOfContents.Root>\n </Aside>\n</Grid>",
|
|
393
|
+
"relatedTo": [
|
|
394
|
+
{
|
|
395
|
+
"component": "Grid",
|
|
396
|
+
"kind": "composition",
|
|
397
|
+
"relationship": "Grid layout=\"content-aside\" gives Aside its asideW track and stacks it below md"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"component": "TableOfContents",
|
|
401
|
+
"kind": "composition",
|
|
402
|
+
"relationship": "The usual content of an Aside on a docs page"
|
|
403
|
+
}
|
|
404
|
+
],
|
|
405
|
+
"whenNotToUse": [
|
|
406
|
+
"Inspecting a selected record — use DetailPanel",
|
|
407
|
+
"A navigation rail for the app — use AppShell.Rail"
|
|
408
|
+
],
|
|
409
|
+
"whenToUse": [
|
|
410
|
+
"The second track of Grid layout=\"content-aside\": an \"On this page\" list, related links",
|
|
411
|
+
"Secondary content that should stay in view beside a long page"
|
|
412
|
+
]
|
|
413
|
+
},
|
|
414
|
+
"name": "Aside",
|
|
415
|
+
"props": [
|
|
416
|
+
{
|
|
417
|
+
"description": "Names the landmark (\"Page outline\"); required, from your text catalog.",
|
|
418
|
+
"name": "aria-label",
|
|
419
|
+
"required": true,
|
|
420
|
+
"type": "string"
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"default": "'lg'",
|
|
424
|
+
"description": "The gap kept above the aside while it is stuck, and below it when it is taller than the viewport. Default `lg`.",
|
|
425
|
+
"name": "offset",
|
|
426
|
+
"required": false,
|
|
427
|
+
"type": "SpacingToken",
|
|
428
|
+
"union": [
|
|
429
|
+
"xs",
|
|
430
|
+
"sm",
|
|
431
|
+
"ms",
|
|
432
|
+
"md",
|
|
433
|
+
"lg",
|
|
434
|
+
"xl",
|
|
435
|
+
"xxl",
|
|
436
|
+
"xxxl"
|
|
437
|
+
]
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"description": "The `aside` element.",
|
|
441
|
+
"name": "ref",
|
|
442
|
+
"required": false,
|
|
443
|
+
"type": "Ref<HTMLElement>"
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
"name": "children",
|
|
447
|
+
"required": true,
|
|
448
|
+
"type": "ReactNode"
|
|
449
|
+
}
|
|
450
|
+
],
|
|
451
|
+
"sourcePath": "packages/ui/src/components/Aside/Aside.tsx"
|
|
452
|
+
},
|
|
226
453
|
"Badge": {
|
|
227
454
|
"importPath": "@duro-app/ui",
|
|
228
455
|
"kind": "component",
|
|
@@ -937,6 +1164,69 @@
|
|
|
937
1164
|
],
|
|
938
1165
|
"sourcePath": "packages/ui/src/components/Cluster/Cluster.tsx"
|
|
939
1166
|
},
|
|
1167
|
+
"CodeBlock": {
|
|
1168
|
+
"importPath": "@duro-app/ui",
|
|
1169
|
+
"kind": "component",
|
|
1170
|
+
"meta": {
|
|
1171
|
+
"description": "A block of code with a copy button: a pre that scrolls sideways when a line is long, and a Button that copies its text, shows the copied label for copiedDuration ms and announces it through a polite LiveRegion. Labels come from props.",
|
|
1172
|
+
"example": "<CodeBlock copyLabel=\"Copy\" copiedLabel=\"Copied\">\n <code>pnpm add @duro-app/ui</code>\n</CodeBlock>",
|
|
1173
|
+
"relatedTo": [
|
|
1174
|
+
{
|
|
1175
|
+
"component": "Prose",
|
|
1176
|
+
"kind": "composition",
|
|
1177
|
+
"relationship": "CodeBlock keeps its own styles inside Prose"
|
|
1178
|
+
},
|
|
1179
|
+
{
|
|
1180
|
+
"component": "LiveRegion",
|
|
1181
|
+
"kind": "composition",
|
|
1182
|
+
"relationship": "The copied confirmation is announced through a LiveRegion"
|
|
1183
|
+
}
|
|
1184
|
+
],
|
|
1185
|
+
"whenNotToUse": [
|
|
1186
|
+
"A short identifier in running text — use inline code (Prose styles it)",
|
|
1187
|
+
"Editable code — use Textarea"
|
|
1188
|
+
],
|
|
1189
|
+
"whenToUse": [
|
|
1190
|
+
"Code or a command the reader is likely to paste: a docs page, an install step",
|
|
1191
|
+
"A Markdown renderer's pre, inside Prose"
|
|
1192
|
+
]
|
|
1193
|
+
},
|
|
1194
|
+
"name": "CodeBlock",
|
|
1195
|
+
"props": [
|
|
1196
|
+
{
|
|
1197
|
+
"description": "The code: text, or the `<code>` element a Markdown renderer produced (highlighted spans included). What is copied is its text content.",
|
|
1198
|
+
"name": "children",
|
|
1199
|
+
"required": true,
|
|
1200
|
+
"type": "ReactNode"
|
|
1201
|
+
},
|
|
1202
|
+
{
|
|
1203
|
+
"description": "The copy button's label (\"Copy\"), from your text catalog.",
|
|
1204
|
+
"name": "copyLabel",
|
|
1205
|
+
"required": true,
|
|
1206
|
+
"type": "string"
|
|
1207
|
+
},
|
|
1208
|
+
{
|
|
1209
|
+
"description": "The label while the copy is confirmed (\"Copied\"), also announced to screen readers.",
|
|
1210
|
+
"name": "copiedLabel",
|
|
1211
|
+
"required": true,
|
|
1212
|
+
"type": "string"
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
"default": "2000",
|
|
1216
|
+
"description": "How long the confirmation stays, in milliseconds. Default 2000.",
|
|
1217
|
+
"name": "copiedDuration",
|
|
1218
|
+
"required": false,
|
|
1219
|
+
"type": "number"
|
|
1220
|
+
},
|
|
1221
|
+
{
|
|
1222
|
+
"description": "Called when the clipboard refuses the write (an insecure context, a denied permission).",
|
|
1223
|
+
"name": "onCopyError",
|
|
1224
|
+
"required": false,
|
|
1225
|
+
"type": "(error: unknown) => void"
|
|
1226
|
+
}
|
|
1227
|
+
],
|
|
1228
|
+
"sourcePath": "packages/ui/src/components/CodeBlock/CodeBlock.tsx"
|
|
1229
|
+
},
|
|
940
1230
|
"ColorInput": {
|
|
941
1231
|
"importPath": "@duro-app/ui",
|
|
942
1232
|
"kind": "component",
|
|
@@ -1947,14 +2237,17 @@
|
|
|
1947
2237
|
"kind": "compound",
|
|
1948
2238
|
"meta": {
|
|
1949
2239
|
"anatomy": {
|
|
2240
|
+
"optional": [
|
|
2241
|
+
"Handle"
|
|
2242
|
+
],
|
|
1950
2243
|
"required": [
|
|
1951
2244
|
"Root",
|
|
1952
2245
|
"Zone",
|
|
1953
2246
|
"Item"
|
|
1954
2247
|
]
|
|
1955
2248
|
},
|
|
1956
|
-
"description": "Move items between zones
|
|
1957
|
-
"example": "<DragDrop.Root
|
|
2249
|
+
"description": "Move items between zones by pointer (mouse, pen and touch through one pointer-event path; touch holds briefly, then drags) or by keyboard (a Handle per item: Space picks up, arrows move, Space drops, Escape cancels). The innermost accepting zone wins, so a zone nested in an Item (a card in a column) takes its own drops; a zone can refuse with a reason that is shown and announced. Placeholders, edge auto-scroll and list-style announcements (through `announce`, for catalog strings) come with it.",
|
|
2250
|
+
"example": "<DragDrop.Root\n onDrop={({item, target}) => move(item.id, target.zone, target.index)}\n renderPlaceholder={({label}) => <Text variant=\"caption\">→ {label}</Text>}\n announce={(e) => t(`board.drag.${e.kind}`, e)}\n>\n {columns.map((col) => (\n <DragDrop.Zone key={col.id} id={col.id} label={col.name} orientation=\"vertical\" list\n accepts={(item) => item.data.kind === 'task' || {ok: false, reason: t('board.attachOnCard')}}>\n {col.cards.map((card) => (\n <DragDrop.Item key={card.id} id={card.id} zone={col.id} label={card.title} data={card}>\n <DragDrop.Handle>\n <DragDrop.Zone id={`attach:${card.id}`} label={card.title}\n accepts={(item) => item.data.kind === 'activity'}>\n <Card>{card.title}</Card>\n </DragDrop.Zone>\n </DragDrop.Handle>\n </DragDrop.Item>\n ))}\n </DragDrop.Zone>\n ))}\n</DragDrop.Root>",
|
|
1958
2251
|
"relatedTo": [
|
|
1959
2252
|
{
|
|
1960
2253
|
"component": "Tag",
|
|
@@ -1968,18 +2261,36 @@
|
|
|
1968
2261
|
}
|
|
1969
2262
|
],
|
|
1970
2263
|
"whenNotToUse": [
|
|
1971
|
-
"As the ONLY way to do something —
|
|
1972
|
-
"Long lists that scroll while dragging — the ghost follows the pointer but zones do not auto-scroll",
|
|
2264
|
+
"As the ONLY way to do something — WCAG 2.5.7 asks for a single-pointer alternative to dragging (a button or menu that moves the item); a Handle adds the keyboard path, not a click one",
|
|
1973
2265
|
"Sorting tabular data — sort the Table instead",
|
|
1974
2266
|
"React Native — Item renders its children without drag behaviour there"
|
|
1975
2267
|
],
|
|
1976
2268
|
"whenToUse": [
|
|
1977
2269
|
"Slotting things into places — people into approval gates, cards into columns, files into folders",
|
|
1978
|
-
"Reordering a short row or list when the order is visible and meaningful"
|
|
2270
|
+
"Reordering a short row or list when the order is visible and meaningful",
|
|
2271
|
+
"A board: columns as labelled lists (`list`), cards with a Handle, an attach zone nested in each card"
|
|
1979
2272
|
]
|
|
1980
2273
|
},
|
|
1981
2274
|
"name": "DragDrop",
|
|
1982
2275
|
"parts": {
|
|
2276
|
+
"Handle": {
|
|
2277
|
+
"name": "Handle",
|
|
2278
|
+
"props": [
|
|
2279
|
+
{
|
|
2280
|
+
"description": "Defaults to the Item's label.",
|
|
2281
|
+
"name": "aria-label",
|
|
2282
|
+
"required": false,
|
|
2283
|
+
"type": "string"
|
|
2284
|
+
},
|
|
2285
|
+
{
|
|
2286
|
+
"description": "What the handle shows: a grip, or the item's whole face. Keep other controls out of it — a handle is one widget.",
|
|
2287
|
+
"name": "children",
|
|
2288
|
+
"required": true,
|
|
2289
|
+
"type": "ReactNode"
|
|
2290
|
+
}
|
|
2291
|
+
],
|
|
2292
|
+
"sourcePath": "packages/ui/src/components/DragDrop/DragDrop.tsx"
|
|
2293
|
+
},
|
|
1983
2294
|
"Item": {
|
|
1984
2295
|
"name": "Item",
|
|
1985
2296
|
"props": [
|
|
@@ -1995,7 +2306,7 @@
|
|
|
1995
2306
|
"type": "string"
|
|
1996
2307
|
},
|
|
1997
2308
|
{
|
|
1998
|
-
"description": "Read to screen readers when picked up or dropped.",
|
|
2309
|
+
"description": "Read to screen readers when picked up or dropped; a Handle's default accessible name.",
|
|
1999
2310
|
"name": "label",
|
|
2000
2311
|
"required": true,
|
|
2001
2312
|
"type": "string"
|
|
@@ -2030,16 +2341,35 @@
|
|
|
2030
2341
|
"name": "Root",
|
|
2031
2342
|
"props": [
|
|
2032
2343
|
{
|
|
2033
|
-
"description": "Called when an item is released over a zone that accepts it. Reordering inside the item's own zone arrives here too, with the new index.",
|
|
2344
|
+
"description": "Called when an item is released over a zone that accepts it (or dropped with Space/Enter). Reordering inside the item's own zone arrives here too, with the new index.",
|
|
2034
2345
|
"name": "onDrop",
|
|
2035
2346
|
"required": true,
|
|
2036
2347
|
"type": "(event: DragDropEvent<T>) => void"
|
|
2037
2348
|
},
|
|
2038
2349
|
{
|
|
2039
|
-
"description": "
|
|
2350
|
+
"description": "Called whenever the target under the drag changes — a new zone or index, nothing, or a refusal.",
|
|
2351
|
+
"name": "onDragOver",
|
|
2352
|
+
"required": false,
|
|
2353
|
+
"type": "(event: DragDropOverEvent<T>) => void"
|
|
2354
|
+
},
|
|
2355
|
+
{
|
|
2356
|
+
"description": "Supplies every live-region string (pick, move, drop, cancel, refuse), e.g. from the app's message catalog. Defaults to English.",
|
|
2040
2357
|
"name": "announce",
|
|
2041
2358
|
"required": false,
|
|
2042
|
-
"type": "(event:
|
|
2359
|
+
"type": "(event: DragDropAnnouncement) => string"
|
|
2360
|
+
},
|
|
2361
|
+
{
|
|
2362
|
+
"description": "What marks the insertion point in a zone while dragging; a Zone's own renderPlaceholder wins. Without one, only the zone lights up.",
|
|
2363
|
+
"name": "renderPlaceholder",
|
|
2364
|
+
"required": false,
|
|
2365
|
+
"type": "DragDropRenderPlaceholder"
|
|
2366
|
+
},
|
|
2367
|
+
{
|
|
2368
|
+
"default": "DEFAULT_INSTRUCTIONS",
|
|
2369
|
+
"description": "Read by screen readers on a focused Handle.",
|
|
2370
|
+
"name": "instructions",
|
|
2371
|
+
"required": false,
|
|
2372
|
+
"type": "string"
|
|
2043
2373
|
},
|
|
2044
2374
|
{
|
|
2045
2375
|
"name": "children",
|
|
@@ -2058,7 +2388,7 @@
|
|
|
2058
2388
|
"type": "string"
|
|
2059
2389
|
},
|
|
2060
2390
|
{
|
|
2061
|
-
"description": "Read to screen readers when an item
|
|
2391
|
+
"description": "Read to screen readers when an item moves or drops here; the list's accessible name with `list`.",
|
|
2062
2392
|
"name": "label",
|
|
2063
2393
|
"required": true,
|
|
2064
2394
|
"type": "string"
|
|
@@ -2071,10 +2401,53 @@
|
|
|
2071
2401
|
"type": "'horizontal' | 'vertical'"
|
|
2072
2402
|
},
|
|
2073
2403
|
{
|
|
2074
|
-
"description": "
|
|
2404
|
+
"description": "Take the item (`true`), let it pass to an outer zone (`false`), or refuse it with a reason that is shown and announced (`{ok: false, reason}`). Omitted: every item is taken.",
|
|
2075
2405
|
"name": "accepts",
|
|
2076
2406
|
"required": false,
|
|
2077
|
-
"type": "(item: DragDropItemData<T>) =>
|
|
2407
|
+
"type": "(item: DragDropItemData<T>) => DragDropVerdict"
|
|
2408
|
+
},
|
|
2409
|
+
{
|
|
2410
|
+
"description": "Keyboard order across zones (Left/Right); zones without one follow, in DOM order.",
|
|
2411
|
+
"name": "order",
|
|
2412
|
+
"required": false,
|
|
2413
|
+
"type": "number"
|
|
2414
|
+
},
|
|
2415
|
+
{
|
|
2416
|
+
"description": "Marks the insertion point in this zone; overrides the Root's.",
|
|
2417
|
+
"name": "renderPlaceholder",
|
|
2418
|
+
"required": false,
|
|
2419
|
+
"type": "DragDropRenderPlaceholder"
|
|
2420
|
+
},
|
|
2421
|
+
{
|
|
2422
|
+
"default": "false",
|
|
2423
|
+
"description": "Render the zone as a labelled list (`role=\"list\"`) laid out along `orientation`, its Items as list items. Put the Items directly in it.",
|
|
2424
|
+
"name": "list",
|
|
2425
|
+
"required": false,
|
|
2426
|
+
"type": "boolean"
|
|
2427
|
+
},
|
|
2428
|
+
{
|
|
2429
|
+
"default": "'sm'",
|
|
2430
|
+
"description": "Gap between the Items of a `list` zone.",
|
|
2431
|
+
"name": "gap",
|
|
2432
|
+
"required": false,
|
|
2433
|
+
"type": "SpacingToken",
|
|
2434
|
+
"union": [
|
|
2435
|
+
"xs",
|
|
2436
|
+
"sm",
|
|
2437
|
+
"ms",
|
|
2438
|
+
"md",
|
|
2439
|
+
"lg",
|
|
2440
|
+
"xl",
|
|
2441
|
+
"xxl",
|
|
2442
|
+
"xxxl"
|
|
2443
|
+
]
|
|
2444
|
+
},
|
|
2445
|
+
{
|
|
2446
|
+
"default": "false",
|
|
2447
|
+
"description": "Stretch to fill the parent (a Timeline bar, a card) instead of sizing to the content.",
|
|
2448
|
+
"name": "fill",
|
|
2449
|
+
"required": false,
|
|
2450
|
+
"type": "boolean"
|
|
2078
2451
|
},
|
|
2079
2452
|
{
|
|
2080
2453
|
"name": "children",
|
|
@@ -2677,7 +3050,7 @@
|
|
|
2677
3050
|
"importPath": "@duro-app/ui",
|
|
2678
3051
|
"kind": "component",
|
|
2679
3052
|
"meta": {
|
|
2680
|
-
"description": "Grid layout. Columns are a count (1-6), a list of weights ([1, 2] for one-third / two-thirds), responsive auto-fit via minColumnWidth, or a named split layout (list/detail, nav/content) that collapses to one column on the width of its own container, so it is safe to nest and to place beside a DetailPanel. Weights rather than CSS template strings, so the same props render as CSS grid on web and as a wrapping flex row on native.
|
|
3053
|
+
"description": "Grid layout. Columns are a count (1-6), a list of weights ([1, 2] for one-third / two-thirds), responsive auto-fit via minColumnWidth, or a named split layout (list/detail, nav/content) that collapses to one column on the width of its own container, so it is safe to nest and to place beside a DetailPanel. Weights rather than CSS template strings, so the same props render as CSS grid on web and as a wrapping flex row on native. layout=\"content-aside\" is a reading column beside an Aside (asideW), one column below md on its own container. ref resolves to the outer element (with a layout, the container its query measures — hand it to useContainerBelow). For another fixed track beside fractions, tracks takes a token track list — tracks={['1fr', 'gridColXs']} — web only, equal columns on native.",
|
|
2681
3054
|
"example": "// Split: list ≥ sizes.gridColSm (240px) beside a detail pane, one column below md\n<Grid layout=\"split\" gap=\"lg\">\n <List.Root>…</List.Root>\n <Panel.Root>…</Panel.Root>\n</Grid>\n\n// Responsive: columns auto-fit based on min width\n<Grid minColumnWidth=\"gridColMd\" gap=\"md\">\n <Card>A</Card>\n <Card>B</Card>\n <Card>C</Card>\n</Grid>\n\n// Fixed: always 3 columns\n<Grid columns={3} gap=\"md\">\n <Card>A</Card>\n <Card>B</Card>\n <Card>C</Card>\n</Grid>\n\n// Weighted: a one-third / two-thirds split (works on native too)\n<Grid columns={[1, 2]} gap=\"md\">\n <Card>Sidebar</Card>\n <Card>Content</Card>\n</Grid>",
|
|
2682
3055
|
"relatedTo": [
|
|
2683
3056
|
{
|
|
@@ -2698,7 +3071,8 @@
|
|
|
2698
3071
|
"whenToUse": [
|
|
2699
3072
|
"Card grids, dashboard layouts, multi-column forms",
|
|
2700
3073
|
"Responsive layouts that should auto-adjust column count",
|
|
2701
|
-
"A list/detail or nav/content screen — layout=\"split\" | \"split-wide\", never a hand-rolled gridTemplateColumns with its own @media; a split inside a split is fine, each collapses on its own room"
|
|
3074
|
+
"A list/detail or nav/content screen — layout=\"split\" | \"split-wide\", never a hand-rolled gridTemplateColumns with its own @media; a split inside a split is fine, each collapses on its own room",
|
|
3075
|
+
"A long page with a table of contents beside it — layout=\"content-aside\" with an Aside"
|
|
2702
3076
|
]
|
|
2703
3077
|
},
|
|
2704
3078
|
"name": "Grid",
|
|
@@ -2732,10 +3106,15 @@
|
|
|
2732
3106
|
"type": "Length"
|
|
2733
3107
|
},
|
|
2734
3108
|
{
|
|
2735
|
-
"description": "A named responsive layout. `split` is list/detail (1:2, list ≥ 240px), `split-wide` is nav/content (1:3, nav ≥ 280px). Each collapses to one column on the width of its OWN container — `split` below `sm` (640px), `split-wide` below `md` (768px) — so a split nested inside another split, or beside an open DetailPanel, collapses when it runs out of room rather than when the window does. Wins over `columns` / `minColumnWidth`.",
|
|
3109
|
+
"description": "A named responsive layout. `split` is list/detail (1:2, list ≥ 240px), `split-wide` is nav/content (1:3, nav ≥ 280px). Each collapses to one column on the width of its OWN container — `split` below `sm` (640px), `split-wide` below `md` (768px) — so a split nested inside another split, or beside an open DetailPanel, collapses when it runs out of room rather than when the window does. `content-aside` is a reading column beside an `Aside` (`asideW`, 320px), one column below `md`. Wins over `columns` / `minColumnWidth`.",
|
|
2736
3110
|
"name": "layout",
|
|
2737
3111
|
"required": false,
|
|
2738
|
-
"type": "GridLayout"
|
|
3112
|
+
"type": "GridLayout",
|
|
3113
|
+
"union": [
|
|
3114
|
+
"split",
|
|
3115
|
+
"split-wide",
|
|
3116
|
+
"content-aside"
|
|
3117
|
+
]
|
|
2739
3118
|
},
|
|
2740
3119
|
{
|
|
2741
3120
|
"description": "An explicit track list, for columns that are not all fractions: a size token for a fixed track (`['1fr', 'asideW']`), or `minmax()` / `fit-content()` of tokens and fractions (`'minmax(gridColXs, 1fr)'`). A px is a type error. Web only — on native it falls back to equal columns, one per track. Wins over `columns` / `minColumnWidth`; `layout` wins over it.",
|
|
@@ -2743,6 +3122,12 @@
|
|
|
2743
3122
|
"required": false,
|
|
2744
3123
|
"type": "readonly GridTrack[]"
|
|
2745
3124
|
},
|
|
3125
|
+
{
|
|
3126
|
+
"description": "The Grid's outer element: with a `layout`, the wrapper its container query measures (hand it to `useContainerBelow` to follow the same collapse); otherwise the grid itself. Web only: on native the ref is not attached.",
|
|
3127
|
+
"name": "ref",
|
|
3128
|
+
"required": false,
|
|
3129
|
+
"type": "Ref<HTMLDivElement>"
|
|
3130
|
+
},
|
|
2746
3131
|
{
|
|
2747
3132
|
"name": "children",
|
|
2748
3133
|
"required": true,
|
|
@@ -2807,6 +3192,12 @@
|
|
|
2807
3192
|
"required": false,
|
|
2808
3193
|
"type": "'start' | 'center' | 'end'"
|
|
2809
3194
|
},
|
|
3195
|
+
{
|
|
3196
|
+
"description": "The heading's id: an in-page link's target (`href=\"#id\"`), an `aria-labelledby` reference.",
|
|
3197
|
+
"name": "id",
|
|
3198
|
+
"required": false,
|
|
3199
|
+
"type": "string"
|
|
3200
|
+
},
|
|
2810
3201
|
{
|
|
2811
3202
|
"name": "children",
|
|
2812
3203
|
"required": true,
|
|
@@ -3728,6 +4119,68 @@
|
|
|
3728
4119
|
"props": null,
|
|
3729
4120
|
"sourcePath": "packages/ui/src/components/Listbox/Listbox.tsx"
|
|
3730
4121
|
},
|
|
4122
|
+
"LiveRegion": {
|
|
4123
|
+
"importPath": "@duro-app/ui",
|
|
4124
|
+
"kind": "component",
|
|
4125
|
+
"meta": {
|
|
4126
|
+
"description": "Tells assistive tech about a change that has no focus move: a polite (role=\"status\") or assertive (role=\"alert\") region. Always mounted — render it empty and change its content to announce; visuallyHidden keeps it off screen.",
|
|
4127
|
+
"example": "<LiveRegion visuallyHidden>{copied ? 'Link copied' : ''}</LiveRegion>",
|
|
4128
|
+
"relatedTo": [
|
|
4129
|
+
{
|
|
4130
|
+
"component": "VisuallyHidden",
|
|
4131
|
+
"kind": "contrast",
|
|
4132
|
+
"relationship": "VisuallyHidden hides static text; LiveRegion visuallyHidden announces changing text"
|
|
4133
|
+
},
|
|
4134
|
+
{
|
|
4135
|
+
"component": "CodeBlock",
|
|
4136
|
+
"kind": "composition",
|
|
4137
|
+
"relationship": "CodeBlock announces \"copied\" through a LiveRegion"
|
|
4138
|
+
}
|
|
4139
|
+
],
|
|
4140
|
+
"whenNotToUse": [
|
|
4141
|
+
"A message that also needs to be seen and dismissed — use Toast (it announces itself)",
|
|
4142
|
+
"An inline field error — use Field.Error"
|
|
4143
|
+
],
|
|
4144
|
+
"whenToUse": [
|
|
4145
|
+
"Confirming an action that leaves focus where it is (\"Link copied\", \"Saved\")",
|
|
4146
|
+
"A result that arrives later (\"12 results\", \"Answer ready\")",
|
|
4147
|
+
"An error the person must hear now — politeness=\"assertive\""
|
|
4148
|
+
]
|
|
4149
|
+
},
|
|
4150
|
+
"name": "LiveRegion",
|
|
4151
|
+
"props": [
|
|
4152
|
+
{
|
|
4153
|
+
"description": "What to announce. Change it to announce; leave it empty when there is nothing to say — never unmount the region to clear it.",
|
|
4154
|
+
"name": "children",
|
|
4155
|
+
"required": false,
|
|
4156
|
+
"type": "ReactNode"
|
|
4157
|
+
},
|
|
4158
|
+
{
|
|
4159
|
+
"default": "'polite'",
|
|
4160
|
+
"description": "`polite` (default) waits for the screen reader to finish (`role=\"status\"`): \"Copied\", \"3 results\". `assertive` interrupts (`role=\"alert\"`): only for what the person must hear now, such as an error that blocks them.",
|
|
4161
|
+
"name": "politeness",
|
|
4162
|
+
"required": false,
|
|
4163
|
+
"type": "LiveRegionPoliteness",
|
|
4164
|
+
"union": [
|
|
4165
|
+
"polite",
|
|
4166
|
+
"assertive"
|
|
4167
|
+
]
|
|
4168
|
+
},
|
|
4169
|
+
{
|
|
4170
|
+
"default": "false",
|
|
4171
|
+
"description": "Keeps the region off screen and in the accessibility tree. Default false.",
|
|
4172
|
+
"name": "visuallyHidden",
|
|
4173
|
+
"required": false,
|
|
4174
|
+
"type": "boolean"
|
|
4175
|
+
},
|
|
4176
|
+
{
|
|
4177
|
+
"name": "id",
|
|
4178
|
+
"required": false,
|
|
4179
|
+
"type": "string"
|
|
4180
|
+
}
|
|
4181
|
+
],
|
|
4182
|
+
"sourcePath": "packages/ui/src/components/LiveRegion/LiveRegion.tsx"
|
|
4183
|
+
},
|
|
3731
4184
|
"Menu": {
|
|
3732
4185
|
"importPath": "@duro-app/ui",
|
|
3733
4186
|
"kind": "compound",
|
|
@@ -3895,9 +4348,81 @@
|
|
|
3895
4348
|
],
|
|
3896
4349
|
"sourcePath": "packages/ui/src/components/Menu/Menu.tsx"
|
|
3897
4350
|
}
|
|
3898
|
-
},
|
|
3899
|
-
"props": null,
|
|
3900
|
-
"sourcePath": "packages/ui/src/components/Menu/Menu.tsx"
|
|
4351
|
+
},
|
|
4352
|
+
"props": null,
|
|
4353
|
+
"sourcePath": "packages/ui/src/components/Menu/Menu.tsx"
|
|
4354
|
+
},
|
|
4355
|
+
"Meter": {
|
|
4356
|
+
"importPath": "@duro-app/ui",
|
|
4357
|
+
"kind": "component",
|
|
4358
|
+
"meta": {
|
|
4359
|
+
"description": "A scalar inside a known range — WIP 2 of 3, a milestone 40% done — as role=\"meter\" with a value text, drawn as a thin bar (the meterH token). The label is the accessible name; valueText says the value in words.",
|
|
4360
|
+
"example": "<Meter label=\"In progress WIP\" value={2} max={3} valueText=\"2 of 3\" />\n<Meter label=\"Milestone done\" value={0.4} tone=\"success\" />",
|
|
4361
|
+
"relatedTo": [
|
|
4362
|
+
{
|
|
4363
|
+
"component": "Badge",
|
|
4364
|
+
"kind": "contrast",
|
|
4365
|
+
"relationship": "Badge states a status or a count; Meter shows a level within a range"
|
|
4366
|
+
}
|
|
4367
|
+
],
|
|
4368
|
+
"whenNotToUse": [
|
|
4369
|
+
"Progress of a task that is still running — use Spinner (or a determinate progress pattern)",
|
|
4370
|
+
"Picking a value — use an input; a meter has no thumb",
|
|
4371
|
+
"A status with no range (ok/failing) — use Badge or StatusIcon"
|
|
4372
|
+
],
|
|
4373
|
+
"whenToUse": [
|
|
4374
|
+
"A level against a limit or a total: WIP against its limit, tasks done in a milestone, quota used",
|
|
4375
|
+
"Beside a count, when the proportion matters more than the number"
|
|
4376
|
+
]
|
|
4377
|
+
},
|
|
4378
|
+
"name": "Meter",
|
|
4379
|
+
"props": [
|
|
4380
|
+
{
|
|
4381
|
+
"name": "value",
|
|
4382
|
+
"required": true,
|
|
4383
|
+
"type": "number"
|
|
4384
|
+
},
|
|
4385
|
+
{
|
|
4386
|
+
"default": "0",
|
|
4387
|
+
"description": "Defaults to 0.",
|
|
4388
|
+
"name": "min",
|
|
4389
|
+
"required": false,
|
|
4390
|
+
"type": "number"
|
|
4391
|
+
},
|
|
4392
|
+
{
|
|
4393
|
+
"default": "1",
|
|
4394
|
+
"description": "Defaults to 1, so a fraction needs nothing else.",
|
|
4395
|
+
"name": "max",
|
|
4396
|
+
"required": false,
|
|
4397
|
+
"type": "number"
|
|
4398
|
+
},
|
|
4399
|
+
{
|
|
4400
|
+
"description": "The accessible name, e.g. \"In progress WIP\".",
|
|
4401
|
+
"name": "label",
|
|
4402
|
+
"required": true,
|
|
4403
|
+
"type": "string"
|
|
4404
|
+
},
|
|
4405
|
+
{
|
|
4406
|
+
"description": "What screen readers read for the value, e.g. \"4 of 3, over the limit\". Defaults to the percentage.",
|
|
4407
|
+
"name": "valueText",
|
|
4408
|
+
"required": false,
|
|
4409
|
+
"type": "string"
|
|
4410
|
+
},
|
|
4411
|
+
{
|
|
4412
|
+
"default": "'accent'",
|
|
4413
|
+
"description": "The fill's colour; defaults to accent.",
|
|
4414
|
+
"name": "tone",
|
|
4415
|
+
"required": false,
|
|
4416
|
+
"type": "MeterTone",
|
|
4417
|
+
"union": [
|
|
4418
|
+
"accent",
|
|
4419
|
+
"success",
|
|
4420
|
+
"warning",
|
|
4421
|
+
"error"
|
|
4422
|
+
]
|
|
4423
|
+
}
|
|
4424
|
+
],
|
|
4425
|
+
"sourcePath": "packages/ui/src/components/Meter/Meter.tsx"
|
|
3901
4426
|
},
|
|
3902
4427
|
"Node": {
|
|
3903
4428
|
"importPath": "@duro-app/diagrams",
|
|
@@ -4467,6 +4992,50 @@
|
|
|
4467
4992
|
"props": null,
|
|
4468
4993
|
"sourcePath": "packages/ui/src/components/Popover/Popover.tsx"
|
|
4469
4994
|
},
|
|
4995
|
+
"Prose": {
|
|
4996
|
+
"importPath": "@duro-app/ui",
|
|
4997
|
+
"kind": "component",
|
|
4998
|
+
"meta": {
|
|
4999
|
+
"description": "The container for HTML Duro does not author — rendered Markdown, CMS output: headings, paragraphs, lists, tables, blockquotes, inline code, links and images are styled from tokens by descendant rules scoped to it (plain CSS in dist/index.css, :where() and its own cascade layer). Duro components inside it keep their styles, and an app's own CSS wins over every Prose rule. Web only.",
|
|
5000
|
+
"example": "<Prose>\n <ReactMarkdown components={{pre: ({children}) => <CodeBlock copyLabel=\"Copy\" copiedLabel=\"Copied\">{children}</CodeBlock>}}>\n {body}\n </ReactMarkdown>\n</Prose>",
|
|
5001
|
+
"relatedTo": [
|
|
5002
|
+
{
|
|
5003
|
+
"component": "CodeBlock",
|
|
5004
|
+
"kind": "composition",
|
|
5005
|
+
"relationship": "Pass CodeBlock as the Markdown renderer's pre, for a copy button"
|
|
5006
|
+
},
|
|
5007
|
+
{
|
|
5008
|
+
"component": "TextLink",
|
|
5009
|
+
"kind": "composition",
|
|
5010
|
+
"relationship": "Pass TextLink as the renderer's a, for onNavigate; it keeps its own styles inside Prose"
|
|
5011
|
+
}
|
|
5012
|
+
],
|
|
5013
|
+
"whenNotToUse": [
|
|
5014
|
+
"Text you write as components — use Heading, Text and Stack",
|
|
5015
|
+
"A short label or paragraph — use Text"
|
|
5016
|
+
],
|
|
5017
|
+
"whenToUse": [
|
|
5018
|
+
"The body of a docs page rendered from Markdown",
|
|
5019
|
+
"Any HTML produced by a renderer you do not write as JSX"
|
|
5020
|
+
]
|
|
5021
|
+
},
|
|
5022
|
+
"name": "Prose",
|
|
5023
|
+
"props": [
|
|
5024
|
+
{
|
|
5025
|
+
"description": "HTML Duro does not author: the output of a Markdown renderer.",
|
|
5026
|
+
"name": "children",
|
|
5027
|
+
"required": true,
|
|
5028
|
+
"type": "ReactNode"
|
|
5029
|
+
},
|
|
5030
|
+
{
|
|
5031
|
+
"description": "The container element.",
|
|
5032
|
+
"name": "ref",
|
|
5033
|
+
"required": false,
|
|
5034
|
+
"type": "Ref<HTMLDivElement>"
|
|
5035
|
+
}
|
|
5036
|
+
],
|
|
5037
|
+
"sourcePath": "packages/ui/src/components/Prose/Prose.tsx"
|
|
5038
|
+
},
|
|
4470
5039
|
"RadioGroup": {
|
|
4471
5040
|
"importPath": "@duro-app/ui",
|
|
4472
5041
|
"kind": "compound",
|
|
@@ -4968,6 +5537,12 @@
|
|
|
4968
5537
|
"required": true,
|
|
4969
5538
|
"type": "ReactNode"
|
|
4970
5539
|
},
|
|
5540
|
+
{
|
|
5541
|
+
"description": "Names the navigation landmark (\"Main\", \"Settings\"). Give one whenever the page has another nav (a breadcrumb, a pager): screen readers list landmarks by name.",
|
|
5542
|
+
"name": "aria-label",
|
|
5543
|
+
"required": false,
|
|
5544
|
+
"type": "string"
|
|
5545
|
+
},
|
|
4971
5546
|
{
|
|
4972
5547
|
"name": "value",
|
|
4973
5548
|
"required": false,
|
|
@@ -6617,11 +7192,254 @@
|
|
|
6617
7192
|
],
|
|
6618
7193
|
"sourcePath": "packages/ui/src/components/ThemeProvider/ThemeProvider.tsx"
|
|
6619
7194
|
},
|
|
7195
|
+
"Time": {
|
|
7196
|
+
"importPath": "@duro-app/ui",
|
|
7197
|
+
"kind": "component",
|
|
7198
|
+
"meta": {
|
|
7199
|
+
"description": "A date or time in running text as a <time> element: the visible text comes from you, the exact instant goes in dateTime (an ISO string) and title. relative(date, {now, locale}) gives the text on Intl.RelativeTimeFormat (\"3 days ago\", \"il y a 3 jours\"); now is required, so the server and the client render the same string. Web only.",
|
|
7200
|
+
"example": "<Time dateTime={doc.lastCommitAt} title={formatFull(doc.lastCommitAt, locale)}>\n {relative(doc.lastCommitAt, {now: loaderNow, locale})}\n</Time>",
|
|
7201
|
+
"whenNotToUse": [
|
|
7202
|
+
"A date the person edits — use an Input",
|
|
7203
|
+
"A live countdown or a clock — Time renders once from the now you pass"
|
|
7204
|
+
],
|
|
7205
|
+
"whenToUse": [
|
|
7206
|
+
"When something happened: \"Updated 3 days ago\", a commit date, a last-indexed time",
|
|
7207
|
+
"Any date shown as relative text whose exact value should stay available"
|
|
7208
|
+
]
|
|
7209
|
+
},
|
|
7210
|
+
"name": "Time",
|
|
7211
|
+
"props": [
|
|
7212
|
+
{
|
|
7213
|
+
"description": "The instant, machine-readable: a `Date` (written as its ISO string) or an ISO 8601 string, which is passed through unchanged.",
|
|
7214
|
+
"name": "dateTime",
|
|
7215
|
+
"required": true,
|
|
7216
|
+
"type": "Date | string"
|
|
7217
|
+
},
|
|
7218
|
+
{
|
|
7219
|
+
"description": "The exact date and time, shown on hover (\"8 October 2026, 14:03 UTC\"), formatted by you in the reader's locale.",
|
|
7220
|
+
"name": "title",
|
|
7221
|
+
"required": false,
|
|
7222
|
+
"type": "string"
|
|
7223
|
+
},
|
|
7224
|
+
{
|
|
7225
|
+
"description": "What the reader sees: a relative label from `relative()`, or a date.",
|
|
7226
|
+
"name": "children",
|
|
7227
|
+
"required": true,
|
|
7228
|
+
"type": "ReactNode"
|
|
7229
|
+
}
|
|
7230
|
+
],
|
|
7231
|
+
"sourcePath": "packages/ui/src/components/Time/Time.tsx"
|
|
7232
|
+
},
|
|
7233
|
+
"Timeline": {
|
|
7234
|
+
"importPath": "@duro-app/ui",
|
|
7235
|
+
"kind": "compound",
|
|
7236
|
+
"meta": {
|
|
7237
|
+
"anatomy": {
|
|
7238
|
+
"required": [
|
|
7239
|
+
"Root",
|
|
7240
|
+
"Row",
|
|
7241
|
+
"Bar"
|
|
7242
|
+
]
|
|
7243
|
+
},
|
|
7244
|
+
"description": "Rows of date bars against a date axis (milestones, releases, sprints), with a progress fill per bar and a today marker. Dates are calendar days (YYYY-MM-DD, UTC). A bar is a toggle button (selected/onSelect), can be a DragDrop.Zone target (dropZone), and its edges are keyboard sliders whose value text is a date (onStartChange/onEndChange).",
|
|
7245
|
+
"example": "<Timeline.Root aria-label=\"Milestones\" start=\"2026-09-21\" end=\"2026-11-08\" today=\"2026-10-08\">\n {milestones.map((m) => (\n <Timeline.Row key={m.id} label={m.title} description={`${m.done} of ${m.total} done`}>\n <Timeline.Bar\n label={m.title}\n start={m.start}\n end={m.end}\n progress={m.done / m.total}\n selected={selected === m.id}\n onSelect={() => select(m.id)}\n onEndChange={(end) => reschedule(m.id, {end})}\n dropZone={{id: `ms:${m.id}`, label: m.title}}\n >\n {m.done}/{m.total}\n </Timeline.Bar>\n </Timeline.Row>\n ))}\n</Timeline.Root>",
|
|
7246
|
+
"relatedTo": [
|
|
7247
|
+
{
|
|
7248
|
+
"component": "DragDrop",
|
|
7249
|
+
"kind": "composition",
|
|
7250
|
+
"relationship": "Pass dropZone to make a bar a DragDrop.Zone inside a DragDrop.Root"
|
|
7251
|
+
},
|
|
7252
|
+
{
|
|
7253
|
+
"component": "Meter",
|
|
7254
|
+
"kind": "contrast",
|
|
7255
|
+
"relationship": "Meter shows one level; Timeline places spans of time"
|
|
7256
|
+
}
|
|
7257
|
+
],
|
|
7258
|
+
"whenNotToUse": [
|
|
7259
|
+
"A schedule by hour — a calendar grid fits (timeGutterW, dayHeaderH)",
|
|
7260
|
+
"A dependency graph or a full Gantt chart with links — this draws bars, not edges",
|
|
7261
|
+
"Moving dates with the pointer — edges are keyboard sliders; give a date field for the rest"
|
|
7262
|
+
],
|
|
7263
|
+
"whenToUse": [
|
|
7264
|
+
"Milestones or releases over weeks, where the overlap and today matter",
|
|
7265
|
+
"Dropping work onto a milestone (bars as DragDrop zones)"
|
|
7266
|
+
]
|
|
7267
|
+
},
|
|
7268
|
+
"name": "Timeline",
|
|
7269
|
+
"parts": {
|
|
7270
|
+
"Bar": {
|
|
7271
|
+
"name": "Bar",
|
|
7272
|
+
"props": [
|
|
7273
|
+
{
|
|
7274
|
+
"name": "start",
|
|
7275
|
+
"required": true,
|
|
7276
|
+
"type": "TimelineDate"
|
|
7277
|
+
},
|
|
7278
|
+
{
|
|
7279
|
+
"name": "end",
|
|
7280
|
+
"required": true,
|
|
7281
|
+
"type": "TimelineDate"
|
|
7282
|
+
},
|
|
7283
|
+
{
|
|
7284
|
+
"description": "The bar's accessible name.",
|
|
7285
|
+
"name": "label",
|
|
7286
|
+
"required": true,
|
|
7287
|
+
"type": "string"
|
|
7288
|
+
},
|
|
7289
|
+
{
|
|
7290
|
+
"description": "Done fraction, 0–1, drawn as a fill from the start edge.",
|
|
7291
|
+
"name": "progress",
|
|
7292
|
+
"required": false,
|
|
7293
|
+
"type": "number"
|
|
7294
|
+
},
|
|
7295
|
+
{
|
|
7296
|
+
"default": "'default'",
|
|
7297
|
+
"description": "`planned` draws a dashed outline; `done` the success tone.",
|
|
7298
|
+
"name": "tone",
|
|
7299
|
+
"required": false,
|
|
7300
|
+
"type": "'default' | 'planned' | 'done'"
|
|
7301
|
+
},
|
|
7302
|
+
{
|
|
7303
|
+
"description": "Makes the bar a toggle button (aria-pressed).",
|
|
7304
|
+
"name": "selected",
|
|
7305
|
+
"required": false,
|
|
7306
|
+
"type": "boolean"
|
|
7307
|
+
},
|
|
7308
|
+
{
|
|
7309
|
+
"name": "onSelect",
|
|
7310
|
+
"required": false,
|
|
7311
|
+
"type": "() => void"
|
|
7312
|
+
},
|
|
7313
|
+
{
|
|
7314
|
+
"description": "Adds the start-edge slider.",
|
|
7315
|
+
"name": "onStartChange",
|
|
7316
|
+
"required": false,
|
|
7317
|
+
"type": "(date: TimelineDate) => void"
|
|
7318
|
+
},
|
|
7319
|
+
{
|
|
7320
|
+
"description": "Adds the end-edge slider.",
|
|
7321
|
+
"name": "onEndChange",
|
|
7322
|
+
"required": false,
|
|
7323
|
+
"type": "(date: TimelineDate) => void"
|
|
7324
|
+
},
|
|
7325
|
+
{
|
|
7326
|
+
"description": "Names of the edge sliders; default \"<label>, start\" / \"<label>, end\".",
|
|
7327
|
+
"name": "startLabel",
|
|
7328
|
+
"required": false,
|
|
7329
|
+
"type": "string"
|
|
7330
|
+
},
|
|
7331
|
+
{
|
|
7332
|
+
"name": "endLabel",
|
|
7333
|
+
"required": false,
|
|
7334
|
+
"type": "string"
|
|
7335
|
+
},
|
|
7336
|
+
{
|
|
7337
|
+
"description": "Makes the bar a DragDrop.Zone (needs a DragDrop.Root above).",
|
|
7338
|
+
"name": "dropZone",
|
|
7339
|
+
"required": false,
|
|
7340
|
+
"type": "TimelineBarDropZone<T>"
|
|
7341
|
+
},
|
|
7342
|
+
{
|
|
7343
|
+
"description": "Text inside the bar, e.g. \"4/7\".",
|
|
7344
|
+
"name": "children",
|
|
7345
|
+
"required": false,
|
|
7346
|
+
"type": "ReactNode"
|
|
7347
|
+
}
|
|
7348
|
+
],
|
|
7349
|
+
"sourcePath": "packages/ui/src/components/Timeline/Timeline.tsx"
|
|
7350
|
+
},
|
|
7351
|
+
"Root": {
|
|
7352
|
+
"name": "Root",
|
|
7353
|
+
"props": [
|
|
7354
|
+
{
|
|
7355
|
+
"description": "First day on the axis.",
|
|
7356
|
+
"name": "start",
|
|
7357
|
+
"required": true,
|
|
7358
|
+
"type": "TimelineDate"
|
|
7359
|
+
},
|
|
7360
|
+
{
|
|
7361
|
+
"description": "Last day on the axis (included).",
|
|
7362
|
+
"name": "end",
|
|
7363
|
+
"required": true,
|
|
7364
|
+
"type": "TimelineDate"
|
|
7365
|
+
},
|
|
7366
|
+
{
|
|
7367
|
+
"description": "Draws the today marker when inside the range.",
|
|
7368
|
+
"name": "today",
|
|
7369
|
+
"required": false,
|
|
7370
|
+
"type": "TimelineDate"
|
|
7371
|
+
},
|
|
7372
|
+
{
|
|
7373
|
+
"description": "The timeline's accessible name.",
|
|
7374
|
+
"name": "aria-label",
|
|
7375
|
+
"required": true,
|
|
7376
|
+
"type": "string"
|
|
7377
|
+
},
|
|
7378
|
+
{
|
|
7379
|
+
"description": "Text above the row labels, e.g. \"Milestones\".",
|
|
7380
|
+
"name": "heading",
|
|
7381
|
+
"required": false,
|
|
7382
|
+
"type": "ReactNode"
|
|
7383
|
+
},
|
|
7384
|
+
{
|
|
7385
|
+
"default": "'Today'",
|
|
7386
|
+
"description": "The today marker's text.",
|
|
7387
|
+
"name": "todayLabel",
|
|
7388
|
+
"required": false,
|
|
7389
|
+
"type": "string"
|
|
7390
|
+
},
|
|
7391
|
+
{
|
|
7392
|
+
"description": "BCP 47 locale for the default date format.",
|
|
7393
|
+
"name": "locale",
|
|
7394
|
+
"required": false,
|
|
7395
|
+
"type": "string"
|
|
7396
|
+
},
|
|
7397
|
+
{
|
|
7398
|
+
"description": "Formats a day for the axis and the edge sliders' value text.",
|
|
7399
|
+
"name": "formatDate",
|
|
7400
|
+
"required": false,
|
|
7401
|
+
"type": "(date: TimelineDate) => string"
|
|
7402
|
+
},
|
|
7403
|
+
{
|
|
7404
|
+
"name": "children",
|
|
7405
|
+
"required": true,
|
|
7406
|
+
"type": "ReactNode"
|
|
7407
|
+
}
|
|
7408
|
+
],
|
|
7409
|
+
"sourcePath": "packages/ui/src/components/Timeline/Timeline.tsx"
|
|
7410
|
+
},
|
|
7411
|
+
"Row": {
|
|
7412
|
+
"name": "Row",
|
|
7413
|
+
"props": [
|
|
7414
|
+
{
|
|
7415
|
+
"description": "The row's name, shown in the label column.",
|
|
7416
|
+
"name": "label",
|
|
7417
|
+
"required": true,
|
|
7418
|
+
"type": "string"
|
|
7419
|
+
},
|
|
7420
|
+
{
|
|
7421
|
+
"description": "A second line under the label, e.g. \"4 of 7 done\".",
|
|
7422
|
+
"name": "description",
|
|
7423
|
+
"required": false,
|
|
7424
|
+
"type": "ReactNode"
|
|
7425
|
+
},
|
|
7426
|
+
{
|
|
7427
|
+
"name": "children",
|
|
7428
|
+
"required": false,
|
|
7429
|
+
"type": "ReactNode"
|
|
7430
|
+
}
|
|
7431
|
+
],
|
|
7432
|
+
"sourcePath": "packages/ui/src/components/Timeline/Timeline.tsx"
|
|
7433
|
+
}
|
|
7434
|
+
},
|
|
7435
|
+
"props": null,
|
|
7436
|
+
"sourcePath": "packages/ui/src/components/Timeline/Timeline.tsx"
|
|
7437
|
+
},
|
|
6620
7438
|
"ToastProvider": {
|
|
6621
7439
|
"importPath": "@duro-app/ui",
|
|
6622
7440
|
"kind": "provider",
|
|
6623
7441
|
"meta": {
|
|
6624
|
-
"description": "Transient, self-dismissing notification for the RESULT of an action (saved, sent, revoked, failed). Mount <ToastProvider> once at the app root and call useToast().toast() from anywhere. Toasts stack and portal above dialogs.",
|
|
7442
|
+
"description": "Transient, self-dismissing notification for the RESULT of an action (saved, sent, revoked, failed). Mount <ToastProvider> once at the app root and call useToast().toast() from anywhere. Toasts stack and portal above dialogs. Variants: success, info, warning, error. The countdown pauses while a toast is hovered or holds focus, and every toast has a close button (`dismissLabel` on the provider names it).",
|
|
6625
7443
|
"example": "function Example() {\n const {toast} = useToast()\n return (\n <Button onClick={() => toast({variant: 'success', message: 'Grant revoked', action: {label: 'Undo', onClick: restore}})}>\n Revoke\n </Button>\n )\n}",
|
|
6626
7444
|
"relatedTo": [
|
|
6627
7445
|
{
|
|
@@ -6643,11 +7461,19 @@
|
|
|
6643
7461
|
"whenToUse": [
|
|
6644
7462
|
"Confirming an action succeeded (e.g. \"Grant revoked\")",
|
|
6645
7463
|
"Reporting an action failed, with the reason",
|
|
6646
|
-
"Reversible actions that benefit from an inline Undo"
|
|
7464
|
+
"Reversible actions that benefit from an inline Undo",
|
|
7465
|
+
"A soft limit crossed but allowed (variant warning), e.g. a column over its WIP limit"
|
|
6647
7466
|
]
|
|
6648
7467
|
},
|
|
6649
7468
|
"name": "ToastProvider",
|
|
6650
7469
|
"props": [
|
|
7470
|
+
{
|
|
7471
|
+
"default": "'Dismiss'",
|
|
7472
|
+
"description": "Accessible name of each toast's close button, e.g. from the app's message catalog.",
|
|
7473
|
+
"name": "dismissLabel",
|
|
7474
|
+
"required": false,
|
|
7475
|
+
"type": "string"
|
|
7476
|
+
},
|
|
6651
7477
|
{
|
|
6652
7478
|
"name": "children",
|
|
6653
7479
|
"required": true,
|
|
@@ -7318,6 +8144,25 @@
|
|
|
7318
8144
|
],
|
|
7319
8145
|
"sourcePath": "packages/ui/src/components/VisuallyHidden/VisuallyHidden.tsx"
|
|
7320
8146
|
},
|
|
8147
|
+
"relative": {
|
|
8148
|
+
"importPath": "@duro-app/ui",
|
|
8149
|
+
"kind": "function",
|
|
8150
|
+
"meta": {
|
|
8151
|
+
"description": "A date or time in running text as a <time> element: the visible text comes from you, the exact instant goes in dateTime (an ISO string) and title. relative(date, {now, locale}) gives the text on Intl.RelativeTimeFormat (\"3 days ago\", \"il y a 3 jours\"); now is required, so the server and the client render the same string. Web only.",
|
|
8152
|
+
"example": "<Time dateTime={doc.lastCommitAt} title={formatFull(doc.lastCommitAt, locale)}>\n {relative(doc.lastCommitAt, {now: loaderNow, locale})}\n</Time>",
|
|
8153
|
+
"whenNotToUse": [
|
|
8154
|
+
"A date the person edits — use an Input",
|
|
8155
|
+
"A live countdown or a clock — Time renders once from the now you pass"
|
|
8156
|
+
],
|
|
8157
|
+
"whenToUse": [
|
|
8158
|
+
"When something happened: \"Updated 3 days ago\", a commit date, a last-indexed time",
|
|
8159
|
+
"Any date shown as relative text whose exact value should stay available"
|
|
8160
|
+
]
|
|
8161
|
+
},
|
|
8162
|
+
"name": "relative",
|
|
8163
|
+
"props": [],
|
|
8164
|
+
"sourcePath": "packages/ui/src/components/Time/relative.ts"
|
|
8165
|
+
},
|
|
7321
8166
|
"useColorMode": {
|
|
7322
8167
|
"importPath": "@duro-app/ui",
|
|
7323
8168
|
"kind": "hook",
|
|
@@ -7359,6 +8204,14 @@
|
|
|
7359
8204
|
"props": [],
|
|
7360
8205
|
"sourcePath": "packages/ui/src/components/ColorMode/ColorMode.tsx"
|
|
7361
8206
|
},
|
|
8207
|
+
"useContainerBelow": {
|
|
8208
|
+
"importPath": "@duro-app/ui",
|
|
8209
|
+
"kind": "hook",
|
|
8210
|
+
"meta": null,
|
|
8211
|
+
"name": "useContainerBelow",
|
|
8212
|
+
"props": [],
|
|
8213
|
+
"sourcePath": "packages/ui/src/hooks/useContainerBelow.ts"
|
|
8214
|
+
},
|
|
7362
8215
|
"useContainerQuery": {
|
|
7363
8216
|
"importPath": "@duro-app/ui",
|
|
7364
8217
|
"kind": "hook",
|
|
@@ -7419,14 +8272,17 @@
|
|
|
7419
8272
|
"kind": "hook",
|
|
7420
8273
|
"meta": {
|
|
7421
8274
|
"anatomy": {
|
|
8275
|
+
"optional": [
|
|
8276
|
+
"Handle"
|
|
8277
|
+
],
|
|
7422
8278
|
"required": [
|
|
7423
8279
|
"Root",
|
|
7424
8280
|
"Zone",
|
|
7425
8281
|
"Item"
|
|
7426
8282
|
]
|
|
7427
8283
|
},
|
|
7428
|
-
"description": "Move items between zones
|
|
7429
|
-
"example": "<DragDrop.Root
|
|
8284
|
+
"description": "Move items between zones by pointer (mouse, pen and touch through one pointer-event path; touch holds briefly, then drags) or by keyboard (a Handle per item: Space picks up, arrows move, Space drops, Escape cancels). The innermost accepting zone wins, so a zone nested in an Item (a card in a column) takes its own drops; a zone can refuse with a reason that is shown and announced. Placeholders, edge auto-scroll and list-style announcements (through `announce`, for catalog strings) come with it.",
|
|
8285
|
+
"example": "<DragDrop.Root\n onDrop={({item, target}) => move(item.id, target.zone, target.index)}\n renderPlaceholder={({label}) => <Text variant=\"caption\">→ {label}</Text>}\n announce={(e) => t(`board.drag.${e.kind}`, e)}\n>\n {columns.map((col) => (\n <DragDrop.Zone key={col.id} id={col.id} label={col.name} orientation=\"vertical\" list\n accepts={(item) => item.data.kind === 'task' || {ok: false, reason: t('board.attachOnCard')}}>\n {col.cards.map((card) => (\n <DragDrop.Item key={card.id} id={card.id} zone={col.id} label={card.title} data={card}>\n <DragDrop.Handle>\n <DragDrop.Zone id={`attach:${card.id}`} label={card.title}\n accepts={(item) => item.data.kind === 'activity'}>\n <Card>{card.title}</Card>\n </DragDrop.Zone>\n </DragDrop.Handle>\n </DragDrop.Item>\n ))}\n </DragDrop.Zone>\n ))}\n</DragDrop.Root>",
|
|
7430
8286
|
"relatedTo": [
|
|
7431
8287
|
{
|
|
7432
8288
|
"component": "Tag",
|
|
@@ -7440,14 +8296,14 @@
|
|
|
7440
8296
|
}
|
|
7441
8297
|
],
|
|
7442
8298
|
"whenNotToUse": [
|
|
7443
|
-
"As the ONLY way to do something —
|
|
7444
|
-
"Long lists that scroll while dragging — the ghost follows the pointer but zones do not auto-scroll",
|
|
8299
|
+
"As the ONLY way to do something — WCAG 2.5.7 asks for a single-pointer alternative to dragging (a button or menu that moves the item); a Handle adds the keyboard path, not a click one",
|
|
7445
8300
|
"Sorting tabular data — sort the Table instead",
|
|
7446
8301
|
"React Native — Item renders its children without drag behaviour there"
|
|
7447
8302
|
],
|
|
7448
8303
|
"whenToUse": [
|
|
7449
8304
|
"Slotting things into places — people into approval gates, cards into columns, files into folders",
|
|
7450
|
-
"Reordering a short row or list when the order is visible and meaningful"
|
|
8305
|
+
"Reordering a short row or list when the order is visible and meaningful",
|
|
8306
|
+
"A board: columns as labelled lists (`list`), cards with a Handle, an attach zone nested in each card"
|
|
7451
8307
|
]
|
|
7452
8308
|
},
|
|
7453
8309
|
"name": "useDragDrop",
|
|
@@ -7484,7 +8340,7 @@
|
|
|
7484
8340
|
"importPath": "@duro-app/ui",
|
|
7485
8341
|
"kind": "hook",
|
|
7486
8342
|
"meta": {
|
|
7487
|
-
"description": "Transient, self-dismissing notification for the RESULT of an action (saved, sent, revoked, failed). Mount <ToastProvider> once at the app root and call useToast().toast() from anywhere. Toasts stack and portal above dialogs.",
|
|
8343
|
+
"description": "Transient, self-dismissing notification for the RESULT of an action (saved, sent, revoked, failed). Mount <ToastProvider> once at the app root and call useToast().toast() from anywhere. Toasts stack and portal above dialogs. Variants: success, info, warning, error. The countdown pauses while a toast is hovered or holds focus, and every toast has a close button (`dismissLabel` on the provider names it).",
|
|
7488
8344
|
"example": "function Example() {\n const {toast} = useToast()\n return (\n <Button onClick={() => toast({variant: 'success', message: 'Grant revoked', action: {label: 'Undo', onClick: restore}})}>\n Revoke\n </Button>\n )\n}",
|
|
7489
8345
|
"relatedTo": [
|
|
7490
8346
|
{
|
|
@@ -7506,7 +8362,8 @@
|
|
|
7506
8362
|
"whenToUse": [
|
|
7507
8363
|
"Confirming an action succeeded (e.g. \"Grant revoked\")",
|
|
7508
8364
|
"Reporting an action failed, with the reason",
|
|
7509
|
-
"Reversible actions that benefit from an inline Undo"
|
|
8365
|
+
"Reversible actions that benefit from an inline Undo",
|
|
8366
|
+
"A soft limit crossed but allowed (variant warning), e.g. a column over its WIP limit"
|
|
7510
8367
|
]
|
|
7511
8368
|
},
|
|
7512
8369
|
"name": "useToast",
|
|
@@ -9003,6 +9860,14 @@
|
|
|
9003
9860
|
{
|
|
9004
9861
|
"key": "dayHeaderH",
|
|
9005
9862
|
"value": "46px"
|
|
9863
|
+
},
|
|
9864
|
+
{
|
|
9865
|
+
"key": "timelineLabelW",
|
|
9866
|
+
"value": "180px"
|
|
9867
|
+
},
|
|
9868
|
+
{
|
|
9869
|
+
"key": "appBarH",
|
|
9870
|
+
"value": "61px"
|
|
9006
9871
|
}
|
|
9007
9872
|
],
|
|
9008
9873
|
"exportName": "sizes",
|
|
@@ -9153,7 +10018,7 @@
|
|
|
9153
10018
|
"importPath": "@duro-app/tokens/tokens/typography.css"
|
|
9154
10019
|
}
|
|
9155
10020
|
},
|
|
9156
|
-
"mockupCss": "/*\n * GENERATED by scripts/generate-mockup-css.mjs — do not edit.\n *\n * The design tokens as resolved values, for HTML that loads no stylesheet\n * (mockup artboards, static previews). Same names as vars.css; where vars.css\n * follows the live theme, this file carries every theme and switches on\n * <html data-theme=\"light|high-contrast\">.\n *\n * Inside the component library and the apps, never use this: go through\n * css.create() and the token imports, or vars.css from plain CSS.\n */\n:root {\n color-scheme: dark;\n /* colors */\n --duro-color-accent: #6aaffc;\n --duro-color-accent-contrast: #000000;\n --duro-color-accent-hover: #93c5fd;\n --duro-color-bg: #0f0f0f;\n --duro-color-bg-card: #1a1a1a;\n --duro-color-bg-card-hover: #242424;\n --duro-color-border: #333333;\n --duro-color-contrast-border: rgba(0, 0, 0, 0.42);\n --duro-color-contrast-surface: #f5f5f5;\n --duro-color-error: #f87171;\n --duro-color-error-bg: rgba(248, 113, 113, 0.1);\n --duro-color-error-border: rgba(248, 113, 113, 0.3);\n --duro-color-error-contrast: #000000;\n --duro-color-error-hover: #fca5a5;\n --duro-color-error-text: #fca5a5;\n --duro-color-fixed-light: #ffffff;\n --duro-color-highlight: #c084fc;\n --duro-color-highlight-bg: rgba(192, 132, 252, 0.1);\n --duro-color-highlight-border: rgba(192, 132, 252, 0.3);\n --duro-color-highlight-text: #d8b4fe;\n --duro-color-info: #6aaffc;\n --duro-color-info-bg: rgba(106, 175, 252, 0.1);\n --duro-color-info-border: rgba(106, 175, 252, 0.3);\n --duro-color-info-text: #93c5fd;\n --duro-color-inverse-border: rgba(0, 0, 0, 0.55);\n --duro-color-inverse-border-hover: rgba(0, 0, 0, 0.70);\n --duro-color-inverse-fill: rgba(0, 0, 0, 0.10);\n --duro-color-inverse-fill-hover: rgba(0, 0, 0, 0.18);\n --duro-color-on-contrast-surface: #1a1a1a;\n --duro-color-overlay-light: rgba(255, 255, 255, 0.78);\n --duro-color-scrim: rgba(0, 0, 0, 0.4);\n --duro-color-success: #22c55e;\n --duro-color-success-bg: rgba(34, 197, 94, 0.1);\n --duro-color-success-border: rgba(34, 197, 94, 0.3);\n --duro-color-success-text: #86efac;\n --duro-color-text: #e5e5e5;\n --duro-color-text-muted: #b0b0b0;\n --duro-color-warning: #fbbf24;\n --duro-color-warning-bg: rgba(251, 191, 36, 0.1);\n --duro-color-warning-border: rgba(251, 191, 36, 0.3);\n --duro-color-warning-text: #fde68a;\n /* shadows */\n --duro-shadow-drop-over: inset 0 0 0 2px #6aaffc;\n --duro-shadow-drop-ready: inset 0 0 0 1px #333333;\n --duro-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);\n --duro-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);\n --duro-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.3);\n /* spacing */\n --duro-spacing-lg: 24px;\n --duro-spacing-md: 16px;\n --duro-spacing-ms: 12px;\n --duro-spacing-sm: 8px;\n --duro-spacing-xl: 32px;\n --duro-spacing-xs: 4px;\n --duro-spacing-xxl: 48px;\n --duro-spacing-xxxl: 64px;\n /* microSpacing */\n --duro-micro-spacing-px1: 1px;\n --duro-micro-spacing-px2: 2px;\n --duro-micro-spacing-px3: 3px;\n --duro-micro-spacing-px5: 5px;\n --duro-micro-spacing-px6: 6px;\n /* radii */\n --duro-radius-full: 9999px;\n --duro-radius-lg: 16px;\n --duro-radius-md: 12px;\n --duro-radius-px6: 6px;\n --duro-radius-sm: 8px;\n --duro-radius-xs: 4px;\n /* sizes */\n --duro-size-aside-w: 320px;\n --duro-size-bar-h: 4px;\n --duro-size-canvas-min-h: 480px;\n --duro-size-check-mark-h: 9px;\n --duro-size-check-mark-w: 5px;\n --duro-size-chip: 24px;\n --duro-size-color-area-h: 150px;\n --duro-size-color-picker-w: 196px;\n --duro-size-color-preview-h: 22px;\n --duro-size-color-swatch: 20px;\n --duro-size-color-track-h: 12px;\n --duro-size-control-lg: 40px;\n --duro-size-control-md: 39px;\n --duro-size-control-sm: 28px;\n --duro-size-day-header-h: 46px;\n --duro-size-device-bar-w: 96px;\n --duro-size-dialog-lg: 680px;\n --duro-size-dialog-md: 520px;\n --duro-size-dialog-sm: 400px;\n --duro-size-divider: 1px;\n --duro-size-drop-zone-min-h: 128px;\n --duro-size-edge-fade: 32px;\n --duro-size-editor-min-h: 160px;\n --duro-size-embed-w: 550px;\n --duro-size-field-min-w: 160px;\n --duro-size-field-min-w-sm: 80px;\n --duro-size-glyph-md: 16px;\n --duro-size-glyph-sm: 12px;\n --duro-size-glyph-xs: 10px;\n --duro-size-grid-col-md: 280px;\n --duro-size-grid-col-sm: 240px;\n --duro-size-grid-col-xs: 200px;\n --duro-size-handle: 16px;\n --duro-size-icon-button: 32px;\n --duro-size-icon-button-sm: 28px;\n --duro-size-icon-lg: 24px;\n --duro-size-icon-md: 18px;\n --duro-size-icon-sm: 16px;\n --duro-size-icon-xl: 36px;\n --duro-size-icon-xxl: 48px;\n --duro-size-indicator: 18px;\n --duro-size-indicator-dot: 8px;\n --duro-size-label-min-w: 120px;\n --duro-size-list-max-h: 280px;\n --duro-size-list-max-h-sm: 200px;\n --duro-size-meter-h: 6px;\n --duro-size-nav-marker-h: 18px;\n --duro-size-nav-marker-w: 3px;\n --duro-size-page-lg: 1200px;\n --duro-size-page-md: 800px;\n --duro-size-page-sm: 600px;\n --duro-size-page-xl: 1440px;\n --duro-size-page-xs: 480px;\n --duro-size-palette-min-w: 96px;\n --duro-size-panel-lg: 640px;\n --duro-size-panel-md: 480px;\n --duro-size-panel-sm: 360px;\n --duro-size-placeholder-min-h: 80px;\n --duro-size-popover-w: 320px;\n --duro-size-popover-w-sm: 240px;\n --duro-size-popup-max-w: 280px;\n --duro-size-popup-min-w: 160px;\n --duro-size-preview-max-h: 320px;\n --duro-size-readout-w: 40px;\n --duro-size-scrollbar: 8px;\n --duro-size-sidebar-w: 240px;\n --duro-size-skeleton-chip-w: 96px;\n --duro-size-slider-w: 96px;\n --duro-size-spinner-lg: 40px;\n --duro-size-spinner-md: 24px;\n --duro-size-spinner-sm: 16px;\n --duro-size-swatch-h: 34px;\n --duro-size-swatch-w: 44px;\n --duro-size-switch-thumb: 16px;\n --duro-size-switch-track-h: 20px;\n --duro-size-switch-track-w: 36px;\n --duro-size-tab-indicator: 2px;\n --duro-size-time-gutter-w: 64px;\n --duro-size-toast-max-w: 440px;\n --duro-size-toolbar-h: 36px;\n --duro-size-touch-target: 44px;\n /* borders */\n --duro-border-accent: 3px;\n --duro-border-focus-offset: 2px;\n --duro-border-focus-offset-sm: 1px;\n --duro-border-focus-ring: 2px;\n --duro-border-hairline: 1px;\n --duro-border-strong: 2px;\n /* layers */\n --duro-layer-floating: 50;\n --duro-layer-floating-raised: 60;\n --duro-layer-modal: 1001;\n --duro-layer-modal-raised: 1002;\n --duro-layer-overlay: 1000;\n --duro-layer-popover: 1040;\n --duro-layer-popover-raised: 1041;\n --duro-layer-popup: 1050;\n --duro-layer-popup-backdrop: 1049;\n --duro-layer-portal: 1100;\n --duro-layer-raised: 1;\n --duro-layer-toast: 1060;\n /* effects */\n --duro-effect-overlay-blur: blur(2px);\n --duro-effect-surface-blur: blur(6px);\n /* layoutSpacing */\n --duro-layout-spacing-container-lg: 32px;\n --duro-layout-spacing-container-md: 24px;\n --duro-layout-spacing-container-sm: 16px;\n --duro-layout-spacing-inline-lg: 24px;\n --duro-layout-spacing-inline-md: 16px;\n --duro-layout-spacing-inline-sm: 8px;\n --duro-layout-spacing-inline-xs: 4px;\n --duro-layout-spacing-stack-lg: 24px;\n --duro-layout-spacing-stack-md: 16px;\n --duro-layout-spacing-stack-sm: 8px;\n --duro-layout-spacing-stack-xl: 48px;\n --duro-layout-spacing-stack-xs: 4px;\n /* typography */\n --duro-typography-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n --duro-typography-font-family-mono: \"SF Mono\", \"Fira Code\", \"Fira Mono\", \"Roboto Mono\", \"Courier New\", monospace;\n --duro-typography-font-size-heading: 1.5rem;\n --duro-typography-font-size-lg: 1.125rem;\n --duro-typography-font-size-md: 1rem;\n --duro-typography-font-size-sm: 0.875rem;\n --duro-typography-font-size-xl: 1.25rem;\n --duro-typography-font-size-xs: 0.75rem;\n --duro-typography-font-weight-bold: 700;\n --duro-typography-font-weight-medium: 500;\n --duro-typography-font-weight-normal: 400;\n --duro-typography-font-weight-semibold: 600;\n --duro-typography-line-height: 1.5;\n /* typeScale */\n --duro-type-scale-display-lg: clamp(3.5rem, 2rem + 3.5vw, 4.5rem);\n --duro-type-scale-display-md: clamp(2.75rem, 1.75rem + 2.5vw, 3.75rem);\n --duro-type-scale-display-sm: clamp(2.25rem, 1.5rem + 2vw, 3rem);\n --duro-type-scale-font-size1: 0.75rem;\n --duro-type-scale-font-size2: 0.8125rem;\n --duro-type-scale-font-size3: 0.875rem;\n --duro-type-scale-font-size4: 1rem;\n --duro-type-scale-font-size5: 1.125rem;\n --duro-type-scale-font-size6: 1.25rem;\n --duro-type-scale-font-size7: 1.5rem;\n --duro-type-scale-font-size8: 1.875rem;\n --duro-type-scale-font-size9: 2.25rem;\n --duro-type-scale-letter-spacing-normal: 0;\n --duro-type-scale-letter-spacing-tight: -0.02em;\n --duro-type-scale-letter-spacing-wide: 0.04em;\n --duro-type-scale-line-height1: 1rem;\n --duro-type-scale-line-height2: 1.25rem;\n --duro-type-scale-line-height3: 1.25rem;\n --duro-type-scale-line-height4: 1.5rem;\n --duro-type-scale-line-height5: 1.5rem;\n --duro-type-scale-line-height6: 1.75rem;\n --duro-type-scale-line-height7: 2rem;\n --duro-type-scale-line-height8: 2.25rem;\n --duro-type-scale-line-height9: 2.75rem;\n /* duration */\n --duro-duration-base: 200ms;\n --duro-duration-brisk: 160ms;\n --duro-duration-fast: 150ms;\n --duro-duration-instant: 0ms;\n --duro-duration-minimal: 1ms;\n --duro-duration-quick: 120ms;\n --duro-duration-slow: 280ms;\n /* easing */\n --duro-easing-ease-in: cubic-bezier(0.72, 0, 0.68, 0.28);\n --duro-easing-ease-out: cubic-bezier(0.32, 0.72, 0, 1);\n --duro-easing-linear: linear;\n --duro-easing-standard: ease;\n /* breakpoints */\n --duro-breakpoint-lg: 1024px;\n --duro-breakpoint-md: 768px;\n --duro-breakpoint-sm: 640px;\n --duro-breakpoint-xl: 1280px;\n --duro-breakpoint-xs: 480px;\n}\n\n:root[data-theme=\"light\"] {\n color-scheme: light;\n /* colors */\n --duro-color-accent: #1e40af;\n --duro-color-accent-contrast: #ffffff;\n --duro-color-accent-hover: #1a3799;\n --duro-color-bg: #ffffff;\n --duro-color-bg-card: #f5f5f5;\n --duro-color-bg-card-hover: #ebebeb;\n --duro-color-border: #d4d4d4;\n --duro-color-contrast-border: rgba(255, 255, 255, 0.33);\n --duro-color-contrast-surface: #1a1a1a;\n --duro-color-error: #991b1b;\n --duro-color-error-bg: rgba(153, 27, 27, 0.08);\n --duro-color-error-border: rgba(153, 27, 27, 0.3);\n --duro-color-error-contrast: #ffffff;\n --duro-color-error-hover: #7f1d1d;\n --duro-color-error-text: #7f1d1d;\n --duro-color-fixed-light: #ffffff;\n --duro-color-highlight: #6b21a8;\n --duro-color-highlight-bg: rgba(107, 33, 168, 0.08);\n --duro-color-highlight-border: rgba(107, 33, 168, 0.3);\n --duro-color-highlight-text: #581c87;\n --duro-color-info: #1e40af;\n --duro-color-info-bg: rgba(30, 64, 175, 0.08);\n --duro-color-info-border: rgba(30, 64, 175, 0.3);\n --duro-color-info-text: #1e40af;\n --duro-color-inverse-border: rgba(0, 0, 0, 0.55);\n --duro-color-inverse-border-hover: rgba(0, 0, 0, 0.70);\n --duro-color-inverse-fill: rgba(0, 0, 0, 0.10);\n --duro-color-inverse-fill-hover: rgba(0, 0, 0, 0.18);\n --duro-color-on-contrast-surface: #e5e5e5;\n --duro-color-overlay-light: rgba(255, 255, 255, 0.78);\n --duro-color-scrim: rgba(0, 0, 0, 0.4);\n --duro-color-success: #166534;\n --duro-color-success-bg: rgba(22, 101, 52, 0.08);\n --duro-color-success-border: rgba(22, 101, 52, 0.3);\n --duro-color-success-text: #14532d;\n --duro-color-text: #1a1a1a;\n --duro-color-text-muted: #4a4a4a;\n --duro-color-warning: #92400e;\n --duro-color-warning-bg: rgba(146, 64, 14, 0.08);\n --duro-color-warning-border: rgba(146, 64, 14, 0.3);\n --duro-color-warning-text: #78350f;\n /* shadows */\n --duro-shadow-drop-over: inset 0 0 0 2px #1e40af;\n --duro-shadow-drop-ready: inset 0 0 0 1px #d4d4d4;\n --duro-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.16);\n --duro-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.12);\n --duro-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n:root[data-theme=\"high-contrast\"] {\n color-scheme: dark;\n /* colors */\n --duro-color-accent: #60a5fa;\n --duro-color-accent-contrast: #000000;\n --duro-color-accent-hover: #93c5fd;\n --duro-color-bg: #000000;\n --duro-color-bg-card: #111111;\n --duro-color-bg-card-hover: #1a1a1a;\n --duro-color-border: #555555;\n --duro-color-contrast-border: rgba(0, 0, 0, 0.42);\n --duro-color-contrast-surface: #ffffff;\n --duro-color-error: #f87171;\n --duro-color-error-bg: rgba(248, 113, 113, 0.15);\n --duro-color-error-border: rgba(248, 113, 113, 0.5);\n --duro-color-error-contrast: #000000;\n --duro-color-error-hover: #fca5a5;\n --duro-color-error-text: #fca5a5;\n --duro-color-fixed-light: #ffffff;\n --duro-color-highlight: #d8b4fe;\n --duro-color-highlight-bg: rgba(216, 180, 254, 0.15);\n --duro-color-highlight-border: rgba(216, 180, 254, 0.5);\n --duro-color-highlight-text: #e9d5ff;\n --duro-color-info: #60a5fa;\n --duro-color-info-bg: rgba(96, 165, 250, 0.15);\n --duro-color-info-border: rgba(96, 165, 250, 0.5);\n --duro-color-info-text: #bfdbfe;\n --duro-color-inverse-border: rgba(0, 0, 0, 0.55);\n --duro-color-inverse-border-hover: rgba(0, 0, 0, 0.70);\n --duro-color-inverse-fill: rgba(0, 0, 0, 0.10);\n --duro-color-inverse-fill-hover: rgba(0, 0, 0, 0.18);\n --duro-color-on-contrast-surface: #000000;\n --duro-color-overlay-light: rgba(255, 255, 255, 0.78);\n --duro-color-scrim: rgba(0, 0, 0, 0.4);\n --duro-color-success: #4ade80;\n --duro-color-success-bg: rgba(74, 222, 128, 0.15);\n --duro-color-success-border: rgba(74, 222, 128, 0.5);\n --duro-color-success-text: #86efac;\n --duro-color-text: #ffffff;\n --duro-color-text-muted: #b0b0b0;\n --duro-color-warning: #fcd34d;\n --duro-color-warning-bg: rgba(252, 211, 77, 0.15);\n --duro-color-warning-border: rgba(252, 211, 77, 0.5);\n --duro-color-warning-text: #fef08a;\n /* shadows */\n --duro-shadow-drop-over: inset 0 0 0 2px #60a5fa;\n --duro-shadow-drop-ready: inset 0 0 0 1px #555555;\n --duro-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.8);\n --duro-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.7);\n --duro-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.6);\n}\n"
|
|
10021
|
+
"mockupCss": "/*\n * GENERATED by scripts/generate-mockup-css.mjs — do not edit.\n *\n * The design tokens as resolved values, for HTML that loads no stylesheet\n * (mockup artboards, static previews). Same names as vars.css; where vars.css\n * follows the live theme, this file carries every theme and switches on\n * <html data-theme=\"light|high-contrast\">.\n *\n * Inside the component library and the apps, never use this: go through\n * css.create() and the token imports, or vars.css from plain CSS.\n */\n:root {\n color-scheme: dark;\n /* colors */\n --duro-color-accent: #6aaffc;\n --duro-color-accent-contrast: #000000;\n --duro-color-accent-hover: #93c5fd;\n --duro-color-bg: #0f0f0f;\n --duro-color-bg-card: #1a1a1a;\n --duro-color-bg-card-hover: #242424;\n --duro-color-border: #333333;\n --duro-color-contrast-border: rgba(0, 0, 0, 0.42);\n --duro-color-contrast-surface: #f5f5f5;\n --duro-color-error: #f87171;\n --duro-color-error-bg: rgba(248, 113, 113, 0.1);\n --duro-color-error-border: rgba(248, 113, 113, 0.3);\n --duro-color-error-contrast: #000000;\n --duro-color-error-hover: #fca5a5;\n --duro-color-error-text: #fca5a5;\n --duro-color-fixed-light: #ffffff;\n --duro-color-highlight: #c084fc;\n --duro-color-highlight-bg: rgba(192, 132, 252, 0.1);\n --duro-color-highlight-border: rgba(192, 132, 252, 0.3);\n --duro-color-highlight-text: #d8b4fe;\n --duro-color-info: #6aaffc;\n --duro-color-info-bg: rgba(106, 175, 252, 0.1);\n --duro-color-info-border: rgba(106, 175, 252, 0.3);\n --duro-color-info-text: #93c5fd;\n --duro-color-inverse-border: rgba(0, 0, 0, 0.55);\n --duro-color-inverse-border-hover: rgba(0, 0, 0, 0.70);\n --duro-color-inverse-fill: rgba(0, 0, 0, 0.10);\n --duro-color-inverse-fill-hover: rgba(0, 0, 0, 0.18);\n --duro-color-on-contrast-surface: #1a1a1a;\n --duro-color-overlay-light: rgba(255, 255, 255, 0.78);\n --duro-color-scrim: rgba(0, 0, 0, 0.4);\n --duro-color-success: #22c55e;\n --duro-color-success-bg: rgba(34, 197, 94, 0.1);\n --duro-color-success-border: rgba(34, 197, 94, 0.3);\n --duro-color-success-text: #86efac;\n --duro-color-text: #e5e5e5;\n --duro-color-text-muted: #b0b0b0;\n --duro-color-warning: #fbbf24;\n --duro-color-warning-bg: rgba(251, 191, 36, 0.1);\n --duro-color-warning-border: rgba(251, 191, 36, 0.3);\n --duro-color-warning-text: #fde68a;\n /* shadows */\n --duro-shadow-drop-over: inset 0 0 0 2px #6aaffc;\n --duro-shadow-drop-ready: inset 0 0 0 1px #333333;\n --duro-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);\n --duro-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);\n --duro-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.3);\n /* spacing */\n --duro-spacing-lg: 24px;\n --duro-spacing-md: 16px;\n --duro-spacing-ms: 12px;\n --duro-spacing-sm: 8px;\n --duro-spacing-xl: 32px;\n --duro-spacing-xs: 4px;\n --duro-spacing-xxl: 48px;\n --duro-spacing-xxxl: 64px;\n /* microSpacing */\n --duro-micro-spacing-px1: 1px;\n --duro-micro-spacing-px2: 2px;\n --duro-micro-spacing-px3: 3px;\n --duro-micro-spacing-px5: 5px;\n --duro-micro-spacing-px6: 6px;\n /* radii */\n --duro-radius-full: 9999px;\n --duro-radius-lg: 16px;\n --duro-radius-md: 12px;\n --duro-radius-px6: 6px;\n --duro-radius-sm: 8px;\n --duro-radius-xs: 4px;\n /* sizes */\n --duro-size-app-bar-h: 61px;\n --duro-size-aside-w: 320px;\n --duro-size-bar-h: 4px;\n --duro-size-canvas-min-h: 480px;\n --duro-size-check-mark-h: 9px;\n --duro-size-check-mark-w: 5px;\n --duro-size-chip: 24px;\n --duro-size-color-area-h: 150px;\n --duro-size-color-picker-w: 196px;\n --duro-size-color-preview-h: 22px;\n --duro-size-color-swatch: 20px;\n --duro-size-color-track-h: 12px;\n --duro-size-control-lg: 40px;\n --duro-size-control-md: 39px;\n --duro-size-control-sm: 28px;\n --duro-size-day-header-h: 46px;\n --duro-size-device-bar-w: 96px;\n --duro-size-dialog-lg: 680px;\n --duro-size-dialog-md: 520px;\n --duro-size-dialog-sm: 400px;\n --duro-size-divider: 1px;\n --duro-size-drop-zone-min-h: 128px;\n --duro-size-edge-fade: 32px;\n --duro-size-editor-min-h: 160px;\n --duro-size-embed-w: 550px;\n --duro-size-field-min-w: 160px;\n --duro-size-field-min-w-sm: 80px;\n --duro-size-glyph-md: 16px;\n --duro-size-glyph-sm: 12px;\n --duro-size-glyph-xs: 10px;\n --duro-size-grid-col-md: 280px;\n --duro-size-grid-col-sm: 240px;\n --duro-size-grid-col-xs: 200px;\n --duro-size-handle: 16px;\n --duro-size-icon-button: 32px;\n --duro-size-icon-button-sm: 28px;\n --duro-size-icon-lg: 24px;\n --duro-size-icon-md: 18px;\n --duro-size-icon-sm: 16px;\n --duro-size-icon-xl: 36px;\n --duro-size-icon-xxl: 48px;\n --duro-size-indicator: 18px;\n --duro-size-indicator-dot: 8px;\n --duro-size-label-min-w: 120px;\n --duro-size-list-max-h: 280px;\n --duro-size-list-max-h-sm: 200px;\n --duro-size-meter-h: 6px;\n --duro-size-nav-marker-h: 18px;\n --duro-size-nav-marker-w: 3px;\n --duro-size-page-lg: 1200px;\n --duro-size-page-md: 800px;\n --duro-size-page-sm: 600px;\n --duro-size-page-xl: 1440px;\n --duro-size-page-xs: 480px;\n --duro-size-palette-min-w: 96px;\n --duro-size-panel-lg: 640px;\n --duro-size-panel-md: 480px;\n --duro-size-panel-sm: 360px;\n --duro-size-placeholder-min-h: 80px;\n --duro-size-popover-w: 320px;\n --duro-size-popover-w-sm: 240px;\n --duro-size-popup-max-w: 280px;\n --duro-size-popup-min-w: 160px;\n --duro-size-preview-max-h: 320px;\n --duro-size-readout-w: 40px;\n --duro-size-scrollbar: 8px;\n --duro-size-sidebar-w: 240px;\n --duro-size-skeleton-chip-w: 96px;\n --duro-size-slider-w: 96px;\n --duro-size-spinner-lg: 40px;\n --duro-size-spinner-md: 24px;\n --duro-size-spinner-sm: 16px;\n --duro-size-swatch-h: 34px;\n --duro-size-swatch-w: 44px;\n --duro-size-switch-thumb: 16px;\n --duro-size-switch-track-h: 20px;\n --duro-size-switch-track-w: 36px;\n --duro-size-tab-indicator: 2px;\n --duro-size-time-gutter-w: 64px;\n --duro-size-timeline-label-w: 180px;\n --duro-size-toast-max-w: 440px;\n --duro-size-toolbar-h: 36px;\n --duro-size-touch-target: 44px;\n /* borders */\n --duro-border-accent: 3px;\n --duro-border-focus-offset: 2px;\n --duro-border-focus-offset-sm: 1px;\n --duro-border-focus-ring: 2px;\n --duro-border-hairline: 1px;\n --duro-border-strong: 2px;\n /* layers */\n --duro-layer-floating: 50;\n --duro-layer-floating-raised: 60;\n --duro-layer-modal: 1001;\n --duro-layer-modal-raised: 1002;\n --duro-layer-overlay: 1000;\n --duro-layer-popover: 1040;\n --duro-layer-popover-raised: 1041;\n --duro-layer-popup: 1050;\n --duro-layer-popup-backdrop: 1049;\n --duro-layer-portal: 1100;\n --duro-layer-raised: 1;\n --duro-layer-toast: 1060;\n /* effects */\n --duro-effect-overlay-blur: blur(2px);\n --duro-effect-surface-blur: blur(6px);\n /* layoutSpacing */\n --duro-layout-spacing-container-lg: 32px;\n --duro-layout-spacing-container-md: 24px;\n --duro-layout-spacing-container-sm: 16px;\n --duro-layout-spacing-inline-lg: 24px;\n --duro-layout-spacing-inline-md: 16px;\n --duro-layout-spacing-inline-sm: 8px;\n --duro-layout-spacing-inline-xs: 4px;\n --duro-layout-spacing-stack-lg: 24px;\n --duro-layout-spacing-stack-md: 16px;\n --duro-layout-spacing-stack-sm: 8px;\n --duro-layout-spacing-stack-xl: 48px;\n --duro-layout-spacing-stack-xs: 4px;\n /* typography */\n --duro-typography-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n --duro-typography-font-family-mono: \"SF Mono\", \"Fira Code\", \"Fira Mono\", \"Roboto Mono\", \"Courier New\", monospace;\n --duro-typography-font-size-heading: 1.5rem;\n --duro-typography-font-size-lg: 1.125rem;\n --duro-typography-font-size-md: 1rem;\n --duro-typography-font-size-sm: 0.875rem;\n --duro-typography-font-size-xl: 1.25rem;\n --duro-typography-font-size-xs: 0.75rem;\n --duro-typography-font-weight-bold: 700;\n --duro-typography-font-weight-medium: 500;\n --duro-typography-font-weight-normal: 400;\n --duro-typography-font-weight-semibold: 600;\n --duro-typography-line-height: 1.5;\n /* typeScale */\n --duro-type-scale-display-lg: clamp(3.5rem, 2rem + 3.5vw, 4.5rem);\n --duro-type-scale-display-md: clamp(2.75rem, 1.75rem + 2.5vw, 3.75rem);\n --duro-type-scale-display-sm: clamp(2.25rem, 1.5rem + 2vw, 3rem);\n --duro-type-scale-font-size1: 0.75rem;\n --duro-type-scale-font-size2: 0.8125rem;\n --duro-type-scale-font-size3: 0.875rem;\n --duro-type-scale-font-size4: 1rem;\n --duro-type-scale-font-size5: 1.125rem;\n --duro-type-scale-font-size6: 1.25rem;\n --duro-type-scale-font-size7: 1.5rem;\n --duro-type-scale-font-size8: 1.875rem;\n --duro-type-scale-font-size9: 2.25rem;\n --duro-type-scale-letter-spacing-normal: 0;\n --duro-type-scale-letter-spacing-tight: -0.02em;\n --duro-type-scale-letter-spacing-wide: 0.04em;\n --duro-type-scale-line-height1: 1rem;\n --duro-type-scale-line-height2: 1.25rem;\n --duro-type-scale-line-height3: 1.25rem;\n --duro-type-scale-line-height4: 1.5rem;\n --duro-type-scale-line-height5: 1.5rem;\n --duro-type-scale-line-height6: 1.75rem;\n --duro-type-scale-line-height7: 2rem;\n --duro-type-scale-line-height8: 2.25rem;\n --duro-type-scale-line-height9: 2.75rem;\n /* duration */\n --duro-duration-base: 200ms;\n --duro-duration-brisk: 160ms;\n --duro-duration-fast: 150ms;\n --duro-duration-instant: 0ms;\n --duro-duration-minimal: 1ms;\n --duro-duration-quick: 120ms;\n --duro-duration-slow: 280ms;\n /* easing */\n --duro-easing-ease-in: cubic-bezier(0.72, 0, 0.68, 0.28);\n --duro-easing-ease-out: cubic-bezier(0.32, 0.72, 0, 1);\n --duro-easing-linear: linear;\n --duro-easing-standard: ease;\n /* breakpoints */\n --duro-breakpoint-lg: 1024px;\n --duro-breakpoint-md: 768px;\n --duro-breakpoint-sm: 640px;\n --duro-breakpoint-xl: 1280px;\n --duro-breakpoint-xs: 480px;\n}\n\n:root[data-theme=\"light\"] {\n color-scheme: light;\n /* colors */\n --duro-color-accent: #1e40af;\n --duro-color-accent-contrast: #ffffff;\n --duro-color-accent-hover: #1a3799;\n --duro-color-bg: #ffffff;\n --duro-color-bg-card: #f5f5f5;\n --duro-color-bg-card-hover: #ebebeb;\n --duro-color-border: #d4d4d4;\n --duro-color-contrast-border: rgba(255, 255, 255, 0.33);\n --duro-color-contrast-surface: #1a1a1a;\n --duro-color-error: #991b1b;\n --duro-color-error-bg: rgba(153, 27, 27, 0.08);\n --duro-color-error-border: rgba(153, 27, 27, 0.3);\n --duro-color-error-contrast: #ffffff;\n --duro-color-error-hover: #7f1d1d;\n --duro-color-error-text: #7f1d1d;\n --duro-color-fixed-light: #ffffff;\n --duro-color-highlight: #6b21a8;\n --duro-color-highlight-bg: rgba(107, 33, 168, 0.08);\n --duro-color-highlight-border: rgba(107, 33, 168, 0.3);\n --duro-color-highlight-text: #581c87;\n --duro-color-info: #1e40af;\n --duro-color-info-bg: rgba(30, 64, 175, 0.08);\n --duro-color-info-border: rgba(30, 64, 175, 0.3);\n --duro-color-info-text: #1e40af;\n --duro-color-inverse-border: rgba(0, 0, 0, 0.55);\n --duro-color-inverse-border-hover: rgba(0, 0, 0, 0.70);\n --duro-color-inverse-fill: rgba(0, 0, 0, 0.10);\n --duro-color-inverse-fill-hover: rgba(0, 0, 0, 0.18);\n --duro-color-on-contrast-surface: #e5e5e5;\n --duro-color-overlay-light: rgba(255, 255, 255, 0.78);\n --duro-color-scrim: rgba(0, 0, 0, 0.4);\n --duro-color-success: #166534;\n --duro-color-success-bg: rgba(22, 101, 52, 0.08);\n --duro-color-success-border: rgba(22, 101, 52, 0.3);\n --duro-color-success-text: #14532d;\n --duro-color-text: #1a1a1a;\n --duro-color-text-muted: #4a4a4a;\n --duro-color-warning: #92400e;\n --duro-color-warning-bg: rgba(146, 64, 14, 0.08);\n --duro-color-warning-border: rgba(146, 64, 14, 0.3);\n --duro-color-warning-text: #78350f;\n /* shadows */\n --duro-shadow-drop-over: inset 0 0 0 2px #1e40af;\n --duro-shadow-drop-ready: inset 0 0 0 1px #d4d4d4;\n --duro-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.16);\n --duro-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.12);\n --duro-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n:root[data-theme=\"high-contrast\"] {\n color-scheme: dark;\n /* colors */\n --duro-color-accent: #60a5fa;\n --duro-color-accent-contrast: #000000;\n --duro-color-accent-hover: #93c5fd;\n --duro-color-bg: #000000;\n --duro-color-bg-card: #111111;\n --duro-color-bg-card-hover: #1a1a1a;\n --duro-color-border: #555555;\n --duro-color-contrast-border: rgba(0, 0, 0, 0.42);\n --duro-color-contrast-surface: #ffffff;\n --duro-color-error: #f87171;\n --duro-color-error-bg: rgba(248, 113, 113, 0.15);\n --duro-color-error-border: rgba(248, 113, 113, 0.5);\n --duro-color-error-contrast: #000000;\n --duro-color-error-hover: #fca5a5;\n --duro-color-error-text: #fca5a5;\n --duro-color-fixed-light: #ffffff;\n --duro-color-highlight: #d8b4fe;\n --duro-color-highlight-bg: rgba(216, 180, 254, 0.15);\n --duro-color-highlight-border: rgba(216, 180, 254, 0.5);\n --duro-color-highlight-text: #e9d5ff;\n --duro-color-info: #60a5fa;\n --duro-color-info-bg: rgba(96, 165, 250, 0.15);\n --duro-color-info-border: rgba(96, 165, 250, 0.5);\n --duro-color-info-text: #bfdbfe;\n --duro-color-inverse-border: rgba(0, 0, 0, 0.55);\n --duro-color-inverse-border-hover: rgba(0, 0, 0, 0.70);\n --duro-color-inverse-fill: rgba(0, 0, 0, 0.10);\n --duro-color-inverse-fill-hover: rgba(0, 0, 0, 0.18);\n --duro-color-on-contrast-surface: #000000;\n --duro-color-overlay-light: rgba(255, 255, 255, 0.78);\n --duro-color-scrim: rgba(0, 0, 0, 0.4);\n --duro-color-success: #4ade80;\n --duro-color-success-bg: rgba(74, 222, 128, 0.15);\n --duro-color-success-border: rgba(74, 222, 128, 0.5);\n --duro-color-success-text: #86efac;\n --duro-color-text: #ffffff;\n --duro-color-text-muted: #b0b0b0;\n --duro-color-warning: #fcd34d;\n --duro-color-warning-bg: rgba(252, 211, 77, 0.15);\n --duro-color-warning-border: rgba(252, 211, 77, 0.5);\n --duro-color-warning-text: #fef08a;\n /* shadows */\n --duro-shadow-drop-over: inset 0 0 0 2px #60a5fa;\n --duro-shadow-drop-ready: inset 0 0 0 1px #555555;\n --duro-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.8);\n --duro-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.7);\n --duro-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.6);\n}\n"
|
|
9157
10022
|
},
|
|
9158
10023
|
"unions": {
|
|
9159
10024
|
"AlertVariant": [
|
|
@@ -9162,6 +10027,11 @@
|
|
|
9162
10027
|
"warning",
|
|
9163
10028
|
"info"
|
|
9164
10029
|
],
|
|
10030
|
+
"AppShellCollapse": [
|
|
10031
|
+
"sm",
|
|
10032
|
+
"md",
|
|
10033
|
+
"lg"
|
|
10034
|
+
],
|
|
9165
10035
|
"BadgeSize": [
|
|
9166
10036
|
"sm",
|
|
9167
10037
|
"md"
|
|
@@ -9254,6 +10124,11 @@
|
|
|
9254
10124
|
"lg",
|
|
9255
10125
|
"xl"
|
|
9256
10126
|
],
|
|
10127
|
+
"GridLayout": [
|
|
10128
|
+
"split",
|
|
10129
|
+
"split-wide",
|
|
10130
|
+
"content-aside"
|
|
10131
|
+
],
|
|
9257
10132
|
"HeadingVariant": [
|
|
9258
10133
|
"displayLg",
|
|
9259
10134
|
"displayMd",
|
|
@@ -9340,6 +10215,16 @@
|
|
|
9340
10215
|
"listMaxH",
|
|
9341
10216
|
"listMaxHSm"
|
|
9342
10217
|
],
|
|
10218
|
+
"LiveRegionPoliteness": [
|
|
10219
|
+
"polite",
|
|
10220
|
+
"assertive"
|
|
10221
|
+
],
|
|
10222
|
+
"MeterTone": [
|
|
10223
|
+
"accent",
|
|
10224
|
+
"success",
|
|
10225
|
+
"warning",
|
|
10226
|
+
"error"
|
|
10227
|
+
],
|
|
9343
10228
|
"PageShellMaxWidth": [
|
|
9344
10229
|
"sm",
|
|
9345
10230
|
"md",
|
|
@@ -9474,7 +10359,8 @@
|
|
|
9474
10359
|
"ToastVariant": [
|
|
9475
10360
|
"success",
|
|
9476
10361
|
"error",
|
|
9477
|
-
"info"
|
|
10362
|
+
"info",
|
|
10363
|
+
"warning"
|
|
9478
10364
|
],
|
|
9479
10365
|
"ToggleSize": [
|
|
9480
10366
|
"default",
|