@ratio-ui/core 0.3.0 → 0.5.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/catalogue.json +935 -75
- package/dist/components/accordion/Accordion.d.ts +19 -0
- package/dist/components/accordion/Accordion.js +52 -0
- package/dist/components/accordion/index.d.ts +2 -0
- package/dist/components/accordion/index.js +1 -0
- package/dist/components/alert/Alert.js +4 -3
- package/dist/components/breadcrumb/Breadcrumb.d.ts +19 -0
- package/dist/components/breadcrumb/Breadcrumb.js +50 -0
- package/dist/components/breadcrumb/index.d.ts +2 -0
- package/dist/components/breadcrumb/index.js +1 -0
- package/dist/components/button/Button.js +6 -6
- package/dist/components/calendar/Calendar.js +2 -2
- package/dist/components/chart/Chart.d.ts +137 -0
- package/dist/components/chart/Chart.js +238 -0
- package/dist/components/chart/index.d.ts +2 -0
- package/dist/components/chart/index.js +1 -0
- package/dist/components/checkbox/Checkbox.js +1 -1
- package/dist/components/combobox/Combobox.d.ts +52 -0
- package/dist/components/combobox/Combobox.js +92 -0
- package/dist/components/combobox/index.d.ts +2 -0
- package/dist/components/combobox/index.js +1 -0
- package/dist/components/data-table/DataTable.js +12 -18
- package/dist/components/date-picker/DatePicker.d.ts +3 -2
- package/dist/components/date-picker/DatePicker.js +7 -3
- package/dist/components/date-range-picker/DateRangePicker.d.ts +3 -2
- package/dist/components/date-range-picker/DateRangePicker.js +7 -3
- package/dist/components/definition/Definition.js +1 -1
- package/dist/components/dialog/Dialog.js +1 -1
- package/dist/components/drawer/Drawer.d.ts +52 -0
- package/dist/components/drawer/Drawer.js +120 -0
- package/dist/components/drawer/index.d.ts +2 -0
- package/dist/components/drawer/index.js +1 -0
- package/dist/components/field/Field.d.ts +8 -5
- package/dist/components/field/Field.js +9 -3
- package/dist/components/icon/Icon.d.ts +1 -1
- package/dist/components/icon/Icon.js +16 -5
- package/dist/components/icon/glyphs.js +19 -8
- package/dist/components/icon/registry.d.ts +3 -2
- package/dist/components/icon/registry.js +14 -2
- package/dist/components/input/Input.js +1 -1
- package/dist/components/input-group/InputGroup.d.ts +3 -1
- package/dist/components/input-group/InputGroup.js +20 -8
- package/dist/components/input-otp/InputOtp.d.ts +43 -0
- package/dist/components/input-otp/InputOtp.js +45 -0
- package/dist/components/input-otp/index.d.ts +2 -0
- package/dist/components/input-otp/index.js +1 -0
- package/dist/components/key-value-list/KeyValueList.d.ts +25 -0
- package/dist/components/key-value-list/KeyValueList.js +40 -0
- package/dist/components/key-value-list/index.d.ts +2 -0
- package/dist/components/key-value-list/index.js +1 -0
- package/dist/components/link/Link.js +1 -1
- package/dist/components/metric-strip/MetricStrip.js +1 -1
- package/dist/components/page-header/PageHeader.js +8 -8
- package/dist/components/pagination/Pagination.js +1 -1
- package/dist/components/progress/Progress.d.ts +25 -0
- package/dist/components/progress/Progress.js +38 -0
- package/dist/components/progress/index.d.ts +2 -0
- package/dist/components/progress/index.js +1 -0
- package/dist/components/radio-group/RadioGroup.d.ts +18 -0
- package/dist/components/radio-group/RadioGroup.js +32 -0
- package/dist/components/radio-group/index.d.ts +2 -0
- package/dist/components/radio-group/index.js +1 -0
- package/dist/components/scroll-area/ScrollArea.d.ts +12 -0
- package/dist/components/scroll-area/ScrollArea.js +34 -0
- package/dist/components/scroll-area/index.d.ts +2 -0
- package/dist/components/scroll-area/index.js +1 -0
- package/dist/components/search-field/SearchField.js +8 -4
- package/dist/components/select/Select.js +1 -1
- package/dist/components/separator/Separator.d.ts +15 -0
- package/dist/components/separator/Separator.js +25 -0
- package/dist/components/separator/index.d.ts +2 -0
- package/dist/components/separator/index.js +1 -0
- package/dist/components/sheet/Sheet.d.ts +52 -0
- package/dist/components/sheet/Sheet.js +89 -0
- package/dist/components/sheet/index.d.ts +2 -0
- package/dist/components/sheet/index.js +1 -0
- package/dist/components/side-nav/SideNav.js +15 -10
- package/dist/components/status-pill/StatusPill.js +1 -1
- package/dist/components/summary-chips/SummaryChips.js +1 -1
- package/dist/components/switch/Switch.js +2 -2
- package/dist/components/table/Table.d.ts +1 -1
- package/dist/components/table/Table.js +24 -3
- package/dist/components/tag-input/TagInput.js +1 -1
- package/dist/components/text/Text.d.ts +3 -2
- package/dist/components/text/Text.js +3 -1
- package/dist/components/textarea/Textarea.js +1 -1
- package/dist/components/toaster/Toaster.js +1 -1
- package/dist/components/tooltip/Tooltip.d.ts +1 -1
- package/dist/components/tooltip/Tooltip.js +2 -2
- package/dist/components/top-bar/TopBar.d.ts +2 -4
- package/dist/components/top-bar/TopBar.js +2 -7
- package/dist/index.d.ts +28 -4
- package/dist/index.js +13 -1
- package/dist/lib/cn.js +3 -1
- package/dist/styles.css +1 -1
- package/package.json +52 -1
package/dist/catalogue.json
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.5.0",
|
|
3
3
|
"components": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Accordion",
|
|
6
|
+
"import": "import { Accordion } from '@ratio-ui/core'",
|
|
7
|
+
"description": "A stack of sections that open and close. One section is open at a time unless multiple is set.",
|
|
8
|
+
"props": [],
|
|
9
|
+
"usage": {
|
|
10
|
+
"whenToUse": "- Grouped help or settings where the reader opens only the section they need\n- A short list of sections with a heading each, such as setup steps or FAQs",
|
|
11
|
+
"whenNotToUse": "- A single block that hides and shows: use a collapsible\n- Switching between views of the same content: use tabs\n- Styling: Accordion takes no `className` and no `style`",
|
|
12
|
+
"example": "<Accordion>\n <AccordionItem value=\"shipping\">\n <AccordionTrigger>Shipping</AccordionTrigger>\n <AccordionContent>Ships in two days.</AccordionContent>\n </AccordionItem>\n</Accordion>"
|
|
13
|
+
},
|
|
14
|
+
"parts": [
|
|
15
|
+
{
|
|
16
|
+
"name": "AccordionItem",
|
|
17
|
+
"import": "import { AccordionItem } from '@ratio-ui/core'",
|
|
18
|
+
"description": "One section: a trigger and its content, separated from the next by a hairline.",
|
|
19
|
+
"props": []
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "AccordionTrigger",
|
|
23
|
+
"import": "import { AccordionTrigger } from '@ratio-ui/core'",
|
|
24
|
+
"description": "The heading row of a section, with a chevron that turns when it is open.",
|
|
25
|
+
"props": []
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "AccordionContent",
|
|
29
|
+
"import": "import { AccordionContent } from '@ratio-ui/core'",
|
|
30
|
+
"description": "The body of a section. It appears and disappears at once, with no height animation.",
|
|
31
|
+
"props": []
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
4
35
|
{
|
|
5
36
|
"name": "Alert",
|
|
6
37
|
"import": "import { Alert } from '@ratio-ui/core'",
|
|
@@ -234,6 +265,36 @@
|
|
|
234
265
|
"example": "<Avatar name=\"My Store\" shape=\"square\" />\n<Avatar name=\"Kavya Singh\" />"
|
|
235
266
|
}
|
|
236
267
|
},
|
|
268
|
+
{
|
|
269
|
+
"name": "Breadcrumb",
|
|
270
|
+
"import": "import { Breadcrumb } from '@ratio-ui/core'",
|
|
271
|
+
"description": "The trail to the current page: links, chevron separators, the current page as text and an overflow ellipsis.",
|
|
272
|
+
"props": [
|
|
273
|
+
{
|
|
274
|
+
"name": "items",
|
|
275
|
+
"type": "BreadcrumbItem[]",
|
|
276
|
+
"required": true,
|
|
277
|
+
"description": "The trail, from the root to the current page."
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"name": "maxItems",
|
|
281
|
+
"type": "number",
|
|
282
|
+
"required": false,
|
|
283
|
+
"description": "Past this many items the middle ones collapse behind an ellipsis, keeping the first and the last two."
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
"name": "ref",
|
|
287
|
+
"type": "Ref<HTMLElement>",
|
|
288
|
+
"required": false,
|
|
289
|
+
"description": "Receives the rendered nav."
|
|
290
|
+
}
|
|
291
|
+
],
|
|
292
|
+
"usage": {
|
|
293
|
+
"whenToUse": "- Show where a page sits in a hierarchy, with a way back up",
|
|
294
|
+
"whenNotToUse": "- Switching between sibling views: use Tabs",
|
|
295
|
+
"example": "<Breadcrumb items={[{ label: 'Products', href: '/products' }, { label: 'Runner' }]} maxItems={4} />"
|
|
296
|
+
}
|
|
297
|
+
},
|
|
237
298
|
{
|
|
238
299
|
"name": "Button",
|
|
239
300
|
"import": "import { Button } from '@ratio-ui/core'",
|
|
@@ -340,6 +401,198 @@
|
|
|
340
401
|
}
|
|
341
402
|
]
|
|
342
403
|
},
|
|
404
|
+
{
|
|
405
|
+
"name": "Chart",
|
|
406
|
+
"import": "import { Chart } from '@ratio-ui/core'",
|
|
407
|
+
"description": "A chart on Recharts, drawn with the chart tokens. It holds the config the tooltip and legend read, styles Recharts' ticks, grid and cursor with the tokens, and is a figure named by its label and summarised by a description, a visually hidden data table, or both. Motion is colour fades only, so every series passes isAnimationActive false.",
|
|
408
|
+
"props": [
|
|
409
|
+
{
|
|
410
|
+
"name": "description",
|
|
411
|
+
"type": "string",
|
|
412
|
+
"required": false,
|
|
413
|
+
"description": "One sentence on what the chart shows, read after its name, such as \"Sales peak on Tuesday\"."
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"name": "table",
|
|
417
|
+
"type": "ChartTable",
|
|
418
|
+
"required": false,
|
|
419
|
+
"description": "The chart's rows as a visually hidden table, for assistive technology."
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
"name": "config",
|
|
423
|
+
"type": "ChartConfig",
|
|
424
|
+
"required": true,
|
|
425
|
+
"description": "The series and categories, by data key: their labels, icons and chart tokens."
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
"name": "label",
|
|
429
|
+
"type": "string",
|
|
430
|
+
"required": true,
|
|
431
|
+
"description": "The chart's accessible name, such as \"Sales by day\"."
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
"name": "aspect",
|
|
435
|
+
"type": "\"fill\" | \"square\" | \"video\"",
|
|
436
|
+
"required": false,
|
|
437
|
+
"default": "video",
|
|
438
|
+
"description": "The size: video (16:9, the default) or square at the full width, or fill to take the parent's size."
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"name": "initialDimension",
|
|
442
|
+
"type": "{ width: number; height: number; }",
|
|
443
|
+
"required": false,
|
|
444
|
+
"default": "{ width: 320, height: 200 } as const",
|
|
445
|
+
"description": "The size the chart is drawn at before it measures its box. Defaults to 320 by 200."
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
"name": "children",
|
|
449
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>>",
|
|
450
|
+
"required": true,
|
|
451
|
+
"description": "One Recharts chart, such as a BarChart or a LineChart, whose series pass isAnimationActive false."
|
|
452
|
+
}
|
|
453
|
+
],
|
|
454
|
+
"usage": {
|
|
455
|
+
"whenToUse": "- Analytics: a trend or a comparison over days or categories, as bars or lines\n- The page loader's bar mark\n- With a label and a one-sentence description, a data table, or both, so assistive technology gets the same summary\n- Every series passes isAnimationActive false: motion is colour fades only, and the tooltip never moves",
|
|
456
|
+
"whenNotToUse": "- A single number or a few numbers side by side: use MetricStrip\n- Progress towards an end: use Progress\n- Colours outside chart-1 to chart-5, or chart-4 and chart-5 alone on white: they sit below 3:1, so draw them beside a darker series",
|
|
457
|
+
"example": "import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts'\n\nconst config = { sales: { label: 'Sales', color: 'chart-1' } } satisfies ChartConfig\n\n<Chart config={config} label=\"Sales by day\" description=\"Sales peak on Friday\">\n <BarChart data={week} accessibilityLayer>\n <CartesianGrid vertical={false} />\n <XAxis dataKey=\"day\" tickLine={false} axisLine={false} />\n <ChartTooltip content={<ChartTooltipContent formatValue={formatMoney} />} />\n <Bar dataKey=\"sales\" fill={chartColor('chart-1')} isAnimationActive={false} />\n </BarChart>\n</Chart>"
|
|
458
|
+
},
|
|
459
|
+
"parts": [
|
|
460
|
+
{
|
|
461
|
+
"name": "ChartTooltip",
|
|
462
|
+
"import": "import { ChartTooltip } from '@ratio-ui/core'",
|
|
463
|
+
"description": "The chart's tooltip: Recharts' Tooltip, still (no movement), drawing ChartTooltipContent unless given other content.",
|
|
464
|
+
"props": [
|
|
465
|
+
{
|
|
466
|
+
"name": "cursor",
|
|
467
|
+
"type": "boolean",
|
|
468
|
+
"required": false,
|
|
469
|
+
"description": "Shows the cursor line or band under the pointer. On or off: Recharts' SVG props would carry a class name and a style."
|
|
470
|
+
}
|
|
471
|
+
]
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
"name": "ChartTooltipContent",
|
|
475
|
+
"import": "import { ChartTooltipContent } from '@ratio-ui/core'",
|
|
476
|
+
"description": "The box a chart tooltip draws: the active point's label, then a row per series with its swatch, its config label and its value, a count unless formatValue writes it. A 1px border on white, no shadow.",
|
|
477
|
+
"props": [
|
|
478
|
+
{
|
|
479
|
+
"name": "active",
|
|
480
|
+
"type": "boolean",
|
|
481
|
+
"required": false,
|
|
482
|
+
"description": "Set by the tooltip: whether a point is active."
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
"name": "payload",
|
|
486
|
+
"type": "readonly Payload<ValueType, TooltipNameType>[]",
|
|
487
|
+
"required": false,
|
|
488
|
+
"description": "Set by the tooltip: the values of the series at the active point."
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
"name": "label",
|
|
492
|
+
"type": "ReactNode",
|
|
493
|
+
"required": false,
|
|
494
|
+
"description": "Set by the tooltip: the active point's label, such as its x-axis category."
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
"name": "labelFormatter",
|
|
498
|
+
"type": "((label: ReactNode, payload: readonly Payload<ValueType, TooltipNameType>[]) => ReactNode)",
|
|
499
|
+
"required": false,
|
|
500
|
+
"description": "Writes the label from it and the payload."
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
"name": "formatter",
|
|
504
|
+
"type": "Formatter<ValueType, TooltipNameType>",
|
|
505
|
+
"required": false,
|
|
506
|
+
"description": "Draws a whole row, in place of the swatch, name and value, from the value, name, item, index and payload."
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"name": "indicator",
|
|
510
|
+
"type": "\"dashed\" | \"dot\" | \"line\"",
|
|
511
|
+
"required": false,
|
|
512
|
+
"default": "dot",
|
|
513
|
+
"description": "The swatch: a dot (the default), a line or a dashed line."
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
"name": "hideLabel",
|
|
517
|
+
"type": "boolean",
|
|
518
|
+
"required": false,
|
|
519
|
+
"default": "false",
|
|
520
|
+
"description": "Leaves out the label."
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
"name": "hideIndicator",
|
|
524
|
+
"type": "boolean",
|
|
525
|
+
"required": false,
|
|
526
|
+
"default": "false",
|
|
527
|
+
"description": "Leaves out the swatches."
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
"name": "nameKey",
|
|
531
|
+
"type": "string",
|
|
532
|
+
"required": false,
|
|
533
|
+
"description": "The key of the item, or its data row, whose value names the config entry of a row."
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"name": "labelKey",
|
|
537
|
+
"type": "string",
|
|
538
|
+
"required": false,
|
|
539
|
+
"description": "The key whose config entry labels the tooltip, in place of the active point's label."
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
"name": "color",
|
|
543
|
+
"type": "\"chart-1\" | \"chart-2\" | \"chart-3\" | \"chart-4\" | \"chart-5\"",
|
|
544
|
+
"required": false,
|
|
545
|
+
"description": "One chart token for every swatch, in place of each series' own."
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
"name": "formatValue",
|
|
549
|
+
"type": "((value: number) => string)",
|
|
550
|
+
"required": false,
|
|
551
|
+
"description": "Writes a number for its series, such as formatMoney for sales. Defaults to a count."
|
|
552
|
+
}
|
|
553
|
+
]
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
"name": "ChartLegend",
|
|
557
|
+
"import": "import { ChartLegend } from '@ratio-ui/core'",
|
|
558
|
+
"description": "The chart's legend: Recharts' Legend, drawing ChartLegendContent unless given other content.",
|
|
559
|
+
"props": []
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"name": "ChartLegendContent",
|
|
563
|
+
"import": "import { ChartLegendContent } from '@ratio-ui/core'",
|
|
564
|
+
"description": "The row a chart legend draws: a swatch in each series' chart token, or its icon, and its config label.",
|
|
565
|
+
"props": [
|
|
566
|
+
{
|
|
567
|
+
"name": "payload",
|
|
568
|
+
"type": "readonly LegendPayload[]",
|
|
569
|
+
"required": false,
|
|
570
|
+
"description": "Set by the legend: its series."
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
"name": "verticalAlign",
|
|
574
|
+
"type": "\"bottom\" | \"middle\" | \"top\"",
|
|
575
|
+
"required": false,
|
|
576
|
+
"default": "bottom",
|
|
577
|
+
"description": "Set by the legend: whether it sits above or below the chart, which sets the side of its gap."
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
"name": "hideIcon",
|
|
581
|
+
"type": "boolean",
|
|
582
|
+
"required": false,
|
|
583
|
+
"default": "false",
|
|
584
|
+
"description": "Draws the swatch even where the config gives an icon."
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
"name": "nameKey",
|
|
588
|
+
"type": "string",
|
|
589
|
+
"required": false,
|
|
590
|
+
"description": "The key of the item whose value names the config entry of a series."
|
|
591
|
+
}
|
|
592
|
+
]
|
|
593
|
+
}
|
|
594
|
+
]
|
|
595
|
+
},
|
|
343
596
|
{
|
|
344
597
|
"name": "Checkbox",
|
|
345
598
|
"import": "import { Checkbox } from '@ratio-ui/core'",
|
|
@@ -474,6 +727,124 @@
|
|
|
474
727
|
"example": "```tsx\n<Collapsible title=\"More pricing\" summary={[{ label: 'Cost price', value: '₹450.00' }, { label: 'HSN code', value: '6109' }]}>\n ...fields...\n</Collapsible>\n```\n\nThe panel appears and disappears at once; the library has no height animation."
|
|
475
728
|
}
|
|
476
729
|
},
|
|
730
|
+
{
|
|
731
|
+
"name": "Combobox",
|
|
732
|
+
"import": "import { Combobox } from '@ratio-ui/core'",
|
|
733
|
+
"description": "A field to choose one option from a list, with a search: type to narrow the list, pick with the mouse or Enter. The field looks like an Input and the list like a Popover panel. For several choices shown as chips, use TagInput. Mark it invalid with aria-invalid; give the list an empty text with emptyText. Inside a Field, the label, hint, error and required mark reach the input.",
|
|
734
|
+
"props": [
|
|
735
|
+
{
|
|
736
|
+
"name": "items",
|
|
737
|
+
"type": "readonly ComboboxItem[]",
|
|
738
|
+
"required": true,
|
|
739
|
+
"description": "The options. Strings or { value, label } objects."
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
"name": "value",
|
|
743
|
+
"type": "string | null",
|
|
744
|
+
"required": false,
|
|
745
|
+
"description": "The chosen value for a controlled combobox, or null for none."
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
"name": "defaultValue",
|
|
749
|
+
"type": "string | null",
|
|
750
|
+
"required": false,
|
|
751
|
+
"description": "The value to start with when the combobox keeps its own state."
|
|
752
|
+
},
|
|
753
|
+
{
|
|
754
|
+
"name": "onValueChange",
|
|
755
|
+
"type": "((value: string | null, eventDetails: ChangeEventDetails) => void)",
|
|
756
|
+
"required": false,
|
|
757
|
+
"description": "Called with the new value, or null when the choice is cleared."
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
"name": "placeholder",
|
|
761
|
+
"type": "string",
|
|
762
|
+
"required": false,
|
|
763
|
+
"description": "The text shown while nothing is chosen."
|
|
764
|
+
},
|
|
765
|
+
{
|
|
766
|
+
"name": "emptyText",
|
|
767
|
+
"type": "string",
|
|
768
|
+
"required": false,
|
|
769
|
+
"default": "No results found",
|
|
770
|
+
"description": "The text shown when the search matches no option. Defaults to \"No results found\"."
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
"name": "aria-invalid",
|
|
774
|
+
"type": "boolean | \"true\" | \"false\"",
|
|
775
|
+
"required": false,
|
|
776
|
+
"description": "Marks the field invalid and draws the error ring, as on every form control. Field sets it when it shows an error."
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
"name": "invalid",
|
|
780
|
+
"type": "boolean",
|
|
781
|
+
"required": false,
|
|
782
|
+
"default": "false",
|
|
783
|
+
"description": "The same as aria-invalid, kept as its alias."
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
"name": "clearable",
|
|
787
|
+
"type": "boolean",
|
|
788
|
+
"required": false,
|
|
789
|
+
"default": "true",
|
|
790
|
+
"description": "Shows a button that clears the choice while one is made. Defaults to true."
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
"name": "disabled",
|
|
794
|
+
"type": "boolean",
|
|
795
|
+
"required": false,
|
|
796
|
+
"default": "false",
|
|
797
|
+
"description": "Stops people from changing the choice."
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
"name": "name",
|
|
801
|
+
"type": "string",
|
|
802
|
+
"required": false,
|
|
803
|
+
"description": "The name of the field in a form."
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
"name": "aria-label",
|
|
807
|
+
"type": "string",
|
|
808
|
+
"required": false,
|
|
809
|
+
"description": "The accessible name when no label is wired to the field."
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
"name": "aria-labelledby",
|
|
813
|
+
"type": "string",
|
|
814
|
+
"required": false,
|
|
815
|
+
"description": "The ids of the elements that name the field. Field sets it to its label."
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
"name": "aria-describedby",
|
|
819
|
+
"type": "string",
|
|
820
|
+
"required": false,
|
|
821
|
+
"description": "The ids of the elements that describe the field, such as its hint or error. Field sets it."
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
"name": "aria-required",
|
|
825
|
+
"type": "boolean | \"true\" | \"false\"",
|
|
826
|
+
"required": false,
|
|
827
|
+
"description": "Tells assistive technology that the field must be filled. Field sets it for a required field."
|
|
828
|
+
},
|
|
829
|
+
{
|
|
830
|
+
"name": "id",
|
|
831
|
+
"type": "string",
|
|
832
|
+
"required": false,
|
|
833
|
+
"description": "The id of the input, for a label's htmlFor."
|
|
834
|
+
},
|
|
835
|
+
{
|
|
836
|
+
"name": "ref",
|
|
837
|
+
"type": "Ref<HTMLInputElement>",
|
|
838
|
+
"required": false,
|
|
839
|
+
"description": "Receives the input element."
|
|
840
|
+
}
|
|
841
|
+
],
|
|
842
|
+
"usage": {
|
|
843
|
+
"whenToUse": "- Choosing one option from a long list that people search, such as a vendor or a product type\n- A field where the list may be empty or the search may match nothing",
|
|
844
|
+
"whenNotToUse": "- A short list of a few options: use a radio group or tabs\n- Several choices shown as chips: use TagInput\n- A list of actions: use DropdownMenu",
|
|
845
|
+
"example": "<Combobox aria-label=\"Vendor\" items={['Acme', 'Northwind']} placeholder=\"Choose a vendor\" onValueChange={setVendor} />"
|
|
846
|
+
}
|
|
847
|
+
},
|
|
477
848
|
{
|
|
478
849
|
"name": "DataTable",
|
|
479
850
|
"import": "import { DataTable } from '@ratio-ui/core'",
|
|
@@ -580,7 +951,7 @@
|
|
|
580
951
|
{
|
|
581
952
|
"name": "DatePicker",
|
|
582
953
|
"import": "import { DatePicker } from '@ratio-ui/core'",
|
|
583
|
-
"description": "A field that shows a day as DD/MM/YYYY, reads a typed date through the format module and opens a calendar in a popover from the button at its end. Text that is not a date is marked invalid when the field loses focus
|
|
954
|
+
"description": "A field that shows a day as DD/MM/YYYY, reads a typed date through the format module and opens a calendar in a popover from the button at its end. Text that is not a date reports null (as soon as it is typed over a day, and when the field loses focus) and is marked invalid, aria-invalid, when the field loses focus; the app shows Field's error from the null. Under a name, a form submits the day as YYYY-MM-DD (empty when there is none), never the text on screen.",
|
|
584
955
|
"props": [
|
|
585
956
|
{
|
|
586
957
|
"name": "value",
|
|
@@ -599,7 +970,7 @@
|
|
|
599
970
|
"name": "onValueChange",
|
|
600
971
|
"type": "((value: Date | null) => void)",
|
|
601
972
|
"required": false,
|
|
602
|
-
"description": "Called with the day when a typed date is complete or a day is picked, and with null when the text is cleared."
|
|
973
|
+
"description": "Called with the day when a typed date is complete or a day is picked, and with null when the text is cleared or is not a date."
|
|
603
974
|
},
|
|
604
975
|
{
|
|
605
976
|
"name": "disabledDays",
|
|
@@ -636,13 +1007,13 @@
|
|
|
636
1007
|
"usage": {
|
|
637
1008
|
"whenToUse": "- One day a person types or picks, such as a \"Best before\" custom field: `value` and `onValueChange` take a `Date` (or null when empty)\n- A date inside a table: `size` 32\n- Limiting the days: `disabledDays` (for example `{ before: new Date() }`), `startMonth` and `endMonth`, which limit the calendar (a typed date is not checked against them)",
|
|
638
1009
|
"whenNotToUse": "- A period of days, such as an analytics range: use DateRangePicker\n- A calendar shown on the page, not behind a field: use Calendar\n- Showing a date as text: write it with the format module (`formatDate`)\n- Custom classes or inline styles: DatePicker takes neither `className` nor `style`",
|
|
639
|
-
"example": "```tsx\nconst [bestBefore, setBestBefore] = useState<Date | null>(null)\n\n<DatePicker aria-label=\"Best before\" value={bestBefore} onValueChange={setBestBefore} />\n<DatePicker aria-label=\"Expiry\" size={32} aria-invalid aria-describedby=\"expiry-error\" />\n```\n\nThe field shows DD/MM/YYYY and reads typed dates through the format module (\"3/1/2026\" is 3 January). Text that is not a date
|
|
1010
|
+
"example": "```tsx\nconst [bestBefore, setBestBefore] = useState<Date | null>(null)\n\n<DatePicker aria-label=\"Best before\" value={bestBefore} onValueChange={setBestBefore} />\n<DatePicker aria-label=\"Expiry\" size={32} aria-invalid aria-describedby=\"expiry-error\" />\n```\n\nThe field shows DD/MM/YYYY and reads typed dates through the format module (\"3/1/2026\" is 3 January). Text that is not a date is never reported as a day: `onValueChange` gets `null` (as soon as a held day is typed over, and again when the field loses focus), and the field turns invalid (`aria-invalid`) when it loses focus."
|
|
640
1011
|
}
|
|
641
1012
|
},
|
|
642
1013
|
{
|
|
643
1014
|
"name": "DateRangePicker",
|
|
644
1015
|
"import": "import { DateRangePicker } from '@ratio-ui/core'",
|
|
645
|
-
"description": "A field that shows a range as two DD/MM/YYYY days, reads a typed range through the format module and opens a calendar in a popover from the button at its end, for analytics periods. Pick the first day, then the last. Text that is not a range in order is
|
|
1016
|
+
"description": "A field that shows a range as two DD/MM/YYYY days, reads a typed range through the format module and opens a calendar in a popover from the button at its end, for analytics periods. Pick the first day, then the last. Text that is not a range in order reports null (as soon as it is typed over a range, and when the field loses focus) and is marked invalid, aria-invalid, when the field loses focus. Under a name, a form submits two fields, `name.from` and `name.to`, each as YYYY-MM-DD (empty when there is no range), never the text on screen.",
|
|
646
1017
|
"props": [
|
|
647
1018
|
{
|
|
648
1019
|
"name": "value",
|
|
@@ -661,7 +1032,7 @@
|
|
|
661
1032
|
"name": "onValueChange",
|
|
662
1033
|
"type": "((value: DateRangeValue | null) => void)",
|
|
663
1034
|
"required": false,
|
|
664
|
-
"description": "Called with the range when a typed range is complete or two days are picked, and with null when the text is cleared."
|
|
1035
|
+
"description": "Called with the range when a typed range is complete or two days are picked, and with null when the text is cleared or is not a range."
|
|
665
1036
|
},
|
|
666
1037
|
{
|
|
667
1038
|
"name": "disabledDays",
|
|
@@ -698,7 +1069,7 @@
|
|
|
698
1069
|
"usage": {
|
|
699
1070
|
"whenToUse": "- A period of days a person types or picks, such as an analytics range: `value` and `onValueChange` take `{ from, to }` (or null when empty)\n- Limiting the days: `disabledDays` (for example `{ after: new Date() }` for reports), `startMonth` and `endMonth`, which limit the calendar (a typed range is not checked against them)\n- A range inside a table: `size` 32",
|
|
700
1071
|
"whenNotToUse": "- One day: use DatePicker\n- A calendar shown on the page, not behind a field: use Calendar\n- Showing a range as text: write both days with the format module (`formatDate`)\n- Custom classes or inline styles: DateRangePicker takes neither `className` nor `style`",
|
|
701
|
-
"example": "```tsx\nconst [period, setPeriod] = useState<DateRangeValue | null>(null)\n\n<DateRangePicker aria-label=\"Period\" value={period} onValueChange={setPeriod} disabledDays={{ after: new Date() }} />\n```\n\nThe field shows `28/10/2026 – 03/11/2026`. Pick the first day, then the last (an earlier second day swaps them). A typed range with the end before the start, or one day only,
|
|
1072
|
+
"example": "```tsx\nconst [period, setPeriod] = useState<DateRangeValue | null>(null)\n\n<DateRangePicker aria-label=\"Period\" value={period} onValueChange={setPeriod} disabledDays={{ after: new Date() }} />\n```\n\nThe field shows `28/10/2026 – 03/11/2026`. Pick the first day, then the last (an earlier second day swaps them). A typed range with the end before the start, or one day only, is never reported as a range: `onValueChange` gets `null` (as soon as a held range is typed over, and again on blur), and the field turns invalid (`aria-invalid`) when it loses focus. Show the error with Field as in DatePicker: `error={touched && range === null ? 'Enter a period as DD/MM/YYYY – DD/MM/YYYY' : undefined}`, `touched` set from `onBlur`.\n\nUnder a `name`, a form submits two fields, `name.from` and `name.to`, each the committed day as `YYYY-MM-DD` (empty strings when the field is empty), not the text on screen: `<DateRangePicker name=\"period\" />` posts `period.from=2026-10-28` and `period.to=2026-11-03`. A disabled field posts nothing."
|
|
702
1073
|
}
|
|
703
1074
|
},
|
|
704
1075
|
{
|
|
@@ -829,6 +1200,118 @@
|
|
|
829
1200
|
}
|
|
830
1201
|
]
|
|
831
1202
|
},
|
|
1203
|
+
{
|
|
1204
|
+
"name": "Drawer",
|
|
1205
|
+
"import": "import { Drawer } from '@ratio-ui/core'",
|
|
1206
|
+
"description": "The root of a drawer: a panel people swipe away on a phone. It holds the open state and renders nothing itself. `swipeDirection` picks the edge it leaves by (down, the default, makes a bottom drawer). Pass `open` and `onOpenChange` to control it, or `defaultOpen`. The page behind is inert while it is open, with no scrim over it.",
|
|
1207
|
+
"props": [
|
|
1208
|
+
{
|
|
1209
|
+
"name": "showSwipeHandle",
|
|
1210
|
+
"type": "boolean",
|
|
1211
|
+
"required": false,
|
|
1212
|
+
"default": "false",
|
|
1213
|
+
"description": "Whether a short bar shows on the edge the drawer is swiped from, as a hint on phones. Defaults to false."
|
|
1214
|
+
}
|
|
1215
|
+
],
|
|
1216
|
+
"usage": {
|
|
1217
|
+
"whenToUse": "- A panel on a phone that people swipe away, such as filters or a short form under the list\n- A bottom drawer by default; a side drawer (swipeDirection left or right) for a phone menu\n- Show the swipe handle on phones as a hint; the corner close button stays for people who do not swipe",
|
|
1218
|
+
"whenNotToUse": "- A large surface on a wide screen, such as Settings: use a Sheet\n- A short task or a confirm step: use a Dialog\n- Help text on a control: use a Tooltip or Popover",
|
|
1219
|
+
"example": "<Drawer showSwipeHandle>\n <DrawerTrigger>Filters</DrawerTrigger>\n <DrawerContent>\n <DrawerHeader>\n <DrawerTitle>Filters</DrawerTitle>\n <DrawerDescription>Narrow the product list</DrawerDescription>\n </DrawerHeader>\n <DrawerFooter>\n <DrawerClose>Done</DrawerClose>\n </DrawerFooter>\n </DrawerContent>\n</Drawer>"
|
|
1220
|
+
},
|
|
1221
|
+
"parts": [
|
|
1222
|
+
{
|
|
1223
|
+
"name": "DrawerClose",
|
|
1224
|
+
"import": "import { DrawerClose } from '@ratio-ui/core'",
|
|
1225
|
+
"description": "A button that closes the drawer, such as Done in the footer.",
|
|
1226
|
+
"props": [
|
|
1227
|
+
{
|
|
1228
|
+
"name": "render",
|
|
1229
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DrawerCloseState>",
|
|
1230
|
+
"required": false,
|
|
1231
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
1232
|
+
}
|
|
1233
|
+
]
|
|
1234
|
+
},
|
|
1235
|
+
{
|
|
1236
|
+
"name": "DrawerContent",
|
|
1237
|
+
"import": "import { DrawerContent } from '@ratio-ui/core'",
|
|
1238
|
+
"description": "The panel, white with a hairline and 24px corners on its inner edge. A bottom drawer spans the screen and sizes to its content; a side drawer is full height and three quarters of a phone screen, 384px from the small breakpoint up. It follows the finger while it is swiped and otherwise does not move: no slide in or out, no scrim, blur or shadow. Put DrawerHeader, the content and DrawerFooter inside.",
|
|
1239
|
+
"props": [
|
|
1240
|
+
{
|
|
1241
|
+
"name": "showCloseButton",
|
|
1242
|
+
"type": "boolean",
|
|
1243
|
+
"required": false,
|
|
1244
|
+
"default": "true",
|
|
1245
|
+
"description": "Whether the corner close button shows. It is the way to close without swiping. Defaults to true."
|
|
1246
|
+
},
|
|
1247
|
+
{
|
|
1248
|
+
"name": "closeLabel",
|
|
1249
|
+
"type": "string",
|
|
1250
|
+
"required": false,
|
|
1251
|
+
"default": "Close",
|
|
1252
|
+
"description": "The accessible name of the corner close button. Defaults to Close."
|
|
1253
|
+
},
|
|
1254
|
+
{
|
|
1255
|
+
"name": "render",
|
|
1256
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DrawerPopupState>",
|
|
1257
|
+
"required": false,
|
|
1258
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
1259
|
+
}
|
|
1260
|
+
]
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
"name": "DrawerDescription",
|
|
1264
|
+
"import": "import { DrawerDescription } from '@ratio-ui/core'",
|
|
1265
|
+
"description": "One line that says what the drawer is for, in subdued body text.",
|
|
1266
|
+
"props": [
|
|
1267
|
+
{
|
|
1268
|
+
"name": "render",
|
|
1269
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DrawerDescriptionState>",
|
|
1270
|
+
"required": false,
|
|
1271
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
1272
|
+
}
|
|
1273
|
+
]
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
"name": "DrawerFooter",
|
|
1277
|
+
"import": "import { DrawerFooter } from '@ratio-ui/core'",
|
|
1278
|
+
"description": "The actions at the bottom of the drawer, stacked full width for a thumb.",
|
|
1279
|
+
"props": []
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
"name": "DrawerHeader",
|
|
1283
|
+
"import": "import { DrawerHeader } from '@ratio-ui/core'",
|
|
1284
|
+
"description": "The title and description, stacked, with room on the right for the close button.",
|
|
1285
|
+
"props": []
|
|
1286
|
+
},
|
|
1287
|
+
{
|
|
1288
|
+
"name": "DrawerTitle",
|
|
1289
|
+
"import": "import { DrawerTitle } from '@ratio-ui/core'",
|
|
1290
|
+
"description": "The drawer's name, in the b4 style. It names the drawer for assistive technology.",
|
|
1291
|
+
"props": [
|
|
1292
|
+
{
|
|
1293
|
+
"name": "render",
|
|
1294
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DrawerTitleState>",
|
|
1295
|
+
"required": false,
|
|
1296
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
1297
|
+
}
|
|
1298
|
+
]
|
|
1299
|
+
},
|
|
1300
|
+
{
|
|
1301
|
+
"name": "DrawerTrigger",
|
|
1302
|
+
"import": "import { DrawerTrigger } from '@ratio-ui/core'",
|
|
1303
|
+
"description": "The button that opens the drawer.",
|
|
1304
|
+
"props": [
|
|
1305
|
+
{
|
|
1306
|
+
"name": "render",
|
|
1307
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DrawerTriggerState>",
|
|
1308
|
+
"required": false,
|
|
1309
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
1310
|
+
}
|
|
1311
|
+
]
|
|
1312
|
+
}
|
|
1313
|
+
]
|
|
1314
|
+
},
|
|
832
1315
|
{
|
|
833
1316
|
"name": "DropdownMenu",
|
|
834
1317
|
"import": "import { DropdownMenu } from '@ratio-ui/core'",
|
|
@@ -1099,7 +1582,7 @@
|
|
|
1099
1582
|
{
|
|
1100
1583
|
"name": "Field",
|
|
1101
1584
|
"import": "import { Field } from '@ratio-ui/core'",
|
|
1102
|
-
"description": "A form row: label, control, hint and error. It wires the label to the control by id, links the hint and error with aria-describedby, and sets aria-invalid when there is an error. The control keeps an id it already has.",
|
|
1585
|
+
"description": "A form row: label, control, hint and error. It wires the label to the control by id and aria-labelledby (which also names a group such as RadioGroup), links the hint and error with aria-describedby, and sets aria-invalid when there is an error. The control keeps an id it already has.",
|
|
1103
1586
|
"props": [
|
|
1104
1587
|
{
|
|
1105
1588
|
"name": "label",
|
|
@@ -1141,13 +1624,13 @@
|
|
|
1141
1624
|
"name": "children",
|
|
1142
1625
|
"type": "ReactElement<Record<string, unknown>, string | JSXElementConstructor<any>> | ((props: FieldControlProps) => ReactNode)",
|
|
1143
1626
|
"required": true,
|
|
1144
|
-
"description": "The control: one element, such as Input, which gets an id, aria-describedby, aria-invalid, aria-required and disabled. When the control sits inside a wrapper such as InputGroup, pass a function instead and spread the props it receives onto the input itself."
|
|
1627
|
+
"description": "The control: one element, such as Input, which gets an id, aria-labelledby, aria-describedby, aria-invalid, aria-required and disabled. When the control sits inside a wrapper such as InputGroup, pass a function instead and spread the props it receives onto the input itself."
|
|
1145
1628
|
}
|
|
1146
1629
|
],
|
|
1147
1630
|
"usage": {
|
|
1148
|
-
"whenToUse": "- Every form row: a label, one control, and optional hint, error, info tooltip and required mark\n- Wiring: Field sets the control's id, aria-describedby, aria-invalid, aria-required and disabled, so you do not",
|
|
1631
|
+
"whenToUse": "- Every form row: a label, one control, and optional hint, error, info tooltip and required mark\n- Wiring: Field sets the control's id, aria-labelledby, aria-describedby, aria-invalid, aria-required and disabled, so you do not",
|
|
1149
1632
|
"whenNotToUse": "- A heading for a group of controls: use a fieldset with a legend\n- A label with no control beside it: use Label alone, with `htmlFor`\n- Long help that must be read to finish the task: put it on the screen as the hint",
|
|
1150
|
-
"example": "```tsx\n<Field label=\"Title\" hint=\"Shown in search results\" error={errors.title} required>\n <Input />\n</Field>\n<Field label=\"MRP\" info=\"Maximum retail price, with tax\">\n <Input inputMode=\"decimal\" />\n</Field>\n```\n\nFor an input inside an InputGroup, pass a function child and spread its props onto the input: `<Field label=\"MRP\">{(props) => <InputGroup>…<InputGroupInput {...props} /></InputGroup>}</Field>`.\n\nFor a Select, which renders no element of its own, spread the props onto its trigger: `<Field label=\"GST rate\">{(props) => <Select items={rates}><SelectTrigger {...props}><SelectValue /></SelectTrigger><SelectContent>…</SelectContent></Select>}</Field>`.\n\nThe error shows beside the alert glyph in the error ink (question 1) and replaces the hint. Label is the same label as a separate part."
|
|
1633
|
+
"example": "```tsx\n<Field label=\"Title\" hint=\"Shown in search results\" error={errors.title} required>\n <Input />\n</Field>\n<Field label=\"MRP\" info=\"Maximum retail price, with tax\">\n <Input inputMode=\"decimal\" />\n</Field>\n```\n\nFor an input inside an InputGroup, pass a function child and spread its props onto the input: `<Field label=\"MRP\">{(props) => <InputGroup>…<InputGroupInput {...props} /></InputGroup>}</Field>`.\n\nA Combobox or a RadioGroup goes straight inside, like an Input: the label names a radio group through `aria-labelledby`, because a label cannot point at a group.\n\nFor a Select, which renders no element of its own, spread the props onto its trigger: `<Field label=\"GST rate\">{(props) => <Select items={rates}><SelectTrigger {...props}><SelectValue /></SelectTrigger><SelectContent>…</SelectContent></Select>}</Field>`.\n\nThe error shows beside the alert glyph in the error ink (question 1) and replaces the hint. Label is the same label as a separate part."
|
|
1151
1634
|
},
|
|
1152
1635
|
"parts": [
|
|
1153
1636
|
{
|
|
@@ -1279,11 +1762,11 @@
|
|
|
1279
1762
|
{
|
|
1280
1763
|
"name": "Icon",
|
|
1281
1764
|
"import": "import { Icon } from '@ratio-ui/core'",
|
|
1282
|
-
"description": "Draws one icon of the registry: the design system's own glyphs, filled in a single colour, and Tabler's icons for the rest, drawn with a 1.5px line at every size. The icon is a square box of 8, 12 or 16px and takes the colour of its tone.",
|
|
1765
|
+
"description": "Draws one icon of the registry: the design system's own glyphs, filled (or, for check-mark, stroked) in a single colour, and Tabler's icons for the rest, drawn with a 1.5px line at every size. The icon is a square box of 8, 12 or 16px and takes the colour of its tone.",
|
|
1283
1766
|
"props": [
|
|
1284
1767
|
{
|
|
1285
1768
|
"name": "name",
|
|
1286
|
-
"type": "\"alert-triangle\" | \"calendar\" | \"check\" | \"chevron-left\" | \"chevron-right\" | \"export\" | \"import\" | \"info-circle\" | \"menu\" | \"more\" | \"nav-analytics\" | \"nav-apps\" | \"nav-caret-down\" | \"nav-chevron\" | \"nav-content\" | \"nav-customers\" | \"nav-discounts\" | \"nav-growth\" | \"nav-home\" | \"nav-markets\" | \"nav-orders\" | \"nav-product\" | \"nav-product-2\" | \"nav-sales-channels\" | \"nav-settings\" | \"nav-shortcut\" | \"plus\" | \"search\" | \"x\"",
|
|
1769
|
+
"type": "\"alert-triangle\" | \"arrow-down\" | \"arrow-up\" | \"calendar\" | \"check\" | \"check-mark\" | \"chevron-left\" | \"chevron-right\" | \"export\" | \"import\" | \"info-circle\" | \"menu\" | \"more\" | \"nav-analytics\" | \"nav-apps\" | \"nav-caret-down\" | \"nav-chevron\" | \"nav-content\" | \"nav-customers\" | \"nav-discounts\" | \"nav-growth\" | \"nav-home\" | \"nav-markets\" | \"nav-orders\" | \"nav-product\" | \"nav-product-2\" | \"nav-sales-channels\" | \"nav-settings\" | \"nav-shortcut\" | \"plus\" | \"search\" | \"x\"",
|
|
1287
1770
|
"required": true,
|
|
1288
1771
|
"description": "Which icon to draw, by name."
|
|
1289
1772
|
},
|
|
@@ -1309,7 +1792,7 @@
|
|
|
1309
1792
|
}
|
|
1310
1793
|
],
|
|
1311
1794
|
"usage": {
|
|
1312
|
-
"whenToUse": "- A glyph beside a label inside a control: the plus on a main button, the magnifier in a search field, the export tray on a secondary button. Use size 12\n- The side navigation: the nav glyphs at size 16 (nav-home and nav-product are the design system's own; nav-orders, nav-customers, nav-growth, nav-discounts, nav-content, nav-markets, nav-analytics, nav-sales-channels, nav-apps and nav-settings are Tabler stand-ins for the dashboard's sections, question 7), and the disclosure caret (nav-chevron or nav-caret-down, one glyph under two names) at size 8\n- The date pickers' open button: calendar (Tabler) at size 12\n- Pagination: chevron-left and chevron-right at size 8\n- A mark that Tabler supplies: check, x, alert-triangle, info-circle, import, more (three dots) and menu (the phone menu button). They are drawn with a 1.5px line at every size, so they sit beside the design system's own glyphs without looking heavier\n- Meaning that lives only in the icon: pass label. The icon is then an image that assistive technology announces under that name. Without a label it is decoration and is hidden from assistive technology\n- Colour: tone current, the default, takes the colour of the text around the icon. icon is the design system's icon ink, subdued is its subdued text ink and primary is the accent\n- Chevron geometry (design question 9): the design system has no vector for its pagination chevrons, only a
|
|
1795
|
+
"whenToUse": "- A glyph beside a label inside a control: the plus on a main button, the magnifier in a search field, the export tray on a secondary button. Use size 12\n- The side navigation: the nav glyphs at size 16 (nav-home and nav-product are the design system's own; nav-orders, nav-customers, nav-growth, nav-discounts, nav-content, nav-markets, nav-analytics, nav-sales-channels, nav-apps and nav-settings are Tabler stand-ins for the dashboard's sections, question 7), and the disclosure caret (nav-chevron or nav-caret-down, one glyph under two names) at size 8\n- The date pickers' open button: calendar (Tabler) at size 12\n- Pagination: chevron-left and chevron-right at size 8\n- A mark that Tabler supplies: check, x, alert-triangle, info-circle, import, more (three dots) and menu (the phone menu button). They are drawn with a 1.5px line at every size, so they sit beside the design system's own glyphs without looking heavier\n- Meaning that lives only in the icon: pass label. The icon is then an image that assistive technology announces under that name. Without a label it is decoration and is hidden from assistive technology\n- Colour: tone current, the default, takes the colour of the text around the icon. icon is the design system's icon ink, subdued is its subdued text ink and primary is the accent\n- Chevron geometry (design question 9): the design system has no vector for its pagination chevrons, only a CSS caret in an 8px box (a 4.48px square with 1.5px top and right borders, rotated 45 degrees, square ends), so chevron-left and chevron-right draw that caret as a path: about 8.5px tall, so it reaches 0.23 units past the top and bottom of the 8 unit box (glyphs are not clipped), centred at x 3.5 for the right chevron and 4.5 for the left. Draw them at size 8, and expect them to be replaced when the designer sends real vectors\n- check-mark is the design system's own checkbox check, the path M1 4.2 L3 6.2 L7 1.8 in an 8 unit box as a 1.4 line with round ends; use it at size 8. arrow-up and arrow-down are Tabler's, for a table's sort direction, because the design system has no sort glyph (question 7)",
|
|
1313
1796
|
"whenNotToUse": "- Decoration that adds no meaning. An icon next to text that already says the same thing is hidden from assistive technology, so leave the label off, and leave the icon out when it adds nothing\n- An icon the registry does not have. Components accept no className or style, and icons come from the registry only, so a new one is a registry entry: the design system's glyph first, Tabler for the rest\n- An icon-only control without a name. Pass label, or give the control its own accessible name\n- A size other than 8, 12 or 16, or a colour other than the four tones. There is no red, no destructive colour and no third accent: an error is marked with the alert-triangle glyph beside its message, not with a colour\n- Emoji, or unicode arrows and symbols, as icons. Inter's web subsets do not hold them and the design system bans them",
|
|
1314
1797
|
"example": "import { Icon } from '@ratio-ui/core'\n\n// Beside text that names it: decoration, hidden from assistive technology\n<button type=\"button\">\n <Icon name=\"plus\" />\n Add product\n</button>\n\n// Alone: the label is the accessible name\n<Icon name=\"search\" tone=\"icon\" label=\"Search\" />\n\n// Pagination chevrons are drawn for an 8px box\n<Icon name=\"chevron-right\" size={8} />"
|
|
1315
1798
|
}
|
|
@@ -1403,59 +1886,169 @@
|
|
|
1403
1886
|
"default": "36",
|
|
1404
1887
|
"description": "The height in px: 36 for forms and search, 32 for fields inside a table. Defaults to 36."
|
|
1405
1888
|
},
|
|
1889
|
+
{
|
|
1890
|
+
"name": "search",
|
|
1891
|
+
"type": "boolean",
|
|
1892
|
+
"required": false,
|
|
1893
|
+
"default": "false",
|
|
1894
|
+
"description": "Draws the design system search bar's 8px side padding instead of 12px. SearchField sets it; forms leave it off."
|
|
1895
|
+
},
|
|
1406
1896
|
{
|
|
1407
1897
|
"name": "ref",
|
|
1408
1898
|
"type": "Ref<HTMLDivElement>",
|
|
1409
1899
|
"required": false,
|
|
1410
|
-
"description": "Receives the group element."
|
|
1411
|
-
}
|
|
1412
|
-
],
|
|
1413
|
-
"usage": {
|
|
1414
|
-
"whenToUse": "- A field with something beside the input, all inside one ring: a rupee sign before a price, kg after a weight, a search icon, or a shortcut hint such as ⌘K\n- A table search field or the top bar search: an icon at the start and a shortcut hint at the end\n- A compact field in a table: `size` 32, as for Input",
|
|
1415
|
-
"whenNotToUse": "- A plain field with nothing beside the input: use Input\n- A button inside the field: put it next to the group, because an addon holds text and icons only\n- Custom classes or inline styles: none of the parts take `className` or `style`",
|
|
1416
|
-
"example": "<InputGroup>\n <InputGroupAddon>\n <InputGroupText>₹</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput aria-label=\"Selling price\" inputMode=\"decimal\" />\n</InputGroup>\n<InputGroup>\n <InputGroupAddon><Icon name=\"search\" /></InputGroupAddon>\n <InputGroupInput aria-label=\"Search\" placeholder=\"Search by name, email, etc.\" />\n <InputGroupAddon align=\"end\"><InputGroupShortcut>⌘K</InputGroupShortcut></InputGroupAddon>\n</InputGroup>"
|
|
1417
|
-
},
|
|
1418
|
-
"parts": [
|
|
1900
|
+
"description": "Receives the group element."
|
|
1901
|
+
}
|
|
1902
|
+
],
|
|
1903
|
+
"usage": {
|
|
1904
|
+
"whenToUse": "- A field with something beside the input, all inside one ring: a rupee sign before a price, kg after a weight, a search icon, or a shortcut hint such as ⌘K\n- A table search field or the top bar search: an icon at the start and a shortcut hint at the end\n- A compact field in a table: `size` 32, as for Input",
|
|
1905
|
+
"whenNotToUse": "- A plain field with nothing beside the input: use Input\n- A button inside the field: put it next to the group, because an addon holds text and icons only\n- Custom classes or inline styles: none of the parts take `className` or `style`",
|
|
1906
|
+
"example": "<InputGroup>\n <InputGroupAddon>\n <InputGroupText>₹</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput aria-label=\"Selling price\" inputMode=\"decimal\" />\n</InputGroup>\n<InputGroup>\n <InputGroupAddon><Icon name=\"search\" /></InputGroupAddon>\n <InputGroupInput aria-label=\"Search\" placeholder=\"Search by name, email, etc.\" />\n <InputGroupAddon align=\"end\"><InputGroupShortcut>⌘K</InputGroupShortcut></InputGroupAddon>\n</InputGroup>"
|
|
1907
|
+
},
|
|
1908
|
+
"parts": [
|
|
1909
|
+
{
|
|
1910
|
+
"name": "InputGroupAddon",
|
|
1911
|
+
"import": "import { InputGroupAddon } from '@ratio-ui/core'",
|
|
1912
|
+
"description": "Holds an icon, a prefix, a suffix or a shortcut hint on one side of the input. Clicking it, off a button, moves focus to the input.",
|
|
1913
|
+
"props": [
|
|
1914
|
+
{
|
|
1915
|
+
"name": "align",
|
|
1916
|
+
"type": "\"end\" | \"start\"",
|
|
1917
|
+
"required": false,
|
|
1918
|
+
"default": "start",
|
|
1919
|
+
"description": "The side of the input: start before it, end after it. Defaults to start."
|
|
1920
|
+
}
|
|
1921
|
+
]
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
"name": "InputGroupInput",
|
|
1925
|
+
"import": "import { InputGroupInput } from '@ratio-ui/core'",
|
|
1926
|
+
"description": "The input of an InputGroup. It draws no ring: the group does. Mark it invalid with aria-invalid.",
|
|
1927
|
+
"props": [
|
|
1928
|
+
{
|
|
1929
|
+
"name": "ref",
|
|
1930
|
+
"type": "Ref<HTMLInputElement>",
|
|
1931
|
+
"required": false,
|
|
1932
|
+
"description": "Receives the input element."
|
|
1933
|
+
}
|
|
1934
|
+
]
|
|
1935
|
+
},
|
|
1936
|
+
{
|
|
1937
|
+
"name": "InputGroupShortcut",
|
|
1938
|
+
"import": "import { InputGroupShortcut } from '@ratio-ui/core'",
|
|
1939
|
+
"description": "A shortcut hint such as ⌘K inside an end addon, drawn as a small keycap.",
|
|
1940
|
+
"props": []
|
|
1941
|
+
},
|
|
1942
|
+
{
|
|
1943
|
+
"name": "InputGroupText",
|
|
1944
|
+
"import": "import { InputGroupText } from '@ratio-ui/core'",
|
|
1945
|
+
"description": "A text prefix or suffix inside an addon, such as a currency sign or a unit, in the muted colour.",
|
|
1946
|
+
"props": []
|
|
1947
|
+
}
|
|
1948
|
+
]
|
|
1949
|
+
},
|
|
1950
|
+
{
|
|
1951
|
+
"name": "InputOtp",
|
|
1952
|
+
"import": "import { InputOtp } from '@ratio-ui/core'",
|
|
1953
|
+
"description": "A one-time-code field: six 44px digit slots (set `length` for another count) over one hidden input, so the browser offers the SMS code (autocomplete one-time-code), a pasted code fills every slot, and the numeric keypad opens on phones. Digits only.",
|
|
1954
|
+
"props": [
|
|
1955
|
+
{
|
|
1956
|
+
"name": "length",
|
|
1957
|
+
"type": "number",
|
|
1958
|
+
"required": false,
|
|
1959
|
+
"default": "6",
|
|
1960
|
+
"description": "The number of digits. Defaults to 6."
|
|
1961
|
+
},
|
|
1962
|
+
{
|
|
1963
|
+
"name": "value",
|
|
1964
|
+
"type": "string",
|
|
1965
|
+
"required": false,
|
|
1966
|
+
"description": "The code typed so far, for a controlled field."
|
|
1967
|
+
},
|
|
1968
|
+
{
|
|
1969
|
+
"name": "defaultValue",
|
|
1970
|
+
"type": "string",
|
|
1971
|
+
"required": false,
|
|
1972
|
+
"description": "The code typed so far, for an uncontrolled field."
|
|
1973
|
+
},
|
|
1974
|
+
{
|
|
1975
|
+
"name": "onValueChange",
|
|
1976
|
+
"type": "((value: string) => void)",
|
|
1977
|
+
"required": false,
|
|
1978
|
+
"description": "Called with the whole code on every change, including a paste."
|
|
1979
|
+
},
|
|
1980
|
+
{
|
|
1981
|
+
"name": "onComplete",
|
|
1982
|
+
"type": "((value: string) => void)",
|
|
1983
|
+
"required": false,
|
|
1984
|
+
"description": "Called once with the code when every slot is filled."
|
|
1985
|
+
},
|
|
1986
|
+
{
|
|
1987
|
+
"name": "disabled",
|
|
1988
|
+
"type": "boolean",
|
|
1989
|
+
"required": false,
|
|
1990
|
+
"description": "Stops editing and halves the opacity."
|
|
1991
|
+
},
|
|
1992
|
+
{
|
|
1993
|
+
"name": "aria-invalid",
|
|
1994
|
+
"type": "boolean | \"true\" | \"false\"",
|
|
1995
|
+
"required": false,
|
|
1996
|
+
"description": "Draws the error ring on every slot."
|
|
1997
|
+
},
|
|
1998
|
+
{
|
|
1999
|
+
"name": "aria-label",
|
|
2000
|
+
"type": "string",
|
|
2001
|
+
"required": false,
|
|
2002
|
+
"description": "The accessible name, for example \"6-digit code\"."
|
|
2003
|
+
},
|
|
2004
|
+
{
|
|
2005
|
+
"name": "aria-labelledby",
|
|
2006
|
+
"type": "string",
|
|
2007
|
+
"required": false,
|
|
2008
|
+
"description": "The id of an element that names the field."
|
|
2009
|
+
},
|
|
2010
|
+
{
|
|
2011
|
+
"name": "aria-describedby",
|
|
2012
|
+
"type": "string",
|
|
2013
|
+
"required": false,
|
|
2014
|
+
"description": "The ids of the elements that describe the field, such as its hint or error. Field sets it."
|
|
2015
|
+
},
|
|
2016
|
+
{
|
|
2017
|
+
"name": "aria-required",
|
|
2018
|
+
"type": "boolean | \"true\" | \"false\"",
|
|
2019
|
+
"required": false,
|
|
2020
|
+
"description": "Tells assistive technology that the code must be filled. Field sets it for a required field."
|
|
2021
|
+
},
|
|
1419
2022
|
{
|
|
1420
|
-
"name": "
|
|
1421
|
-
"
|
|
1422
|
-
"
|
|
1423
|
-
"
|
|
1424
|
-
{
|
|
1425
|
-
"name": "align",
|
|
1426
|
-
"type": "\"end\" | \"start\"",
|
|
1427
|
-
"required": false,
|
|
1428
|
-
"default": "start",
|
|
1429
|
-
"description": "The side of the input: start before it, end after it. Defaults to start."
|
|
1430
|
-
}
|
|
1431
|
-
]
|
|
2023
|
+
"name": "id",
|
|
2024
|
+
"type": "string",
|
|
2025
|
+
"required": false,
|
|
2026
|
+
"description": "The id of the hidden input, for a label's htmlFor. Field sets it."
|
|
1432
2027
|
},
|
|
1433
2028
|
{
|
|
1434
|
-
"name": "
|
|
1435
|
-
"
|
|
1436
|
-
"
|
|
1437
|
-
"
|
|
1438
|
-
{
|
|
1439
|
-
"name": "ref",
|
|
1440
|
-
"type": "Ref<HTMLInputElement>",
|
|
1441
|
-
"required": false,
|
|
1442
|
-
"description": "Receives the input element."
|
|
1443
|
-
}
|
|
1444
|
-
]
|
|
2029
|
+
"name": "name",
|
|
2030
|
+
"type": "string",
|
|
2031
|
+
"required": false,
|
|
2032
|
+
"description": "The form field name."
|
|
1445
2033
|
},
|
|
1446
2034
|
{
|
|
1447
|
-
"name": "
|
|
1448
|
-
"
|
|
1449
|
-
"
|
|
1450
|
-
"
|
|
2035
|
+
"name": "autoFocus",
|
|
2036
|
+
"type": "boolean",
|
|
2037
|
+
"required": false,
|
|
2038
|
+
"description": "Focuses the field on mount."
|
|
1451
2039
|
},
|
|
1452
2040
|
{
|
|
1453
|
-
"name": "
|
|
1454
|
-
"
|
|
1455
|
-
"
|
|
1456
|
-
"
|
|
2041
|
+
"name": "ref",
|
|
2042
|
+
"type": "Ref<HTMLInputElement>",
|
|
2043
|
+
"required": false,
|
|
2044
|
+
"description": "Receives the hidden input element."
|
|
1457
2045
|
}
|
|
1458
|
-
]
|
|
2046
|
+
],
|
|
2047
|
+
"usage": {
|
|
2048
|
+
"whenToUse": "- The code step of a sign-in: the 6-digit code sent by SMS or email (\"Verify and sign in\")\n- Any short numeric code: set `length` for another count\n- A wrong code: set `aria-invalid` and every slot draws the error ring, and put the message beside the field in text",
|
|
2049
|
+
"whenNotToUse": "- A code with letters: InputOtp takes digits only\n- A long or free-form value: use Input\n- Custom classes or inline styles: InputOtp takes no `className` and no `style`",
|
|
2050
|
+
"example": "```tsx\n<InputOtp aria-label=\"6-digit code\" value={code} onValueChange={setCode} onComplete={(code) => verify(code)} />\n<InputOtp aria-label=\"PIN\" length={4} aria-invalid />\n```\n\nThe browser offers the SMS code through `autocomplete=\"one-time-code\"`, and a pasted code fills every slot."
|
|
2051
|
+
}
|
|
1459
2052
|
},
|
|
1460
2053
|
{
|
|
1461
2054
|
"name": "Kbd",
|
|
@@ -1483,6 +2076,31 @@
|
|
|
1483
2076
|
}
|
|
1484
2077
|
]
|
|
1485
2078
|
},
|
|
2079
|
+
{
|
|
2080
|
+
"name": "KeyValueList",
|
|
2081
|
+
"import": "import { KeyValueList } from '@ratio-ui/core'",
|
|
2082
|
+
"description": "Settings rows in a hairline bordered panel: the label on the left, the value on the right and an optional action. It is a description list, so a screen reader announces each label with its value.",
|
|
2083
|
+
"props": [
|
|
2084
|
+
{
|
|
2085
|
+
"name": "items",
|
|
2086
|
+
"type": "KeyValueItem[]",
|
|
2087
|
+
"required": true,
|
|
2088
|
+
"description": "The rows, in order."
|
|
2089
|
+
},
|
|
2090
|
+
{
|
|
2091
|
+
"name": "emptyValue",
|
|
2092
|
+
"type": "string",
|
|
2093
|
+
"required": false,
|
|
2094
|
+
"default": "Not set",
|
|
2095
|
+
"description": "What an empty value shows. Defaults to \"Not set\"."
|
|
2096
|
+
}
|
|
2097
|
+
],
|
|
2098
|
+
"usage": {
|
|
2099
|
+
"whenToUse": "- Settings and detail rows: a label on the left, its value on the right, an optional action such as Edit\n- A value that may be empty: it shows a placeholder, \"Not set\" by default",
|
|
2100
|
+
"whenNotToUse": "- Rows of many columns to scan or sort: use Table or DataTable\n- Editing a value in place: use a form with Input",
|
|
2101
|
+
"example": "```tsx\n<KeyValueList\n items={[\n { label: 'Store name', value: 'Maison Yara', action: { label: 'Edit', onClick: edit } },\n { label: 'Phone' },\n ]}\n/>\n```\n\nMoney and dates arrive already formatted; use the format module."
|
|
2102
|
+
}
|
|
2103
|
+
},
|
|
1486
2104
|
{
|
|
1487
2105
|
"name": "Link",
|
|
1488
2106
|
"import": "import { Link } from '@ratio-ui/core'",
|
|
@@ -1522,7 +2140,7 @@
|
|
|
1522
2140
|
}
|
|
1523
2141
|
],
|
|
1524
2142
|
"usage": {
|
|
1525
|
-
"whenToUse": "- A text link to another page: \"← Products\", \"View all variants →\"\n- A back link in a detail page's body (the page header
|
|
2143
|
+
"whenToUse": "- A text link to another page: \"← Products\", \"View all variants →\"\n- A back link in a detail page's body (the page header draws its back link with Link too, so the two look alike)",
|
|
1526
2144
|
"whenNotToUse": "- An action that changes something: use Button\n- A whole table row: use DataTable's `rowHref`\n- A navigation row in the side navigation: use SideNav",
|
|
1527
2145
|
"example": "<Link href=\"/products\" back>Products</Link>\n<Link href=\"/products/blue-shirt/variants\" forward>View all variants</Link>"
|
|
1528
2146
|
}
|
|
@@ -1870,6 +2488,12 @@
|
|
|
1870
2488
|
"import": "import { PopoverTrigger } from '@ratio-ui/core'",
|
|
1871
2489
|
"description": "The element that opens the popover on click or Enter. It renders a button unless render says otherwise.",
|
|
1872
2490
|
"props": [
|
|
2491
|
+
{
|
|
2492
|
+
"name": "render",
|
|
2493
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PopoverTriggerState>",
|
|
2494
|
+
"required": false,
|
|
2495
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
2496
|
+
},
|
|
1873
2497
|
{
|
|
1874
2498
|
"name": "handle",
|
|
1875
2499
|
"type": "PopoverHandle<unknown>",
|
|
@@ -1882,12 +2506,6 @@
|
|
|
1882
2506
|
"required": false,
|
|
1883
2507
|
"description": "A payload to pass to the popover when it is opened."
|
|
1884
2508
|
},
|
|
1885
|
-
{
|
|
1886
|
-
"name": "render",
|
|
1887
|
-
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PopoverTriggerState>",
|
|
1888
|
-
"required": false,
|
|
1889
|
-
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
1890
|
-
},
|
|
1891
2509
|
{
|
|
1892
2510
|
"name": "delay",
|
|
1893
2511
|
"type": "number",
|
|
@@ -1913,6 +2531,75 @@
|
|
|
1913
2531
|
}
|
|
1914
2532
|
]
|
|
1915
2533
|
},
|
|
2534
|
+
{
|
|
2535
|
+
"name": "Progress",
|
|
2536
|
+
"import": "import { Progress } from '@ratio-ui/core'",
|
|
2537
|
+
"description": "The thin progress bar of question 5, 2px high, for page loads and refetches. Determinate with a value, indeterminate without one (a partial bar that moves only when the loading animation token names a motion, question 5). Base UI gives it the progressbar role, its label and its value text.",
|
|
2538
|
+
"props": [
|
|
2539
|
+
{
|
|
2540
|
+
"name": "value",
|
|
2541
|
+
"type": "number | null",
|
|
2542
|
+
"required": false,
|
|
2543
|
+
"default": "null",
|
|
2544
|
+
"description": "The current value; leave it out or pass null for an indeterminate bar."
|
|
2545
|
+
},
|
|
2546
|
+
{
|
|
2547
|
+
"name": "max",
|
|
2548
|
+
"type": "number",
|
|
2549
|
+
"required": false,
|
|
2550
|
+
"default": "100",
|
|
2551
|
+
"description": "The value at which the bar is full. Defaults to 100; for steps, the number of steps."
|
|
2552
|
+
},
|
|
2553
|
+
{
|
|
2554
|
+
"name": "label",
|
|
2555
|
+
"type": "string",
|
|
2556
|
+
"required": false,
|
|
2557
|
+
"description": "A visible label, which also names the bar for screen readers."
|
|
2558
|
+
},
|
|
2559
|
+
{
|
|
2560
|
+
"name": "showValue",
|
|
2561
|
+
"type": "boolean",
|
|
2562
|
+
"required": false,
|
|
2563
|
+
"description": "Shows the value on the right: a percent, or \"value/max\" with steps."
|
|
2564
|
+
},
|
|
2565
|
+
{
|
|
2566
|
+
"name": "steps",
|
|
2567
|
+
"type": "boolean",
|
|
2568
|
+
"required": false,
|
|
2569
|
+
"description": "The step variant: counts completed steps out of max, such as 0/5 for the setup guide. Implies showValue."
|
|
2570
|
+
},
|
|
2571
|
+
{
|
|
2572
|
+
"name": "aria-label",
|
|
2573
|
+
"type": "string",
|
|
2574
|
+
"required": false,
|
|
2575
|
+
"description": "The accessible name when there is no visible label."
|
|
2576
|
+
}
|
|
2577
|
+
],
|
|
2578
|
+
"usage": {
|
|
2579
|
+
"whenToUse": "- A page load or a refetch of content already on screen (the thin 2px bar, question 5)\n- The setup guide's step count, with the steps variant (\"0/5\")",
|
|
2580
|
+
"whenNotToUse": "- A first load of a list or table: use Skeleton rows\n- A short wait on one control: use Spinner",
|
|
2581
|
+
"example": "```tsx\n<Progress label=\"Loading orders\" value={60} showValue />\n<Progress label=\"Setup guide\" value={0} max={5} steps />\n<Progress aria-label=\"Refreshing\" />\n```\n\nWithout a value the bar is indeterminate: a static partial bar, since the loading animation token is none."
|
|
2582
|
+
}
|
|
2583
|
+
},
|
|
2584
|
+
{
|
|
2585
|
+
"name": "RadioGroup",
|
|
2586
|
+
"import": "import { RadioGroup } from '@ratio-ui/core'",
|
|
2587
|
+
"description": "A column of radio buttons where exactly one can be on. The arrow keys move the choice. aria-invalid on the group, as Field sets it, draws the error ring on every item.",
|
|
2588
|
+
"props": [],
|
|
2589
|
+
"usage": {
|
|
2590
|
+
"whenToUse": "- One choice among a few options that all deserve to be seen at once, such as a plan or a delivery method\n- A form field where the answer is exactly one of two to five values",
|
|
2591
|
+
"whenNotToUse": "- Several answers can be on: use checkboxes\n- A setting that applies at once: use a switch\n- A long list of options: use a select\n- Styling: RadioGroup and RadioGroupItem take no `className` and no `style`",
|
|
2592
|
+
"example": "```tsx\n<RadioGroup aria-label=\"Plan\" value={plan} onValueChange={setPlan}>\n <Inline gap={8} align=\"center\">\n <RadioGroupItem id=\"plan-free\" value=\"free\" />\n <Label htmlFor=\"plan-free\">Free</Label>\n </Inline>\n <Inline gap={8} align=\"center\">\n <RadioGroupItem id=\"plan-pro\" value=\"pro\" />\n <Label htmlFor=\"plan-pro\">Pro</Label>\n </Inline>\n</RadioGroup>\n```\n\nGive every item an `id` and a visible `Label` that points at it, so the text people read is the radio's name."
|
|
2593
|
+
},
|
|
2594
|
+
"parts": [
|
|
2595
|
+
{
|
|
2596
|
+
"name": "RadioGroupItem",
|
|
2597
|
+
"import": "import { RadioGroupItem } from '@ratio-ui/core'",
|
|
2598
|
+
"description": "One choice in a RadioGroup: a 14px round control like the checkbox, drawn with a hairline ring and filled in the primary colour with a white dot when chosen. An invisible 24px area around it takes the tap.",
|
|
2599
|
+
"props": []
|
|
2600
|
+
}
|
|
2601
|
+
]
|
|
2602
|
+
},
|
|
1916
2603
|
{
|
|
1917
2604
|
"name": "SaveBar",
|
|
1918
2605
|
"import": "import { SaveBar } from '@ratio-ui/core'",
|
|
@@ -1984,6 +2671,37 @@
|
|
|
1984
2671
|
"example": "```tsx\n<SaveBar dirty={form.isDirty} saving={form.isSaving} onSave={form.save} onDiscard={form.reset} />\n```\n\nIt renders in flow and nothing when not dirty; the app shell decides where it sits. While saving, Save is disabled."
|
|
1985
2672
|
}
|
|
1986
2673
|
},
|
|
2674
|
+
{
|
|
2675
|
+
"name": "ScrollArea",
|
|
2676
|
+
"import": "import { ScrollArea } from '@ratio-ui/core'",
|
|
2677
|
+
"description": "A scrolling region that fills its parent, which sets the height or width, with a thin scrollbar in the design system greys.",
|
|
2678
|
+
"props": [
|
|
2679
|
+
{
|
|
2680
|
+
"name": "children",
|
|
2681
|
+
"type": "ReactNode",
|
|
2682
|
+
"required": true,
|
|
2683
|
+
"description": "The scrolling content."
|
|
2684
|
+
},
|
|
2685
|
+
{
|
|
2686
|
+
"name": "orientation",
|
|
2687
|
+
"type": "\"both\" | \"horizontal\" | \"vertical\"",
|
|
2688
|
+
"required": false,
|
|
2689
|
+
"default": "vertical",
|
|
2690
|
+
"description": "Which scrollbars to offer. Defaults to vertical."
|
|
2691
|
+
},
|
|
2692
|
+
{
|
|
2693
|
+
"name": "ref",
|
|
2694
|
+
"type": "Ref<HTMLDivElement>",
|
|
2695
|
+
"required": false,
|
|
2696
|
+
"description": "Receives the rendered element."
|
|
2697
|
+
}
|
|
2698
|
+
],
|
|
2699
|
+
"usage": {
|
|
2700
|
+
"whenToUse": "- A bounded region (a list, a panel body) that scrolls inside a fixed height or width",
|
|
2701
|
+
"whenNotToUse": "- The page itself: let the page scroll",
|
|
2702
|
+
"example": "<div style={{ height: 240 }}>\n <ScrollArea>{rows}</ScrollArea>\n</div>"
|
|
2703
|
+
}
|
|
2704
|
+
},
|
|
1987
2705
|
{
|
|
1988
2706
|
"name": "SearchField",
|
|
1989
2707
|
"import": "import { SearchField } from '@ratio-ui/core'",
|
|
@@ -2145,6 +2863,155 @@
|
|
|
2145
2863
|
}
|
|
2146
2864
|
]
|
|
2147
2865
|
},
|
|
2866
|
+
{
|
|
2867
|
+
"name": "Separator",
|
|
2868
|
+
"import": "import { Separator } from '@ratio-ui/core'",
|
|
2869
|
+
"description": "A 1px hairline in the divider grey, horizontal or vertical. A horizontal line fills its row and shrinks to share it, so two lines and a word between them in an Inline make the \"or\" divider; a vertical line keeps its 1px.",
|
|
2870
|
+
"props": [
|
|
2871
|
+
{
|
|
2872
|
+
"name": "orientation",
|
|
2873
|
+
"type": "\"horizontal\" | \"vertical\"",
|
|
2874
|
+
"required": false,
|
|
2875
|
+
"default": "horizontal",
|
|
2876
|
+
"description": "The direction of the line. Defaults to horizontal."
|
|
2877
|
+
},
|
|
2878
|
+
{
|
|
2879
|
+
"name": "decorative",
|
|
2880
|
+
"type": "boolean",
|
|
2881
|
+
"required": false,
|
|
2882
|
+
"default": "true",
|
|
2883
|
+
"description": "True, the default, hides the line from assistive technology; false makes it a semantic separator."
|
|
2884
|
+
},
|
|
2885
|
+
{
|
|
2886
|
+
"name": "ref",
|
|
2887
|
+
"type": "Ref<HTMLDivElement>",
|
|
2888
|
+
"required": false,
|
|
2889
|
+
"description": "Receives the rendered element."
|
|
2890
|
+
}
|
|
2891
|
+
],
|
|
2892
|
+
"usage": {
|
|
2893
|
+
"whenToUse": "- A hairline between groups of content, or the \"or\" divider on the login screen\n- A vertical hairline between inline items",
|
|
2894
|
+
"whenNotToUse": "- A card or table edge: those own their border",
|
|
2895
|
+
"example": "```tsx\n<Separator />\n<Inline gap={8}>\n <Separator />\n <Text variant=\"c1\" tone=\"muted\">or</Text>\n <Separator />\n</Inline>\n<Separator orientation=\"vertical\" />\n<Separator decorative={false} />\n```\n\nIn the \"or\" divider the two lines share the row and the word keeps its width. Keep the word short: a longer phrase wraps before the lines give way."
|
|
2896
|
+
}
|
|
2897
|
+
},
|
|
2898
|
+
{
|
|
2899
|
+
"name": "Sheet",
|
|
2900
|
+
"import": "import { Sheet } from '@ratio-ui/core'",
|
|
2901
|
+
"description": "The root of a sheet. It holds the open state and renders nothing itself. Pass `open` and `onOpenChange` to control it, or `defaultOpen` to leave it uncontrolled. The page behind is inert while it is open, with no scrim over it.",
|
|
2902
|
+
"props": [],
|
|
2903
|
+
"usage": {
|
|
2904
|
+
"whenToUse": "- A bottom sheet for a large surface that sits over the page, such as Settings: it spans the screen and has 24px top corners\n- A side sheet for a panel that keeps the page in view, such as filters or the phone navigation\n- Work that needs more room than a 480px dialog",
|
|
2905
|
+
"whenNotToUse": "- A short task or a confirm step: use a Dialog\n- A panel people swipe away on a phone: use a Drawer\n- Help text on a control: use a Tooltip or Popover",
|
|
2906
|
+
"example": "<Sheet>\n <SheetTrigger>Settings</SheetTrigger>\n <SheetContent side=\"bottom\" closeLabel=\"Close settings\">\n <SheetHeader>\n <SheetTitle>General</SheetTitle>\n <SheetDescription>Store name, contact and address</SheetDescription>\n </SheetHeader>\n <SheetBody>Store details</SheetBody>\n <SheetFooter>\n <SheetClose>Done</SheetClose>\n </SheetFooter>\n </SheetContent>\n</Sheet>"
|
|
2907
|
+
},
|
|
2908
|
+
"parts": [
|
|
2909
|
+
{
|
|
2910
|
+
"name": "SheetBody",
|
|
2911
|
+
"import": "import { SheetBody } from '@ratio-ui/core'",
|
|
2912
|
+
"description": "The content between header and footer. It takes the free height and scrolls when the content is taller.",
|
|
2913
|
+
"props": []
|
|
2914
|
+
},
|
|
2915
|
+
{
|
|
2916
|
+
"name": "SheetClose",
|
|
2917
|
+
"import": "import { SheetClose } from '@ratio-ui/core'",
|
|
2918
|
+
"description": "A button that closes the sheet, such as Done in the footer.",
|
|
2919
|
+
"props": [
|
|
2920
|
+
{
|
|
2921
|
+
"name": "render",
|
|
2922
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DialogCloseState>",
|
|
2923
|
+
"required": false,
|
|
2924
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
2925
|
+
}
|
|
2926
|
+
]
|
|
2927
|
+
},
|
|
2928
|
+
{
|
|
2929
|
+
"name": "SheetContent",
|
|
2930
|
+
"import": "import { SheetContent } from '@ratio-ui/core'",
|
|
2931
|
+
"description": "The panel, white with a hairline on its inner edge. A side sheet is full height and three quarters of a phone screen, 384px from the small breakpoint up; a bottom sheet spans the screen, sizes to its content and has 24px top corners. It appears without sliding and with no scrim, blur or shadow. Put SheetHeader, SheetBody and SheetFooter inside.",
|
|
2932
|
+
"props": [
|
|
2933
|
+
{
|
|
2934
|
+
"name": "side",
|
|
2935
|
+
"type": "\"bottom\" | \"left\" | \"right\"",
|
|
2936
|
+
"required": false,
|
|
2937
|
+
"default": "right",
|
|
2938
|
+
"description": "The edge the sheet sits on: a full-height side sheet, or a bottom sheet with 24px top corners. Defaults to right."
|
|
2939
|
+
},
|
|
2940
|
+
{
|
|
2941
|
+
"name": "showCloseButton",
|
|
2942
|
+
"type": "boolean",
|
|
2943
|
+
"required": false,
|
|
2944
|
+
"default": "true",
|
|
2945
|
+
"description": "Whether the corner close button shows. Defaults to true."
|
|
2946
|
+
},
|
|
2947
|
+
{
|
|
2948
|
+
"name": "closeLabel",
|
|
2949
|
+
"type": "string",
|
|
2950
|
+
"required": false,
|
|
2951
|
+
"default": "Close",
|
|
2952
|
+
"description": "The accessible name of the corner close button. Defaults to Close."
|
|
2953
|
+
},
|
|
2954
|
+
{
|
|
2955
|
+
"name": "render",
|
|
2956
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DialogPopupState>",
|
|
2957
|
+
"required": false,
|
|
2958
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
2959
|
+
}
|
|
2960
|
+
]
|
|
2961
|
+
},
|
|
2962
|
+
{
|
|
2963
|
+
"name": "SheetDescription",
|
|
2964
|
+
"import": "import { SheetDescription } from '@ratio-ui/core'",
|
|
2965
|
+
"description": "One line that says what the sheet is for, in subdued body text.",
|
|
2966
|
+
"props": [
|
|
2967
|
+
{
|
|
2968
|
+
"name": "render",
|
|
2969
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DialogDescriptionState>",
|
|
2970
|
+
"required": false,
|
|
2971
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
2972
|
+
}
|
|
2973
|
+
]
|
|
2974
|
+
},
|
|
2975
|
+
{
|
|
2976
|
+
"name": "SheetFooter",
|
|
2977
|
+
"import": "import { SheetFooter } from '@ratio-ui/core'",
|
|
2978
|
+
"description": "The row of actions at the bottom of the sheet, aligned to the end.",
|
|
2979
|
+
"props": []
|
|
2980
|
+
},
|
|
2981
|
+
{
|
|
2982
|
+
"name": "SheetHeader",
|
|
2983
|
+
"import": "import { SheetHeader } from '@ratio-ui/core'",
|
|
2984
|
+
"description": "The title and description, stacked, with room on the right for the close button.",
|
|
2985
|
+
"props": []
|
|
2986
|
+
},
|
|
2987
|
+
{
|
|
2988
|
+
"name": "SheetTitle",
|
|
2989
|
+
"import": "import { SheetTitle } from '@ratio-ui/core'",
|
|
2990
|
+
"description": "The sheet's name, in the b4 style. It names the sheet for assistive technology.",
|
|
2991
|
+
"props": [
|
|
2992
|
+
{
|
|
2993
|
+
"name": "render",
|
|
2994
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DialogTitleState>",
|
|
2995
|
+
"required": false,
|
|
2996
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
2997
|
+
}
|
|
2998
|
+
]
|
|
2999
|
+
},
|
|
3000
|
+
{
|
|
3001
|
+
"name": "SheetTrigger",
|
|
3002
|
+
"import": "import { SheetTrigger } from '@ratio-ui/core'",
|
|
3003
|
+
"description": "The button that opens the sheet.",
|
|
3004
|
+
"props": [
|
|
3005
|
+
{
|
|
3006
|
+
"name": "render",
|
|
3007
|
+
"type": "ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, DialogTriggerState>",
|
|
3008
|
+
"required": false,
|
|
3009
|
+
"description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
|
|
3010
|
+
}
|
|
3011
|
+
]
|
|
3012
|
+
}
|
|
3013
|
+
]
|
|
3014
|
+
},
|
|
2148
3015
|
{
|
|
2149
3016
|
"name": "SideNav",
|
|
2150
3017
|
"import": "import { SideNav } from '@ratio-ui/core'",
|
|
@@ -2387,7 +3254,7 @@
|
|
|
2387
3254
|
{
|
|
2388
3255
|
"name": "TableHead",
|
|
2389
3256
|
"import": "import { TableHead } from '@ratio-ui/core'",
|
|
2390
|
-
"description": "A column heading: 12px uppercase text in the
|
|
3257
|
+
"description": "A column heading: 12px uppercase text in the muted foreground, the design system's colour for column headings. It is a column header unless `scope` says otherwise.",
|
|
2391
3258
|
"props": [
|
|
2392
3259
|
{
|
|
2393
3260
|
"name": "numeric",
|
|
@@ -2646,7 +3513,7 @@
|
|
|
2646
3513
|
"props": [
|
|
2647
3514
|
{
|
|
2648
3515
|
"name": "variant",
|
|
2649
|
-
"type": "\"b1\" | \"b2\" | \"b3\" | \"b4\" | \"c1\" | \"c2\" | \"c3\" | \"display\" | \"h1\" | \"h5\" | \"label\" | \"s1\" | \"s2\"",
|
|
3516
|
+
"type": "\"b1\" | \"b2\" | \"b3\" | \"b4\" | \"badge\" | \"c1\" | \"c2\" | \"c3\" | \"display\" | \"h1\" | \"h5\" | \"label\" | \"s1\" | \"s2\" | \"section\"",
|
|
2650
3517
|
"required": false,
|
|
2651
3518
|
"default": "b3",
|
|
2652
3519
|
"description": "The text style: size, line height, weight and letter spacing. Defaults to b3, the body text."
|
|
@@ -2680,8 +3547,8 @@
|
|
|
2680
3547
|
}
|
|
2681
3548
|
],
|
|
2682
3549
|
"usage": {
|
|
2683
|
-
"whenToUse": "- Any text on a screen: every label, heading, value and hint is set with Text, because components take no `className` and no `style`\n- A style from the design system's type scale: `variant` is one of display, h1, h5, s1, s2, b1, b2, b3, b4, c1, c2, c3 or
|
|
2684
|
-
"whenNotToUse": "- Text in a button: buttons take the design system's two button styles, which are not Text variants\n- A colour that is not a tone: `color` is a type error, and so are `className` and `style`\n- A style that is not in the type scale: `variant=\"h2\"` is a type error, so pick the nearest of the
|
|
3550
|
+
"whenToUse": "- Any text on a screen: every label, heading, value and hint is set with Text, because components take no `className` and no `style`\n- A style from the design system's type scale: `variant` is one of display, h1, h5, s1, s2, b1, b2, b3, b4, c1, c2, c3, label, section or badge, and b3 is the default\n- A colour from the design system's text colours: `tone` is default, subdued, muted, primary or inherit\n- A heading, paragraph or list term that must look like another style: `as` picks the element (span, p, div, strong, em, h1 to h6, legend, dt or dd) and `variant` picks the look, so the two are chosen apart\n- A single line that is cut with an ellipsis: `truncate`, on a block element such as `as=\"p\"` or `as=\"div\"`",
|
|
3551
|
+
"whenNotToUse": "- Text in a button: buttons take the design system's two button styles, which are not Text variants\n- A colour that is not a tone: `color` is a type error, and so are `className` and `style`\n- A style that is not in the type scale: `variant=\"h2\"` is a type error, so pick the nearest of the 15\n- Space around text: use Stack or Inline\n- Several lines cut at a number of lines: `truncate` keeps one line",
|
|
2685
3552
|
"example": "<Text as=\"h1\" variant=\"h1\">Settlements</Text>\n<Text tone=\"subdued\">Paid out every weekday</Text>"
|
|
2686
3553
|
}
|
|
2687
3554
|
},
|
|
@@ -2743,7 +3610,7 @@
|
|
|
2743
3610
|
{
|
|
2744
3611
|
"name": "TooltipContent",
|
|
2745
3612
|
"import": "import { TooltipContent } from '@ratio-ui/core'",
|
|
2746
|
-
"description": "The tooltip text: a
|
|
3613
|
+
"description": "The tooltip text: a white panel with a 1px line-100 border and ink-800 text, like a popover, no shadow and no animation. It sits above the trigger by default.",
|
|
2747
3614
|
"props": [
|
|
2748
3615
|
{
|
|
2749
3616
|
"name": "render",
|
|
@@ -2783,14 +3650,7 @@
|
|
|
2783
3650
|
"name": "logo",
|
|
2784
3651
|
"type": "ReactNode",
|
|
2785
3652
|
"required": false,
|
|
2786
|
-
"description": "The logo, usually
|
|
2787
|
-
},
|
|
2788
|
-
{
|
|
2789
|
-
"name": "wordmarkLabel",
|
|
2790
|
-
"type": "string",
|
|
2791
|
-
"required": false,
|
|
2792
|
-
"default": "Ratio",
|
|
2793
|
-
"description": "The accessible name of the text wordmark, shown when there is no logo. Defaults to Ratio."
|
|
3653
|
+
"description": "The logo, usually the SVG the app gets from its designer. The bar draws no logo of its own: without one the slot is empty."
|
|
2794
3654
|
},
|
|
2795
3655
|
{
|
|
2796
3656
|
"name": "menuLabel",
|