ionbase-ui 0.81.1 → 0.86.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 (59) hide show
  1. package/dist/components/Checkbox.d.ts +39 -0
  2. package/dist/components/Checkbox.d.ts.map +1 -1
  3. package/dist/components/Checkbox.js +77 -4
  4. package/dist/components/Checkbox.js.map +1 -1
  5. package/dist/components/Fieldset.d.ts +62 -0
  6. package/dist/components/Fieldset.d.ts.map +1 -0
  7. package/dist/components/Fieldset.js +58 -0
  8. package/dist/components/Fieldset.js.map +1 -0
  9. package/dist/components/Menu.d.ts +87 -24
  10. package/dist/components/Menu.d.ts.map +1 -1
  11. package/dist/components/Menu.js +245 -28
  12. package/dist/components/Menu.js.map +1 -1
  13. package/dist/components/PageHeader.d.ts +59 -0
  14. package/dist/components/PageHeader.d.ts.map +1 -0
  15. package/dist/components/PageHeader.js +29 -0
  16. package/dist/components/PageHeader.js.map +1 -0
  17. package/dist/components/Radio.d.ts +14 -0
  18. package/dist/components/Radio.d.ts.map +1 -1
  19. package/dist/components/Radio.js +15 -4
  20. package/dist/components/Radio.js.map +1 -1
  21. package/dist/components/SearchField.d.ts +36 -0
  22. package/dist/components/SearchField.d.ts.map +1 -0
  23. package/dist/components/SearchField.js +76 -0
  24. package/dist/components/SearchField.js.map +1 -0
  25. package/dist/components/index.d.ts +10 -4
  26. package/dist/components/index.d.ts.map +1 -1
  27. package/dist/components/index.js +5 -2
  28. package/dist/components/index.js.map +1 -1
  29. package/dist/figma-descriptions.json +96 -76
  30. package/dist/figma-map.json +272 -39
  31. package/dist/meta/Checkbox.json +8 -6
  32. package/dist/meta/CheckboxGroup.json +268 -0
  33. package/dist/meta/Divider.json +2 -2
  34. package/dist/meta/Fieldset.json +162 -0
  35. package/dist/meta/Menu.json +201 -27
  36. package/dist/meta/MenuItem.json +137 -17
  37. package/dist/meta/MenuSection.json +90 -0
  38. package/dist/meta/MenuTrigger.json +177 -0
  39. package/dist/meta/PageHeader.json +169 -0
  40. package/dist/meta/Radio.json +0 -1
  41. package/dist/meta/RadioGroup.json +59 -7
  42. package/dist/meta/SearchField.json +487 -0
  43. package/dist/meta/Stepper.json +2 -2
  44. package/dist/meta/Tabs.json +3 -3
  45. package/dist/meta/components.json +1917 -217
  46. package/dist/meta/contrast.json +594 -90
  47. package/dist/meta/index.json +89 -10
  48. package/dist/meta/patterns/DataTable.json +14 -6
  49. package/dist/meta/patterns/Form.json +27 -2
  50. package/dist/meta/patterns/PageShell.json +18 -5
  51. package/dist/meta/patterns/index.json +5 -2
  52. package/dist/styles/fieldset.css +65 -0
  53. package/dist/styles/index.css +3 -0
  54. package/dist/styles/menu.css +153 -32
  55. package/dist/styles/page-header.css +94 -0
  56. package/dist/styles/radio.css +0 -20
  57. package/dist/styles/search-field.css +70 -0
  58. package/llms.txt +2 -2
  59. package/package.json +1 -1
@@ -2,65 +2,108 @@
2
2
  "name": "Menu",
3
3
  "source": "src/components/Menu.tsx",
4
4
  "propsType": "MenuProps",
5
- "description": "Menu is the list surface, not a popover.\n\nFigma models the list alone — there is no trigger, anchor or open state in\nthe design — so this renders the surface and nothing else. Positioning it\nagainst a button is the caller's job until Figma has a component that says\nhow. Building a popover here would be inventing design, and it would be the\nhard half to unpick later.\n\n`role=\"menu\"` is deliberately NOT set. A real ARIA menu owes the user\nroving-tabindex arrow navigation, typeahead and focus containment; claiming\nthe role without them is worse for a screen-reader user than an honest list,\nbecause it promises interactions that are not there. When the popover exists,\nthe role comes with it.",
5
+ "description": "Menu — Figma `Menu` (82:306), `Menu Item` and `Menu Section Title`.\n\nA real ARIA menu: `role=\"menu\"`, one tab stop, arrow keys, Home and End,\ntypeahead, and disabled rows listed but skipped. Figma's `Type` is\n`selectionMode` — Single draws one check, Multi draws several — and with\na selection mode the rows become `menuitemradio` / `menuitemcheckbox` and\nannounce their checked state.\n\nOn its own it is the surface only, rendered in flow. Inside a MenuTrigger it\nfloats, opens and closes, is named by its trigger, and can open submenus.",
6
6
  "import": "import { Menu } from 'ionbase-ui';",
7
7
  "status": "stable",
8
- "summary": "The list surface only — no trigger, no anchor, no open state. Positioning it is the caller's job.",
8
+ "summary": "An ARIA menu: one tab stop, arrow keys, typeahead, and optional single or multiple selection. Children are MenuItem and MenuSection. Inside a MenuTrigger it floats, opens and closes, and can open submenus; on its own it renders in flow.",
9
9
  "useWhen": [
10
- "rendering a list of actions or options as a surface you have already positioned",
11
- "the rows need icons, a selected check, or two lines — more than a native <select> can hold"
10
+ "a list of actions or choices for the thing the user is on — row actions, a workspace switcher, a sort order",
11
+ "the rows need icons, a selected check, or grouping under headings — more than a native <select> can hold"
12
12
  ],
13
13
  "useInstead": [
14
14
  {
15
- "when": "you want a self-contained dropdown with a trigger and open state",
16
- "use": "Popover",
17
- "why": "Menu is the surface alone; Popover owns the trigger, positioning, focus containment and Escape"
15
+ "when": "a button opens it",
16
+ "use": "MenuTrigger",
17
+ "why": "it gives the trigger aria-haspopup and aria-expanded, opens on ArrowDown, and closes on an action and returns focus — a Popover round a Menu does none of that"
18
18
  },
19
19
  {
20
- "when": "one value is picked from a modest list of plain text options",
20
+ "when": "one value is picked for a form field from a modest list of plain text options",
21
21
  "use": "Select",
22
- "why": "the native picker brings keyboard handling, type-ahead and the mobile platform picker for free"
22
+ "why": "a form value is a listbox, not a menu; the native picker brings type-ahead and the mobile platform picker for free"
23
23
  },
24
24
  {
25
- "when": "it is primary navigation rather than a dropdown",
26
- "use": "NavItem"
25
+ "when": "the user types to narrow a long list down to one value",
26
+ "use": "Combobox"
27
+ },
28
+ {
29
+ "when": "it is primary navigation rather than a list of actions",
30
+ "use": "NavItem",
31
+ "why": "a menu's rows are actions; links to pages belong in the document's navigation, where a screen reader's landmarks find them"
32
+ },
33
+ {
34
+ "when": "any action or page should be reachable by searching",
35
+ "use": "CommandPalette"
27
36
  }
28
37
  ],
29
38
  "composition": {
30
39
  "order": [
31
40
  "Menu",
41
+ "MenuSection",
32
42
  "MenuItem"
33
43
  ],
34
- "example": "<Menu><MenuItem icon={<Icon as={Copy} />}>Duplicate</MenuItem><MenuItem isSelected>Archive</MenuItem></Menu>"
44
+ "note": "MenuItem and MenuSection are collection elements: Menu reads them from its DIRECT children to build the collection, and neither renders anything itself. Every MenuItem needs a `key`, and `onAction`, `selectedKeys` and `disabledKeys` all speak in those keys. To open it from a button, put the Button and the Menu inside a MenuTrigger.",
45
+ "example": "<Menu aria-label=\"Row actions\" onAction={(key) => run(key)}><MenuSection title=\"Edit\"><MenuItem key=\"rename\" icon={<Icon as={Pencil} />}>Rename</MenuItem><MenuItem key=\"duplicate\">Duplicate</MenuItem></MenuSection><MenuSection aria-label=\"Danger\"><MenuItem key=\"archive\" isDisabled>Archive</MenuItem></MenuSection></Menu>"
46
+ },
47
+ "variants": {
48
+ "selectionMode": {
49
+ "none": {
50
+ "use": "the default — a list of actions. Rows are `menuitem`, and there is no check slot"
51
+ },
52
+ "single": {
53
+ "use": "Figma's Type=Single — one current choice, such as a sort order or the active workspace. Rows are `menuitemradio`"
54
+ },
55
+ "multiple": {
56
+ "use": "Figma's Type=Multi — independent toggles, such as visible columns. Rows are `menuitemcheckbox`"
57
+ }
58
+ }
35
59
  },
36
60
  "slots": {
37
61
  "children": {
38
- "accepts": "MenuItem"
62
+ "accepts": [
63
+ "MenuItem",
64
+ "MenuSection"
65
+ ]
39
66
  }
40
67
  },
41
68
  "a11y": {
42
- "role": "none — it is a plain <ul>",
69
+ "role": "menu",
43
70
  "guarantees": [
44
- "no `role=\"menu\"`, deliberately: a real ARIA menu owes the user roving tabindex, arrow-key navigation and typeahead, and claiming the role without them promises interactions that are not there"
71
+ "one tab stop; arrow keys move between rows, Home and End jump, and typing a letter moves to the next row starting with it",
72
+ "disabled rows are listed and announced as unavailable, and the arrow keys skip them",
73
+ "with a selection mode, rows are `menuitemradio` or `menuitemcheckbox` and announce `aria-checked` — the check glyph is never the only signal",
74
+ "the pointer and the keyboard share one highlighted row: hovering a row focuses it"
75
+ ],
76
+ "requires": [
77
+ "an accessible name — `aria-label` or `aria-labelledby` naming what the actions are for"
45
78
  ],
46
79
  "notes": [
47
- "Each MenuItem is a real <button>, so Tab reaches every row. That is honest, and it is not the same as arrow-key menu navigation.",
48
- "The role arrives when the popover that owns it does."
80
+ "A menu is not a form control. It has no `name` and submits nothing; `selectedKeys` is state you hold.",
81
+ "Titled sections are named groups. An untitled section needs `aria-label`, and is set off by a rule.",
82
+ "Submenus need a MenuTrigger. In a standalone Menu a row with MenuItem children renders as a plain row: there is no root to open a submenu from."
49
83
  ]
50
84
  },
51
85
  "antiPatterns": [
52
86
  {
53
- "dont": "adding `role=\"menu\"` yourself",
54
- "why": "the keyboard behaviour that role promises is not implemented; an honest list is better for a screen-reader user than a lying menu"
87
+ "dont": "wrapping MenuItems in a <div>, a fragment or your own component inside Menu",
88
+ "why": "Menu reads its collection from its direct children; a wrapped row is invisible to it and renders nothing"
55
89
  },
56
90
  {
57
- "dont": "using Menu as a dropdown without positioning it",
58
- "why": "it renders in flow — it has no anchor logic of its own"
91
+ "dont": "an `onClick` on MenuItem",
92
+ "why": "MenuItem renders nothing, so there is no element to click. Pass `onAction` to Menu; it receives the item's key, from the pointer, Enter and Space alike"
93
+ },
94
+ {
95
+ "dont": "using Menu for a form field's value",
96
+ "why": "a screen reader announces a menu as actions, and a form cannot read it. Use Select or Combobox"
97
+ },
98
+ {
99
+ "dont": "putting links to other pages in a Menu",
100
+ "why": "they vanish from the page's link list and landmarks. Navigation belongs in NavItem or Sidebar"
59
101
  }
60
102
  ],
61
103
  "stylesheet": "src/styles/menu.css",
62
104
  "tokens": [
63
105
  "--border-focus",
106
+ "--border-strong",
64
107
  "--border-subtle",
65
108
  "--border-width-default",
66
109
  "--border-width-thick",
@@ -72,10 +115,13 @@
72
115
  "--icon-size-sm",
73
116
  "--ion-duration-base",
74
117
  "--ion-ease-out",
118
+ "--ion-menu-min-width",
119
+ "--ion-shadow-shadow-lg",
75
120
  "--radius-sm",
76
121
  "--radius-xl",
77
122
  "--spacing-12",
78
123
  "--spacing-2",
124
+ "--spacing-4",
79
125
  "--spacing-40",
80
126
  "--spacing-6",
81
127
  "--spacing-8",
@@ -85,20 +131,148 @@
85
131
  "--text-disabled",
86
132
  "--text-primary",
87
133
  "--text-secondary",
134
+ "--text-tertiary",
88
135
  "--type-body",
89
- "--type-body-line-height"
136
+ "--type-body-line-height",
137
+ "--type-caption",
138
+ "--type-caption-line-height"
90
139
  ],
91
140
  "props": {
92
- "children": {
93
- "type": "React.ReactNode",
141
+ "className": {
142
+ "type": "string | undefined",
143
+ "required": false,
144
+ "origin": "own"
145
+ },
146
+ "style": {
147
+ "type": "React.CSSProperties | undefined",
94
148
  "required": false,
95
149
  "origin": "own"
150
+ },
151
+ "escapeKeyBehavior": {
152
+ "type": "\"none\" | \"clearSelection\" | undefined",
153
+ "required": false,
154
+ "origin": "aria",
155
+ "description": "Whether pressing the escape key should clear selection in the menu or not.\n\nMost experiences should not modify this option as it eliminates a keyboard user's ability to\neasily clear selection. Only use if the escape key is being handled externally or should not\ntrigger selection clearing contextually.",
156
+ "values": [
157
+ "none",
158
+ "clearSelection"
159
+ ],
160
+ "tags": {
161
+ "default": "'clearSelection'"
162
+ }
163
+ },
164
+ "autoFocus": {
165
+ "type": "boolean | FocusStrategy | undefined",
166
+ "required": false,
167
+ "origin": "aria",
168
+ "description": "Where the focus should be set."
169
+ },
170
+ "shouldFocusWrap": {
171
+ "type": "boolean | undefined",
172
+ "required": false,
173
+ "origin": "aria",
174
+ "description": "Whether keyboard navigation is circular."
175
+ },
176
+ "onAction": {
177
+ "type": "((key: Key, value: T) => void) | undefined",
178
+ "required": false,
179
+ "origin": "aria",
180
+ "description": "Handler that is called when an item is selected."
181
+ },
182
+ "onClose": {
183
+ "type": "(() => void) | undefined",
184
+ "required": false,
185
+ "origin": "aria",
186
+ "description": "Handler that is called when the menu should close after selecting an item."
187
+ },
188
+ "children": {
189
+ "type": "CollectionChildren<T>",
190
+ "required": true,
191
+ "origin": "aria",
192
+ "description": "The contents of the collection."
193
+ },
194
+ "items": {
195
+ "type": "Iterable<T> | undefined",
196
+ "required": false,
197
+ "origin": "aria",
198
+ "description": "Item objects in the collection."
199
+ },
200
+ "disabledKeys": {
201
+ "type": "Iterable<Key> | undefined",
202
+ "required": false,
203
+ "origin": "aria",
204
+ "description": "The item keys that are disabled. These items cannot be selected, focused, or otherwise\ninteracted with."
205
+ },
206
+ "selectionMode": {
207
+ "type": "SelectionMode | undefined",
208
+ "required": false,
209
+ "origin": "aria",
210
+ "description": "The type of selection that is allowed in the collection.",
211
+ "values": [
212
+ "multiple",
213
+ "none",
214
+ "single"
215
+ ]
216
+ },
217
+ "disallowEmptySelection": {
218
+ "type": "boolean | undefined",
219
+ "required": false,
220
+ "origin": "aria",
221
+ "description": "Whether the collection allows empty selection."
222
+ },
223
+ "selectedKeys": {
224
+ "type": "Iterable<Key> | \"all\" | undefined",
225
+ "required": false,
226
+ "origin": "aria",
227
+ "description": "The currently selected keys in the collection (controlled)."
228
+ },
229
+ "defaultSelectedKeys": {
230
+ "type": "Iterable<Key> | \"all\" | undefined",
231
+ "required": false,
232
+ "origin": "aria",
233
+ "description": "The initial selected keys in the collection (uncontrolled)."
234
+ },
235
+ "onSelectionChange": {
236
+ "type": "((keys: Selection) => void) | undefined",
237
+ "required": false,
238
+ "origin": "aria",
239
+ "description": "Handler that is called when the selection changes."
240
+ },
241
+ "id": {
242
+ "type": "string | undefined",
243
+ "required": false,
244
+ "origin": "aria",
245
+ "description": "The element's unique identifier. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)."
246
+ },
247
+ "aria-label": {
248
+ "type": "string | undefined",
249
+ "required": false,
250
+ "origin": "aria",
251
+ "description": "Defines a string value that labels the current element."
252
+ },
253
+ "aria-labelledby": {
254
+ "type": "string | undefined",
255
+ "required": false,
256
+ "origin": "aria",
257
+ "description": "Identifies the element (or elements) that labels the current element."
258
+ },
259
+ "aria-describedby": {
260
+ "type": "string | undefined",
261
+ "required": false,
262
+ "origin": "aria",
263
+ "description": "Identifies the element (or elements) that describes the object."
264
+ },
265
+ "aria-details": {
266
+ "type": "string | undefined",
267
+ "required": false,
268
+ "origin": "aria",
269
+ "description": "Identifies the element (or elements) that provide a detailed, extended description for the\nobject."
96
270
  }
97
271
  },
98
272
  "propCounts": {
99
- "own": 1,
100
- "aria": 0,
101
- "dom": 277,
273
+ "own": 2,
274
+ "aria": 18,
275
+ "dom": 0,
102
276
  "other": 0
103
277
  }
104
278
  }
@@ -2,11 +2,12 @@
2
2
  "name": "MenuItem",
3
3
  "source": "src/components/Menu.tsx",
4
4
  "propsType": "MenuItemProps",
5
+ "description": "One row of a Menu. A collection element, like TabItem: it renders nothing\nitself — Menu reads its props and draws the row — so it only means anything\nas a direct child of Menu or MenuSection. Give it a `key`; that key is what\n`onAction` and `selectedKeys` speak in.",
5
6
  "import": "import { MenuItem } from 'ionbase-ui';",
6
7
  "status": "stable",
7
- "summary": "One row in a Menu. A real <button> inside an <li>, with an optional leading icon and a trailing selected check.",
8
+ "summary": "One row of a Menu. A collection element: Menu reads its props and draws the row as `menuitem`, `menuitemradio` or `menuitemcheckbox`.",
8
9
  "useWhen": [
9
- "a row in a Menu surface"
10
+ "a row in a Menu or a MenuSection — it is not usable anywhere else"
10
11
  ],
11
12
  "useInstead": [
12
13
  {
@@ -18,6 +19,14 @@
18
19
  "use": "Button"
19
20
  }
20
21
  ],
22
+ "composition": {
23
+ "order": [
24
+ "Menu",
25
+ "MenuItem"
26
+ ],
27
+ "note": "A collection element, like TabItem: it renders nothing itself and never appears in the DOM. `key` identifies it to Menu's `onAction`, `selectedKeys` and `disabledKeys`.",
28
+ "example": "<MenuItem key=\"duplicate\" icon={<Icon as={Copy} />}>Duplicate</MenuItem>\n<MenuItem key=\"move\" title=\"Move to\"><MenuItem key=\"archive\">Archive</MenuItem></MenuItem>"
29
+ },
21
30
  "slots": {
22
31
  "icon": {
23
32
  "accepts": "Icon",
@@ -26,37 +35,50 @@
26
35
  "children": {
27
36
  "accepts": "text",
28
37
  "note": "the row label"
38
+ },
39
+ "title": {
40
+ "accepts": "text",
41
+ "note": "only on a row that opens a submenu: the row's label, while its children are the submenu's MenuItems. Submenus open only inside a MenuTrigger"
29
42
  }
30
43
  },
31
44
  "a11y": {
32
- "role": "button",
33
45
  "guarantees": [
34
- "`isSelected` sets `aria-pressed`, so the selected state is announced and not only drawn",
35
- "the check glyph always occupies its slot, so rows never reflow as the selection moves"
46
+ "the role, `aria-checked` and `aria-disabled` are supplied by Menu from its selection mode and keys, not by this element",
47
+ "the check glyph occupies its slot whenever the menu has a selection mode, so rows never reflow as the selection moves"
36
48
  ],
37
49
  "requires": [
38
- "a text label in `children`"
50
+ "a stable `key`",
51
+ "text in `children`, or `textValue` when the children are not plain text — typeahead matches against it"
39
52
  ]
40
53
  },
41
54
  "antiPatterns": [
42
55
  {
43
56
  "dont": "using MenuItem outside a Menu",
44
- "why": "it renders an <li>, which is only valid inside a list"
57
+ "why": "it renders nothing on its own"
45
58
  },
46
59
  {
47
60
  "dont": "an icon-only MenuItem with no children",
48
- "why": "the row announces nothing"
61
+ "why": "the row announces nothing and typeahead cannot reach it"
62
+ },
63
+ {
64
+ "dont": "array indexes as keys in a list that can change",
65
+ "why": "selection and actions are expressed in keys, so the selected row silently becomes a different row"
49
66
  }
50
67
  ],
51
68
  "deprecated": [
52
69
  {
53
70
  "prop": "disabled",
54
71
  "replacement": "isDisabled"
72
+ },
73
+ {
74
+ "prop": "isSelected",
75
+ "note": "Put the item's key in Menu's `selectedKeys` and set its `selectionMode`."
55
76
  }
56
77
  ],
57
78
  "stylesheet": "src/styles/menu.css",
58
79
  "tokens": [
59
80
  "--border-focus",
81
+ "--border-strong",
60
82
  "--border-subtle",
61
83
  "--border-width-default",
62
84
  "--border-width-thick",
@@ -68,10 +90,13 @@
68
90
  "--icon-size-sm",
69
91
  "--ion-duration-base",
70
92
  "--ion-ease-out",
93
+ "--ion-menu-min-width",
94
+ "--ion-shadow-shadow-lg",
71
95
  "--radius-sm",
72
96
  "--radius-xl",
73
97
  "--spacing-12",
74
98
  "--spacing-2",
99
+ "--spacing-4",
75
100
  "--spacing-40",
76
101
  "--spacing-6",
77
102
  "--spacing-8",
@@ -81,15 +106,18 @@
81
106
  "--text-disabled",
82
107
  "--text-primary",
83
108
  "--text-secondary",
109
+ "--text-tertiary",
84
110
  "--type-body",
85
- "--type-body-line-height"
111
+ "--type-body-line-height",
112
+ "--type-caption",
113
+ "--type-caption-line-height"
86
114
  ],
87
115
  "props": {
88
- "isSelected": {
89
- "type": "boolean | undefined",
116
+ "title": {
117
+ "type": "React.ReactNode",
90
118
  "required": false,
91
119
  "origin": "own",
92
- "description": "Figma's `Selected` / `Selected-hover` states. Shows the trailing check."
120
+ "description": "Only on a row that opens a submenu: the row's label. Its children are then\nthe submenu's MenuItems rather than its label. Submenus open only inside a\nMenuTrigger — a standalone Menu has nothing to open them from."
93
121
  },
94
122
  "icon": {
95
123
  "type": "React.ReactNode",
@@ -101,7 +129,7 @@
101
129
  "type": "boolean | undefined",
102
130
  "required": false,
103
131
  "origin": "own",
104
- "description": "Whether the item is disabled."
132
+ "description": "Whether the item is disabled. Listed, skipped by the arrow keys."
105
133
  },
106
134
  "disabled": {
107
135
  "type": "boolean | undefined",
@@ -111,16 +139,108 @@
111
139
  "deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
112
140
  }
113
141
  },
142
+ "isSelected": {
143
+ "type": "boolean | undefined",
144
+ "required": false,
145
+ "origin": "own",
146
+ "tags": {
147
+ "deprecated": "Put the item's key in Menu's `selectedKeys`. Accepted for one\nminor version: when no item's key is in `selectedKeys` and Menu is given\nneither `selectedKeys` nor `defaultSelectedKeys`, the items passing this\nbecome the selection."
148
+ }
149
+ },
114
150
  "children": {
115
- "type": "React.ReactNode",
151
+ "type": "ReactNode",
152
+ "required": true,
153
+ "origin": "aria",
154
+ "description": "Rendered contents of the item or child items."
155
+ },
156
+ "textValue": {
157
+ "type": "string | undefined",
158
+ "required": false,
159
+ "origin": "aria",
160
+ "description": "A string representation of the item's contents, used for features like typeahead."
161
+ },
162
+ "aria-label": {
163
+ "type": "string | undefined",
164
+ "required": false,
165
+ "origin": "aria",
166
+ "description": "An accessibility label for this item."
167
+ },
168
+ "childItems": {
169
+ "type": "Iterable<T> | undefined",
170
+ "required": false,
171
+ "origin": "aria",
172
+ "description": "A list of child item objects. Used for dynamic collections."
173
+ },
174
+ "hasChildItems": {
175
+ "type": "boolean | undefined",
176
+ "required": false,
177
+ "origin": "aria",
178
+ "description": "Whether this item has children, even if not loaded yet."
179
+ },
180
+ "href": {
181
+ "type": "string | undefined",
182
+ "required": false,
183
+ "origin": "aria",
184
+ "description": "A URL to link to. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#href)."
185
+ },
186
+ "hrefLang": {
187
+ "type": "string | undefined",
188
+ "required": false,
189
+ "origin": "aria",
190
+ "description": "Hints at the human language of the linked URL.\nSee[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#hreflang)."
191
+ },
192
+ "target": {
193
+ "type": "HTMLAttributeAnchorTarget | undefined",
194
+ "required": false,
195
+ "origin": "aria",
196
+ "description": "The target window for the link. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target)."
197
+ },
198
+ "rel": {
199
+ "type": "string | undefined",
200
+ "required": false,
201
+ "origin": "aria",
202
+ "description": "The relationship between the linked resource and the current page. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel)."
203
+ },
204
+ "download": {
205
+ "type": "string | boolean | undefined",
206
+ "required": false,
207
+ "origin": "aria",
208
+ "description": "Causes the browser to download the linked URL. A string may be provided to suggest a file name.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download)."
209
+ },
210
+ "ping": {
211
+ "type": "string | undefined",
212
+ "required": false,
213
+ "origin": "aria",
214
+ "description": "A space-separated list of URLs to ping when the link is followed. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#ping)."
215
+ },
216
+ "referrerPolicy": {
217
+ "type": "HTMLAttributeReferrerPolicy | undefined",
218
+ "required": false,
219
+ "origin": "aria",
220
+ "description": "How much of the referrer to send when following the link. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#referrerpolicy).",
221
+ "values": [
222
+ "",
223
+ "origin",
224
+ "no-referrer",
225
+ "no-referrer-when-downgrade",
226
+ "origin-when-cross-origin",
227
+ "same-origin",
228
+ "strict-origin",
229
+ "strict-origin-when-cross-origin",
230
+ "unsafe-url"
231
+ ]
232
+ },
233
+ "routerOptions": {
234
+ "type": "undefined",
116
235
  "required": false,
117
- "origin": "own"
236
+ "origin": "aria",
237
+ "description": "Options for the configured client side router."
118
238
  }
119
239
  },
120
240
  "propCounts": {
121
241
  "own": 5,
122
- "aria": 0,
123
- "dom": 285,
242
+ "aria": 13,
243
+ "dom": 0,
124
244
  "other": 0
125
245
  }
126
246
  }
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "MenuSection",
3
+ "source": "../../node_modules/.pnpm/react-stately@3.48.0_react@19.2.8/node_modules/react-stately/dist/types/src/collections/Section.d.ts",
4
+ "propsType": null,
5
+ "import": "import { MenuSection } from 'ionbase-ui';",
6
+ "status": "stable",
7
+ "summary": "A named group of MenuItems. Re-exported from react-stately's collection Section — `title` is Figma's Menu Section Title.",
8
+ "useWhen": [
9
+ "a Menu has more than one kind of action, such as editing actions and destructive ones",
10
+ "the rows fall into groups the user scans by name"
11
+ ],
12
+ "useInstead": [
13
+ {
14
+ "when": "the menu has one group",
15
+ "use": "MenuItem",
16
+ "why": "a single section adds a heading the user must hear before every menu, and says nothing the menu's own label does not"
17
+ }
18
+ ],
19
+ "composition": {
20
+ "order": [
21
+ "Menu",
22
+ "MenuSection",
23
+ "MenuItem"
24
+ ],
25
+ "note": "A collection element: Menu reads it from its direct children. With `title`, the heading is drawn with a rule after it; without one, `aria-label` names the group and a rule is drawn above it instead.",
26
+ "example": "<MenuSection title=\"Sort by\"><MenuItem key=\"name\">Name</MenuItem><MenuItem key=\"updated\">Last updated</MenuItem></MenuSection>"
27
+ },
28
+ "a11y": {
29
+ "role": "group",
30
+ "guarantees": [
31
+ "the group is named by its title, so a screen reader announces it on entering the first row"
32
+ ],
33
+ "requires": [
34
+ "a `title`; an untitled section still needs a label for the group, or it is announced as an unnamed group"
35
+ ],
36
+ "notes": [
37
+ "The accessible-name lint rule is deliberately not driven from here: a titled section is named by its title and needs nothing more, so demanding a label on every MenuSection would be wrong for the common case."
38
+ ]
39
+ },
40
+ "antiPatterns": [
41
+ {
42
+ "dont": "nesting a MenuSection inside another",
43
+ "why": "a menu has one level of grouping; a section inside a section renders nothing"
44
+ }
45
+ ],
46
+ "stylesheet": "src/styles/menu.css",
47
+ "tokens": [
48
+ "--border-focus",
49
+ "--border-strong",
50
+ "--border-subtle",
51
+ "--border-width-default",
52
+ "--border-width-thick",
53
+ "--font-family-sans",
54
+ "--font-weight-regular",
55
+ "--icon-default",
56
+ "--icon-disabled",
57
+ "--icon-primary",
58
+ "--icon-size-sm",
59
+ "--ion-duration-base",
60
+ "--ion-ease-out",
61
+ "--ion-menu-min-width",
62
+ "--ion-shadow-shadow-lg",
63
+ "--radius-sm",
64
+ "--radius-xl",
65
+ "--spacing-12",
66
+ "--spacing-2",
67
+ "--spacing-4",
68
+ "--spacing-40",
69
+ "--spacing-6",
70
+ "--spacing-8",
71
+ "--surface-default",
72
+ "--surface-hover",
73
+ "--surface-primary-subtle",
74
+ "--text-disabled",
75
+ "--text-primary",
76
+ "--text-secondary",
77
+ "--text-tertiary",
78
+ "--type-body",
79
+ "--type-body-line-height",
80
+ "--type-caption",
81
+ "--type-caption-line-height"
82
+ ],
83
+ "props": {},
84
+ "propCounts": {
85
+ "own": 0,
86
+ "aria": 0,
87
+ "dom": 0,
88
+ "other": 0
89
+ }
90
+ }