ionbase-ui 0.70.0 → 0.75.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.
Files changed (52) hide show
  1. package/dist/components/Chart.d.ts +95 -0
  2. package/dist/components/Chart.d.ts.map +1 -0
  3. package/dist/components/Chart.js +60 -0
  4. package/dist/components/Chart.js.map +1 -0
  5. package/dist/components/SettingRow.d.ts +54 -0
  6. package/dist/components/SettingRow.d.ts.map +1 -0
  7. package/dist/components/SettingRow.js +60 -0
  8. package/dist/components/SettingRow.js.map +1 -0
  9. package/dist/components/StatTile.d.ts +65 -0
  10. package/dist/components/StatTile.d.ts.map +1 -0
  11. package/dist/components/StatTile.js +54 -0
  12. package/dist/components/StatTile.js.map +1 -0
  13. package/dist/components/agent-run.d.ts +147 -0
  14. package/dist/components/agent-run.d.ts.map +1 -0
  15. package/dist/components/agent-run.js +250 -0
  16. package/dist/components/agent-run.js.map +1 -0
  17. package/dist/components/index.d.ts +10 -0
  18. package/dist/components/index.d.ts.map +1 -1
  19. package/dist/components/index.js +16 -0
  20. package/dist/components/index.js.map +1 -1
  21. package/dist/components/use-agent-run.d.ts +65 -0
  22. package/dist/components/use-agent-run.d.ts.map +1 -0
  23. package/dist/components/use-agent-run.js +127 -0
  24. package/dist/components/use-agent-run.js.map +1 -0
  25. package/dist/figma-descriptions.json +88 -63
  26. package/dist/figma-map.json +236 -2
  27. package/dist/meta/ChartLegend.json +125 -0
  28. package/dist/meta/ChartTooltip.json +126 -0
  29. package/dist/meta/SettingRow.json +102 -0
  30. package/dist/meta/StatGroup.json +65 -0
  31. package/dist/meta/StatTile.json +163 -0
  32. package/dist/meta/components.json +595 -1
  33. package/dist/meta/contrast.json +613 -1
  34. package/dist/meta/index.json +64 -1
  35. package/dist/meta/patterns/AgentRun.json +14 -0
  36. package/dist/meta/patterns/HumanApproval.json +4 -0
  37. package/dist/meta/patterns/SettingsPanel.json +2 -1
  38. package/dist/meta/patterns/index.json +4 -1
  39. package/dist/styles/chart.css +275 -0
  40. package/dist/styles/index.css +3 -0
  41. package/dist/styles/setting-row.css +58 -0
  42. package/dist/styles/stat-tile.css +66 -0
  43. package/dist/styles/tokens/base.css +36 -8
  44. package/dist/styles/tokens/theme-dark.css +12 -0
  45. package/dist/tokens/index.d.ts +193 -40
  46. package/dist/tokens/index.d.ts.map +1 -1
  47. package/dist/tokens/index.js +157 -32
  48. package/dist/tokens/index.js.map +1 -1
  49. package/eslint-plugin/meta-data.js +9 -0
  50. package/eslint-plugin/rules/needs-accessible-name.js +14 -1
  51. package/llms.txt +19 -2
  52. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "package": "ionbase-ui",
3
- "version": "0.70.0",
3
+ "version": "0.75.0",
4
4
  "figmaFile": "gaLbGd0QNb1fUl6BjSpfBA",
5
- "figmaExported": "2026-09-24",
5
+ "figmaExported": "2026-09-25",
6
6
  "usage": "Given a Figma node id or component name, look it up here for the React component, its import, and how each Figma property maps onto a real prop. Every mapping is verified against both the Figma export and the TypeScript API on each build.",
7
7
  "generated": "by scripts/verify-figma-map.mjs — do not edit",
8
8
  "byNodeId": {
@@ -1477,6 +1477,33 @@
1477
1477
  }
1478
1478
  }
1479
1479
  },
1480
+ "1418:260": {
1481
+ "figmaComponent": "Setting Row",
1482
+ "figmaNodeId": "1418:260",
1483
+ "figmaPage": "Setting Row",
1484
+ "component": "SettingRow",
1485
+ "import": "import { SettingRow } from 'ionbase-ui';",
1486
+ "docs": "components/setting-row/index.html.md",
1487
+ "props": {
1488
+ "Label#1418:0": {
1489
+ "prop": "label"
1490
+ },
1491
+ "Description#1418:3": {
1492
+ "prop": "description"
1493
+ },
1494
+ "Show Description#1418:6": {
1495
+ "prop": "description",
1496
+ "note": "false means description is omitted"
1497
+ },
1498
+ "Control#1418:9": {
1499
+ "prop": "children",
1500
+ "note": "the control is the row’s child; in code it is named and described by the row automatically, so turn its own label off in Figma too"
1501
+ },
1502
+ "Layout": {
1503
+ "ignore": "not a prop: the row stacks below 30rem of its own width through a container query, the same call Header makes for its Device axis"
1504
+ }
1505
+ }
1506
+ },
1480
1507
  "1396:502": {
1481
1508
  "figmaComponent": "Sidebar",
1482
1509
  "figmaNodeId": "1396:502",
@@ -1620,6 +1647,53 @@
1620
1647
  }
1621
1648
  }
1622
1649
  },
1650
+ "1412:344": {
1651
+ "figmaComponent": "Stat Group",
1652
+ "figmaNodeId": "1412:344",
1653
+ "figmaPage": "Stat Tile",
1654
+ "component": "StatGroup",
1655
+ "import": "import { StatGroup } from 'ionbase-ui';",
1656
+ "docs": "components/stat-group/index.html.md",
1657
+ "props": {}
1658
+ },
1659
+ "1412:343": {
1660
+ "figmaComponent": "Stat Tile",
1661
+ "figmaNodeId": "1412:343",
1662
+ "figmaPage": "Stat Tile",
1663
+ "component": "StatTile",
1664
+ "import": "import { StatTile } from 'ionbase-ui';",
1665
+ "docs": "components/stat-tile/index.html.md",
1666
+ "props": {
1667
+ "Label#1412:0": {
1668
+ "prop": "label"
1669
+ },
1670
+ "Value#1412:10": {
1671
+ "prop": "value"
1672
+ },
1673
+ "Comparison#1412:20": {
1674
+ "prop": "comparison"
1675
+ },
1676
+ "State": {
1677
+ "prop": "isLoading",
1678
+ "values": {
1679
+ "Default": false,
1680
+ "Loading": true
1681
+ }
1682
+ },
1683
+ "Change": {
1684
+ "prop": "goodWhen",
1685
+ "when": {
1686
+ "Better Up": "up",
1687
+ "Better Down": "down",
1688
+ "Worse Up": "down",
1689
+ "Worse Down": "up",
1690
+ "Neutral Up": "neutral",
1691
+ "Neutral Down": "neutral"
1692
+ },
1693
+ "note": "Figma draws what the badge SAYS; code derives it from two props. The direction is the sign of `change` (Up is positive), and Better or Worse follows from that and goodWhen — so Worse Up is a rise where down was good. No Change is a `change` that rounds to zero; None is `change` omitted. The badge text itself is computed from `change` and `changeUnit`."
1694
+ }
1695
+ }
1696
+ },
1623
1697
  "1391:431": {
1624
1698
  "figmaComponent": "Stepper",
1625
1699
  "figmaNodeId": "1391:431",
@@ -2015,6 +2089,48 @@
2015
2089
  "prop": "title"
2016
2090
  }
2017
2091
  }
2092
+ },
2093
+ "1432:282": {
2094
+ "figmaComponent": "Chart Tooltip",
2095
+ "figmaNodeId": "1432:282",
2096
+ "figmaPage": "Chart",
2097
+ "component": "ChartTooltip",
2098
+ "import": "import { ChartTooltip } from 'ionbase-ui';",
2099
+ "docs": "components/chart-tooltip/index.html.md",
2100
+ "props": {
2101
+ "Title#1432:18": {
2102
+ "prop": "title"
2103
+ },
2104
+ "Show Row 2#1432:19": {
2105
+ "prop": "rows",
2106
+ "note": "true draws a second entry in rows; the row count is the length of the array"
2107
+ },
2108
+ "Show Row 3#1432:20": {
2109
+ "prop": "rows",
2110
+ "note": "true draws a third entry in rows"
2111
+ }
2112
+ }
2113
+ },
2114
+ "1432:369": {
2115
+ "figmaComponent": "Chart Legend",
2116
+ "figmaNodeId": "1432:369",
2117
+ "figmaPage": "Chart",
2118
+ "component": "ChartLegend",
2119
+ "import": "import { ChartLegend } from 'ionbase-ui';",
2120
+ "docs": "components/chart-legend/index.html.md",
2121
+ "props": {
2122
+ "Shape": {
2123
+ "prop": "shape",
2124
+ "values": {
2125
+ "Square": "square",
2126
+ "Line": "line"
2127
+ }
2128
+ },
2129
+ "Show Item 3#1432:38": {
2130
+ "prop": "items",
2131
+ "note": "true draws a third entry in items; the entry count is the length of the array"
2132
+ }
2133
+ }
2018
2134
  }
2019
2135
  },
2020
2136
  "byFigmaName": {
@@ -3489,6 +3605,33 @@
3489
3605
  }
3490
3606
  }
3491
3607
  },
3608
+ "Setting Row": {
3609
+ "figmaComponent": "Setting Row",
3610
+ "figmaNodeId": "1418:260",
3611
+ "figmaPage": "Setting Row",
3612
+ "component": "SettingRow",
3613
+ "import": "import { SettingRow } from 'ionbase-ui';",
3614
+ "docs": "components/setting-row/index.html.md",
3615
+ "props": {
3616
+ "Label#1418:0": {
3617
+ "prop": "label"
3618
+ },
3619
+ "Description#1418:3": {
3620
+ "prop": "description"
3621
+ },
3622
+ "Show Description#1418:6": {
3623
+ "prop": "description",
3624
+ "note": "false means description is omitted"
3625
+ },
3626
+ "Control#1418:9": {
3627
+ "prop": "children",
3628
+ "note": "the control is the row’s child; in code it is named and described by the row automatically, so turn its own label off in Figma too"
3629
+ },
3630
+ "Layout": {
3631
+ "ignore": "not a prop: the row stacks below 30rem of its own width through a container query, the same call Header makes for its Device axis"
3632
+ }
3633
+ }
3634
+ },
3492
3635
  "Sidebar": {
3493
3636
  "figmaComponent": "Sidebar",
3494
3637
  "figmaNodeId": "1396:502",
@@ -3632,6 +3775,53 @@
3632
3775
  }
3633
3776
  }
3634
3777
  },
3778
+ "Stat Group": {
3779
+ "figmaComponent": "Stat Group",
3780
+ "figmaNodeId": "1412:344",
3781
+ "figmaPage": "Stat Tile",
3782
+ "component": "StatGroup",
3783
+ "import": "import { StatGroup } from 'ionbase-ui';",
3784
+ "docs": "components/stat-group/index.html.md",
3785
+ "props": {}
3786
+ },
3787
+ "Stat Tile": {
3788
+ "figmaComponent": "Stat Tile",
3789
+ "figmaNodeId": "1412:343",
3790
+ "figmaPage": "Stat Tile",
3791
+ "component": "StatTile",
3792
+ "import": "import { StatTile } from 'ionbase-ui';",
3793
+ "docs": "components/stat-tile/index.html.md",
3794
+ "props": {
3795
+ "Label#1412:0": {
3796
+ "prop": "label"
3797
+ },
3798
+ "Value#1412:10": {
3799
+ "prop": "value"
3800
+ },
3801
+ "Comparison#1412:20": {
3802
+ "prop": "comparison"
3803
+ },
3804
+ "State": {
3805
+ "prop": "isLoading",
3806
+ "values": {
3807
+ "Default": false,
3808
+ "Loading": true
3809
+ }
3810
+ },
3811
+ "Change": {
3812
+ "prop": "goodWhen",
3813
+ "when": {
3814
+ "Better Up": "up",
3815
+ "Better Down": "down",
3816
+ "Worse Up": "down",
3817
+ "Worse Down": "up",
3818
+ "Neutral Up": "neutral",
3819
+ "Neutral Down": "neutral"
3820
+ },
3821
+ "note": "Figma draws what the badge SAYS; code derives it from two props. The direction is the sign of `change` (Up is positive), and Better or Worse follows from that and goodWhen — so Worse Up is a rise where down was good. No Change is a `change` that rounds to zero; None is `change` omitted. The badge text itself is computed from `change` and `changeUnit`."
3822
+ }
3823
+ }
3824
+ },
3635
3825
  "Stepper": {
3636
3826
  "figmaComponent": "Stepper",
3637
3827
  "figmaNodeId": "1391:431",
@@ -4027,12 +4217,56 @@
4027
4217
  "prop": "title"
4028
4218
  }
4029
4219
  }
4220
+ },
4221
+ "Chart Tooltip": {
4222
+ "figmaComponent": "Chart Tooltip",
4223
+ "figmaNodeId": "1432:282",
4224
+ "figmaPage": "Chart",
4225
+ "component": "ChartTooltip",
4226
+ "import": "import { ChartTooltip } from 'ionbase-ui';",
4227
+ "docs": "components/chart-tooltip/index.html.md",
4228
+ "props": {
4229
+ "Title#1432:18": {
4230
+ "prop": "title"
4231
+ },
4232
+ "Show Row 2#1432:19": {
4233
+ "prop": "rows",
4234
+ "note": "true draws a second entry in rows; the row count is the length of the array"
4235
+ },
4236
+ "Show Row 3#1432:20": {
4237
+ "prop": "rows",
4238
+ "note": "true draws a third entry in rows"
4239
+ }
4240
+ }
4241
+ },
4242
+ "Chart Legend": {
4243
+ "figmaComponent": "Chart Legend",
4244
+ "figmaNodeId": "1432:369",
4245
+ "figmaPage": "Chart",
4246
+ "component": "ChartLegend",
4247
+ "import": "import { ChartLegend } from 'ionbase-ui';",
4248
+ "docs": "components/chart-legend/index.html.md",
4249
+ "props": {
4250
+ "Shape": {
4251
+ "prop": "shape",
4252
+ "values": {
4253
+ "Square": "square",
4254
+ "Line": "line"
4255
+ }
4256
+ },
4257
+ "Show Item 3#1432:38": {
4258
+ "prop": "items",
4259
+ "note": "true draws a third entry in items; the entry count is the length of the array"
4260
+ }
4261
+ }
4030
4262
  }
4031
4263
  },
4032
4264
  "unmapped": {
4033
4265
  ".Status Indicator": "The dot Avatar draws in its corners. Avatar owns both instances — Top is Intent=Primary with the check glyph, Bottom is Intent=Success with Show Icon off — and exposes them as `topIndicator` / `bottomIndicator`.\n\nThe leading dot in the name is Figma's own marker for a private component: it is excluded from the published library, so a designer cannot place one on a canvas even if they wanted to. That settles a question this entry used to argue: it is internal by the file's own declaration, not merely by our reading of it. The same call Line, Progress and Progress Heading get for being internal to ScrollProgress — with better evidence.\n\nMap it only if the dot is ever removed.",
4034
4266
  "Calendar": "The open calendar both pickers render internally — Calendar and CalendarPopover are not exported, because a grid with no field to own its value is not a control a caller should mount. Mode=Single is DatePicker’s, Mode=Range is DateRangePicker’s; Months=Two is `visibleMonths={2}`, Show Presets is `presets` and Show Clear is `isClearable`, all on DateRangePicker. Drawn separately because a frame cannot both hug a field and overlay a grid on it — the same reason Combobox Menu is its own frame.",
4035
4267
  "Calendar Day": "A day cell inside Calendar — internal to it the way Pagination Item is internal to Pagination. A caller never places one; `isDateUnavailable`, `minValue` and `maxValue` on the pickers decide which state each day draws in.",
4268
+ "Chart Legend Item": "One entry of Chart Legend — `items[n]` in code, `{ label, series }`. Its Shape follows the legend’s `shape`; Series picks chart/1…8. Internal to the legend.",
4269
+ "Chart Tooltip Row": "One entry of Chart Tooltip — `rows[n]` in code, `{ label, value, series }`. Series picks the swatch from chart/1…8, exactly as `series` does. Internal to the tooltip the way Pagination Item is internal to Pagination.",
4036
4270
  "Combobox Menu": "The list Combobox opens. It is not a separate export: the React component renders its own menu, because the two are one control and splitting them would let a caller mount a listbox with no combobox to own it. Drawn separately in Figma because a frame cannot both hug a field and overlay a list on top of it.",
4037
4271
  "Form Field": "Label, helper text and error wiring are built into Input and Select rather than a separate wrapper — the wrapper is how Figma composes them, not how React does.",
4038
4272
  "Line": "An internal part of the Scroll Progress rail, not a component a caller composes.",
@@ -0,0 +1,125 @@
1
+ {
2
+ "name": "ChartLegend",
3
+ "source": "src/components/Chart.tsx",
4
+ "propsType": "ChartLegendProps",
5
+ "description": "ChartLegend — which colour is which series.\n\nColour alone never identifies a series (SC 1.4.1), so any chart with more\nthan one series needs this, or direct labels on the lines. The swatch reads\nthe same `--chart-<n>` as the series itself, through `chartSeriesClass`, so\nthe two cannot drift apart.",
6
+ "import": "import { ChartLegend } from 'ionbase-ui';",
7
+ "status": "stable",
8
+ "since": "0.74.0",
9
+ "summary": "Which colour is which series, for a chart drawn with visx. The swatch reads the same token as the series.",
10
+ "useWhen": [
11
+ "a chart has more than one series",
12
+ "a single-series chart sits beside others and its colour needs naming"
13
+ ],
14
+ "useInstead": [
15
+ {
16
+ "when": "the lines are few and there is room to label each at its end",
17
+ "use": "direct labels in the SVG, with the series class on the text"
18
+ },
19
+ {
20
+ "when": "the scale is a magnitude ramp (a heatmap), not categories",
21
+ "use": "a Less-to-More row of .ion-chart__heat--0…5 cells"
22
+ }
23
+ ],
24
+ "composition": {
25
+ "note": "Items are listed in the order the series are drawn, with the same series numbers the chart uses. Place it above or below the plot inside the same .ion-chart figure.",
26
+ "example": "<ChartLegend shape=\"line\" items={[{ label: 'Production', series: 1 }, { label: 'Staging', series: 2 }]} />"
27
+ },
28
+ "variants": {
29
+ "shape": {
30
+ "square": {
31
+ "use": "the default — bars, areas and heatmap-like marks"
32
+ },
33
+ "line": {
34
+ "use": "line charts, so the key looks like the mark it names"
35
+ }
36
+ }
37
+ },
38
+ "a11y": {
39
+ "guarantees": [
40
+ "a list, so a screen reader announces how many series there are",
41
+ "swatches are aria-hidden; every series is named in text"
42
+ ],
43
+ "requires": [
44
+ "series numbers matching the chart — the legend cannot see the chart"
45
+ ]
46
+ },
47
+ "antiPatterns": [
48
+ {
49
+ "dont": "a multi-series chart with no legend and no direct labels",
50
+ "why": "colour becomes the only way to tell series apart, which fails SC 1.4.1 and fails anyone who cannot tell blue from purple"
51
+ },
52
+ {
53
+ "dont": "listing series in a different order from the chart",
54
+ "why": "the reader matches legend to chart by position as much as by colour"
55
+ }
56
+ ],
57
+ "stylesheet": "src/styles/chart.css",
58
+ "tokens": [
59
+ "--border-default",
60
+ "--border-strong",
61
+ "--border-stronger",
62
+ "--border-subtle",
63
+ "--border-width-default",
64
+ "--chart-1",
65
+ "--chart-2",
66
+ "--chart-3",
67
+ "--chart-4",
68
+ "--chart-5",
69
+ "--chart-6",
70
+ "--chart-7",
71
+ "--chart-8",
72
+ "--chart-sequential-1",
73
+ "--chart-sequential-2",
74
+ "--chart-sequential-3",
75
+ "--chart-sequential-4",
76
+ "--chart-sequential-5",
77
+ "--font-family-sans",
78
+ "--font-weight-medium",
79
+ "--font-weight-semibold",
80
+ "--ion-chart-series",
81
+ "--ion-shadow-shadow-lg",
82
+ "--radius-2xs",
83
+ "--radius-full",
84
+ "--radius-md",
85
+ "--spacing-12",
86
+ "--spacing-16",
87
+ "--spacing-4",
88
+ "--spacing-6",
89
+ "--spacing-8",
90
+ "--surface-default",
91
+ "--surface-raised",
92
+ "--surface-sunken",
93
+ "--text-default",
94
+ "--text-secondary",
95
+ "--text-tertiary",
96
+ "--type-body-sm",
97
+ "--type-body-sm-line-height",
98
+ "--type-caption",
99
+ "--type-caption-line-height"
100
+ ],
101
+ "props": {
102
+ "items": {
103
+ "type": "ChartLegendItem[]",
104
+ "required": true,
105
+ "origin": "own",
106
+ "description": "One per series, in the order the series are drawn."
107
+ },
108
+ "shape": {
109
+ "type": "ChartLegendShape | undefined",
110
+ "required": false,
111
+ "origin": "own",
112
+ "description": "`square` for bars and areas, `line` for line charts.",
113
+ "values": [
114
+ "square",
115
+ "line"
116
+ ]
117
+ }
118
+ },
119
+ "propCounts": {
120
+ "own": 2,
121
+ "aria": 0,
122
+ "dom": 277,
123
+ "other": 0
124
+ }
125
+ }
@@ -0,0 +1,126 @@
1
+ {
2
+ "name": "ChartTooltip",
3
+ "source": "src/components/Chart.tsx",
4
+ "propsType": "ChartTooltipProps",
5
+ "description": "ChartTooltip — the panel that shows the values under the pointer.\n\nPut it inside visx's Tooltip with `chartTooltipProps`, so visx places it and\nthis draws it: raised, rimmed and shadowed like Popover and Toast.\n\nIT IS NOT THE ACCESSIBLE WAY TO THE DATA. It appears on hover, so a keyboard\nor screen-reader user never sees it. Every chart still needs a text summary\nand the values in a table (visually hidden is fine) — the tooltip is a\nconvenience for pointer users, never the only route to a number.",
6
+ "import": "import { ChartTooltip } from 'ionbase-ui';",
7
+ "status": "stable",
8
+ "since": "0.74.0",
9
+ "summary": "The panel showing the values under the pointer on a visx chart. visx positions it; this draws it.",
10
+ "useWhen": [
11
+ "a chart drawn with visx shows exact values on hover",
12
+ "several series share an x value and the reader compares them at a point"
13
+ ],
14
+ "useInstead": [
15
+ {
16
+ "when": "it explains a control rather than a data point",
17
+ "use": "Tooltip"
18
+ },
19
+ {
20
+ "when": "it holds interactive content",
21
+ "use": "Popover"
22
+ },
23
+ {
24
+ "when": "the reader needs every value, or needs them without a pointer",
25
+ "use": "Table"
26
+ }
27
+ ],
28
+ "composition": {
29
+ "note": "Render it inside visx's Tooltip, TooltipWithBounds or TooltipInPortal with {...chartTooltipProps}, which turns off visx's own box so this one is the only panel. Axes take {...chartAxisProps} and gridlines {...chartGridProps}; a series takes className={chartSeriesClass(n)} plus ion-chart__line, __area, __bar or __point.",
30
+ "example": "<TooltipWithBounds top={top} left={left} {...chartTooltipProps}><ChartTooltip title=\"12 Sep\" rows={[{ label: 'Success rate', value: '96.2%', series: 1 }]} /></TooltipWithBounds>"
31
+ },
32
+ "a11y": {
33
+ "guarantees": [
34
+ "rows are a <dl>, so each value is announced with its label",
35
+ "the series swatch is aria-hidden; the label carries the name"
36
+ ],
37
+ "requires": [
38
+ "a text summary and the values in a table (visually hidden is fine) — the tooltip appears on hover, so keyboard and screen-reader users never reach it",
39
+ "`value` already formatted — the tooltip cannot know the unit or precision"
40
+ ]
41
+ },
42
+ "antiPatterns": [
43
+ {
44
+ "dont": "making the tooltip the only way to read a value",
45
+ "why": "it exists only under a mouse pointer; without a table the data is invisible to keyboard and screen-reader users"
46
+ },
47
+ {
48
+ "dont": "leaving visx's default tooltip styles on",
49
+ "why": "it draws a second white box with a hardcoded shadow around this one, and that box does not theme"
50
+ },
51
+ {
52
+ "dont": "a swatch colour that does not match the series",
53
+ "why": "pass the same `series` number the line or bar uses — the swatch reads the same token only if it is told the same index"
54
+ }
55
+ ],
56
+ "stylesheet": "src/styles/chart.css",
57
+ "tokens": [
58
+ "--border-default",
59
+ "--border-strong",
60
+ "--border-stronger",
61
+ "--border-subtle",
62
+ "--border-width-default",
63
+ "--chart-1",
64
+ "--chart-2",
65
+ "--chart-3",
66
+ "--chart-4",
67
+ "--chart-5",
68
+ "--chart-6",
69
+ "--chart-7",
70
+ "--chart-8",
71
+ "--chart-sequential-1",
72
+ "--chart-sequential-2",
73
+ "--chart-sequential-3",
74
+ "--chart-sequential-4",
75
+ "--chart-sequential-5",
76
+ "--font-family-sans",
77
+ "--font-weight-medium",
78
+ "--font-weight-semibold",
79
+ "--ion-chart-series",
80
+ "--ion-shadow-shadow-lg",
81
+ "--radius-2xs",
82
+ "--radius-full",
83
+ "--radius-md",
84
+ "--spacing-12",
85
+ "--spacing-16",
86
+ "--spacing-4",
87
+ "--spacing-6",
88
+ "--spacing-8",
89
+ "--surface-default",
90
+ "--surface-raised",
91
+ "--surface-sunken",
92
+ "--text-default",
93
+ "--text-secondary",
94
+ "--text-tertiary",
95
+ "--type-body-sm",
96
+ "--type-body-sm-line-height",
97
+ "--type-caption",
98
+ "--type-caption-line-height"
99
+ ],
100
+ "props": {
101
+ "title": {
102
+ "type": "React.ReactNode",
103
+ "required": false,
104
+ "origin": "own",
105
+ "description": "What the pointer is over — usually the x value, e.g. a date."
106
+ },
107
+ "rows": {
108
+ "type": "ChartTooltipRow[] | undefined",
109
+ "required": false,
110
+ "origin": "own",
111
+ "description": "One row per series at that point."
112
+ },
113
+ "children": {
114
+ "type": "React.ReactNode",
115
+ "required": false,
116
+ "origin": "own",
117
+ "description": "Free content after the rows, for anything that is not label/value."
118
+ }
119
+ },
120
+ "propCounts": {
121
+ "own": 3,
122
+ "aria": 0,
123
+ "dom": 276,
124
+ "other": 0
125
+ }
126
+ }
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "SettingRow",
3
+ "source": "src/components/SettingRow.tsx",
4
+ "propsType": "SettingRowProps",
5
+ "description": "SettingRow — one setting: its name and what it does on the left, the control\non the right. The row the SettingsPanel pattern is built from.\n\nTHE WIRING IS THE POINT, NOT THE LAYOUT\n\nA label placed beside a Toggle looks labelled and is not: a screen reader\nannounces \"switch, off\" and nothing else, and the description is never read\nat all. The pattern names this as its first a11y requirement, and the demo\napp's stand-in handed the ids to a render function — which still left the\nwiring as a step to remember. Here an element child is cloned with\n`aria-labelledby` and `aria-describedby` already set, so the row cannot be\nused without them. A value the caller passes explicitly wins, so an\nexisting name is never overwritten.\n\nA CONTROL WITH ITS OWN TEXT KEEPS ITS OWN NAME\n\nA Button reading \"Delete workspace…\" must be announced by that text — WCAG\n2.5.3 wants the visible words inside the accessible name, and a row label of\n\"Danger zone\" would replace them. So a child with children of its own is\nleft named by them, and the row's label joins its description instead: the\nsetting is still announced, just as context rather than as the name.\n\nThe label is text rather than a `<label>` because the control may not be a\nform field, and a `<label>` pointing at a button is invalid.\n\nIt stacks below 30rem of its OWN width, not the viewport's, so the same row\nworks in a full page and in a narrow drawer.",
6
+ "import": "import { SettingRow } from 'ionbase-ui';",
7
+ "status": "stable",
8
+ "since": "0.72.0",
9
+ "summary": "One setting: its name and description on the left, the control on the right — and the control named and described by them automatically.",
10
+ "useWhen": [
11
+ "a settings or preferences panel, one row per setting",
12
+ "a control whose meaning needs a sentence of explanation beside it"
13
+ ],
14
+ "useInstead": [
15
+ {
16
+ "when": "it is a form field with its own visible label above it",
17
+ "use": "Input",
18
+ "why": "Input, Select and the pickers carry their own label and description; a SettingRow around them names the field twice"
19
+ },
20
+ {
21
+ "when": "a group of options answers one question",
22
+ "use": "RadioGroup",
23
+ "why": "the group has its own label; put the RadioGroup under a heading rather than in a row"
24
+ }
25
+ ],
26
+ "slots": {
27
+ "children": {
28
+ "accepts": [
29
+ "Toggle",
30
+ "Checkbox",
31
+ "Select",
32
+ "Button"
33
+ ],
34
+ "note": "an element is cloned with aria-labelledby and aria-describedby pointing at the row's text; a function receives the ids instead, for a control that needs them somewhere else"
35
+ }
36
+ },
37
+ "a11y": {
38
+ "namesChild": true,
39
+ "guarantees": [
40
+ "an element child with no text of its own — a Toggle, a Checkbox with no label — is named by the row's label and described by its description, so it is announced as \"Weekly digest, switch, off\" plus what it does, not \"switch, off\"",
41
+ "a child with its own text — a Button — keeps that text as its name (WCAG 2.5.3), and the row's label and description are attached as its description instead",
42
+ "an aria-labelledby or aria-describedby the caller passes explicitly is kept, never overwritten",
43
+ "it stacks by its own width, so it reads the same in a page and in a narrow drawer"
44
+ ],
45
+ "requires": [
46
+ "one control per row — the ids name one element"
47
+ ],
48
+ "notes": [
49
+ "The label is text, not a <label>, because the control may be a Button; a <label> pointing at a button is invalid."
50
+ ]
51
+ },
52
+ "antiPatterns": [
53
+ {
54
+ "dont": "a Toggle or Checkbox with its own visible label inside a SettingRow",
55
+ "why": "the control then names itself, the row's label becomes a description, and the setting's name is shown twice"
56
+ },
57
+ {
58
+ "dont": "a Checkbox row that saves immediately",
59
+ "why": "Toggle is immediate and Checkbox is saved with a submit — the SettingsPanel pattern's first rule"
60
+ }
61
+ ],
62
+ "stylesheet": "src/styles/setting-row.css",
63
+ "tokens": [
64
+ "--font-family-sans",
65
+ "--font-weight-semibold",
66
+ "--spacing-16",
67
+ "--spacing-2",
68
+ "--spacing-8",
69
+ "--text-default",
70
+ "--text-secondary",
71
+ "--type-body",
72
+ "--type-body-line-height",
73
+ "--type-body-sm",
74
+ "--type-body-sm-line-height"
75
+ ],
76
+ "props": {
77
+ "label": {
78
+ "type": "React.ReactNode",
79
+ "required": true,
80
+ "origin": "own",
81
+ "description": "The setting's name. It becomes the control's accessible name."
82
+ },
83
+ "description": {
84
+ "type": "React.ReactNode",
85
+ "required": false,
86
+ "origin": "own",
87
+ "description": "What the setting does, announced with the control."
88
+ },
89
+ "children": {
90
+ "type": "React.ReactElement<{ 'aria-labelledby'?: string; 'aria-describedby'?: string; children?: React.ReactNode; }, string | React.JSXElementConstructor<any>> | ((ids: SettingRowIds) => React.ReactNode)",
91
+ "required": true,
92
+ "origin": "own",
93
+ "description": "The control. Pass it as an element — `<Toggle />`, `<Select />`,\n`<Button />` — and the row names and describes it for you. Pass a\nfunction when the ids have to go somewhere other than the element's own\nprops; it receives them."
94
+ }
95
+ },
96
+ "propCounts": {
97
+ "own": 3,
98
+ "aria": 0,
99
+ "dom": 277,
100
+ "other": 0
101
+ }
102
+ }