ionbase-ui 0.81.1 → 0.84.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/components/Menu.d.ts +87 -24
- package/dist/components/Menu.d.ts.map +1 -1
- package/dist/components/Menu.js +245 -28
- package/dist/components/Menu.js.map +1 -1
- package/dist/components/PageHeader.d.ts +59 -0
- package/dist/components/PageHeader.d.ts.map +1 -0
- package/dist/components/PageHeader.js +29 -0
- package/dist/components/PageHeader.js.map +1 -0
- package/dist/components/index.d.ts +4 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -1
- package/dist/components/index.js.map +1 -1
- package/dist/figma-descriptions.json +86 -76
- package/dist/figma-map.json +142 -38
- package/dist/meta/Menu.json +201 -27
- package/dist/meta/MenuItem.json +137 -17
- package/dist/meta/MenuSection.json +90 -0
- package/dist/meta/MenuTrigger.json +177 -0
- package/dist/meta/PageHeader.json +169 -0
- package/dist/meta/components.json +817 -87
- package/dist/meta/contrast.json +240 -32
- package/dist/meta/index.json +31 -3
- package/dist/meta/patterns/PageShell.json +18 -5
- package/dist/meta/patterns/index.json +2 -1
- package/dist/styles/index.css +1 -0
- package/dist/styles/menu.css +153 -32
- package/dist/styles/page-header.css +94 -0
- package/llms.txt +2 -2
- package/package.json +1 -1
package/dist/figma-map.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "ionbase-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.84.0",
|
|
4
4
|
"figmaFile": "gaLbGd0QNb1fUl6BjSpfBA",
|
|
5
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.",
|
|
@@ -1129,37 +1129,52 @@
|
|
|
1129
1129
|
"docs": "components/menu/index.html.md",
|
|
1130
1130
|
"props": {
|
|
1131
1131
|
"Type": {
|
|
1132
|
-
"
|
|
1132
|
+
"prop": "selectionMode",
|
|
1133
|
+
"values": {
|
|
1134
|
+
"Single": "single",
|
|
1135
|
+
"Multi": "multiple"
|
|
1136
|
+
},
|
|
1137
|
+
"note": "selectionMode none — an action menu with no check slot — is not drawn; every Figma menu shows a selection."
|
|
1133
1138
|
}
|
|
1134
1139
|
}
|
|
1135
1140
|
},
|
|
1136
|
-
"
|
|
1141
|
+
"82:217": {
|
|
1137
1142
|
"figmaComponent": "Menu Item",
|
|
1138
|
-
"figmaNodeId": "
|
|
1139
|
-
"figmaPage": "
|
|
1143
|
+
"figmaNodeId": "82:217",
|
|
1144
|
+
"figmaPage": "Menu",
|
|
1140
1145
|
"component": "MenuItem",
|
|
1141
1146
|
"import": "import { MenuItem } from 'ionbase-ui';",
|
|
1142
1147
|
"docs": "components/menu-item/index.html.md",
|
|
1143
1148
|
"props": {
|
|
1144
|
-
"
|
|
1145
|
-
"prop": "isSelected",
|
|
1146
|
-
"when": {
|
|
1147
|
-
"Selected": true,
|
|
1148
|
-
"Selected Primary": true
|
|
1149
|
-
},
|
|
1150
|
-
"note": "Hover is CSS. Selected Primary is a second selected styling Figma draws and code does not yet ship."
|
|
1151
|
-
},
|
|
1152
|
-
"Text#639:12": {
|
|
1149
|
+
"Label#82:0": {
|
|
1153
1150
|
"prop": "children"
|
|
1154
1151
|
},
|
|
1155
|
-
"
|
|
1156
|
-
"prop": "icon"
|
|
1152
|
+
"Leading Icon#82:12": {
|
|
1153
|
+
"prop": "icon",
|
|
1154
|
+
"note": "wrap in Icon; omit Icon's label, the row text names it"
|
|
1157
1155
|
},
|
|
1158
|
-
"
|
|
1159
|
-
"prop": "icon"
|
|
1156
|
+
"Show Leading Icon#82:6": {
|
|
1157
|
+
"prop": "icon",
|
|
1158
|
+
"note": "an absent prop is the switch, so false means omit icon"
|
|
1159
|
+
},
|
|
1160
|
+
"State": {
|
|
1161
|
+
"prop": "isDisabled",
|
|
1162
|
+
"when": {
|
|
1163
|
+
"Disabled": true
|
|
1164
|
+
},
|
|
1165
|
+
"note": "Hover is the highlighted row, which the keyboard and the pointer share. Selected and Selected-hover are the row's key in Menu's selectedKeys, not an item prop. A row that opens a submenu is not drawn: code puts a chevron where the check sits."
|
|
1160
1166
|
}
|
|
1161
1167
|
}
|
|
1162
1168
|
},
|
|
1169
|
+
"1468:271": {
|
|
1170
|
+
"figmaComponent": "Menu Section Title",
|
|
1171
|
+
"figmaNodeId": "1468:271",
|
|
1172
|
+
"figmaPage": "Menu",
|
|
1173
|
+
"component": "MenuSection",
|
|
1174
|
+
"import": "import { MenuSection } from 'ionbase-ui';",
|
|
1175
|
+
"docs": "components/menu-section/index.html.md",
|
|
1176
|
+
"props": {}
|
|
1177
|
+
},
|
|
1163
1178
|
"792:1537": {
|
|
1164
1179
|
"figmaComponent": "Modal",
|
|
1165
1180
|
"figmaNodeId": "792:1537",
|
|
@@ -1268,6 +1283,42 @@
|
|
|
1268
1283
|
}
|
|
1269
1284
|
}
|
|
1270
1285
|
},
|
|
1286
|
+
"1473:242": {
|
|
1287
|
+
"figmaComponent": "Page Header",
|
|
1288
|
+
"figmaNodeId": "1473:242",
|
|
1289
|
+
"figmaPage": "Page Header",
|
|
1290
|
+
"component": "PageHeader",
|
|
1291
|
+
"import": "import { PageHeader } from 'ionbase-ui';",
|
|
1292
|
+
"docs": "components/page-header/index.html.md",
|
|
1293
|
+
"props": {
|
|
1294
|
+
"Title#1473:0": {
|
|
1295
|
+
"prop": "title"
|
|
1296
|
+
},
|
|
1297
|
+
"Description#1473:1": {
|
|
1298
|
+
"prop": "description"
|
|
1299
|
+
},
|
|
1300
|
+
"Show Description#1473:4": {
|
|
1301
|
+
"prop": "description",
|
|
1302
|
+
"note": "an absent prop is the switch, so false means omit description"
|
|
1303
|
+
},
|
|
1304
|
+
"Show Breadcrumb#1473:2": {
|
|
1305
|
+
"prop": "breadcrumb",
|
|
1306
|
+
"note": "pass a Breadcrumb; false means omit breadcrumb"
|
|
1307
|
+
},
|
|
1308
|
+
"Show Status#1473:3": {
|
|
1309
|
+
"prop": "status",
|
|
1310
|
+
"note": "a Badge for the record's state; false means omit status"
|
|
1311
|
+
},
|
|
1312
|
+
"Show Actions#1473:5": {
|
|
1313
|
+
"prop": "actions",
|
|
1314
|
+
"note": "Buttons, most important last, and a MenuTrigger with an icon-only Button for the rest; false means omit actions"
|
|
1315
|
+
},
|
|
1316
|
+
"Show Below#1473:6": {
|
|
1317
|
+
"prop": "children",
|
|
1318
|
+
"note": "the row beneath — the page's Tabs or its filters; false means no children"
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
},
|
|
1271
1322
|
"1291:503": {
|
|
1272
1323
|
"figmaComponent": "Pagination",
|
|
1273
1324
|
"figmaNodeId": "1291:503",
|
|
@@ -3431,37 +3482,52 @@
|
|
|
3431
3482
|
"docs": "components/menu/index.html.md",
|
|
3432
3483
|
"props": {
|
|
3433
3484
|
"Type": {
|
|
3434
|
-
"
|
|
3485
|
+
"prop": "selectionMode",
|
|
3486
|
+
"values": {
|
|
3487
|
+
"Single": "single",
|
|
3488
|
+
"Multi": "multiple"
|
|
3489
|
+
},
|
|
3490
|
+
"note": "selectionMode none — an action menu with no check slot — is not drawn; every Figma menu shows a selection."
|
|
3435
3491
|
}
|
|
3436
3492
|
}
|
|
3437
3493
|
},
|
|
3438
3494
|
"Menu Item": {
|
|
3439
3495
|
"figmaComponent": "Menu Item",
|
|
3440
|
-
"figmaNodeId": "
|
|
3441
|
-
"figmaPage": "
|
|
3496
|
+
"figmaNodeId": "82:217",
|
|
3497
|
+
"figmaPage": "Menu",
|
|
3442
3498
|
"component": "MenuItem",
|
|
3443
3499
|
"import": "import { MenuItem } from 'ionbase-ui';",
|
|
3444
3500
|
"docs": "components/menu-item/index.html.md",
|
|
3445
3501
|
"props": {
|
|
3446
|
-
"
|
|
3447
|
-
"prop": "isSelected",
|
|
3448
|
-
"when": {
|
|
3449
|
-
"Selected": true,
|
|
3450
|
-
"Selected Primary": true
|
|
3451
|
-
},
|
|
3452
|
-
"note": "Hover is CSS. Selected Primary is a second selected styling Figma draws and code does not yet ship."
|
|
3453
|
-
},
|
|
3454
|
-
"Text#639:12": {
|
|
3502
|
+
"Label#82:0": {
|
|
3455
3503
|
"prop": "children"
|
|
3456
3504
|
},
|
|
3457
|
-
"
|
|
3458
|
-
"prop": "icon"
|
|
3505
|
+
"Leading Icon#82:12": {
|
|
3506
|
+
"prop": "icon",
|
|
3507
|
+
"note": "wrap in Icon; omit Icon's label, the row text names it"
|
|
3459
3508
|
},
|
|
3460
|
-
"
|
|
3461
|
-
"prop": "icon"
|
|
3509
|
+
"Show Leading Icon#82:6": {
|
|
3510
|
+
"prop": "icon",
|
|
3511
|
+
"note": "an absent prop is the switch, so false means omit icon"
|
|
3512
|
+
},
|
|
3513
|
+
"State": {
|
|
3514
|
+
"prop": "isDisabled",
|
|
3515
|
+
"when": {
|
|
3516
|
+
"Disabled": true
|
|
3517
|
+
},
|
|
3518
|
+
"note": "Hover is the highlighted row, which the keyboard and the pointer share. Selected and Selected-hover are the row's key in Menu's selectedKeys, not an item prop. A row that opens a submenu is not drawn: code puts a chevron where the check sits."
|
|
3462
3519
|
}
|
|
3463
3520
|
}
|
|
3464
3521
|
},
|
|
3522
|
+
"Menu Section Title": {
|
|
3523
|
+
"figmaComponent": "Menu Section Title",
|
|
3524
|
+
"figmaNodeId": "1468:271",
|
|
3525
|
+
"figmaPage": "Menu",
|
|
3526
|
+
"component": "MenuSection",
|
|
3527
|
+
"import": "import { MenuSection } from 'ionbase-ui';",
|
|
3528
|
+
"docs": "components/menu-section/index.html.md",
|
|
3529
|
+
"props": {}
|
|
3530
|
+
},
|
|
3465
3531
|
"Modal": {
|
|
3466
3532
|
"figmaComponent": "Modal",
|
|
3467
3533
|
"figmaNodeId": "792:1537",
|
|
@@ -3570,6 +3636,42 @@
|
|
|
3570
3636
|
}
|
|
3571
3637
|
}
|
|
3572
3638
|
},
|
|
3639
|
+
"Page Header": {
|
|
3640
|
+
"figmaComponent": "Page Header",
|
|
3641
|
+
"figmaNodeId": "1473:242",
|
|
3642
|
+
"figmaPage": "Page Header",
|
|
3643
|
+
"component": "PageHeader",
|
|
3644
|
+
"import": "import { PageHeader } from 'ionbase-ui';",
|
|
3645
|
+
"docs": "components/page-header/index.html.md",
|
|
3646
|
+
"props": {
|
|
3647
|
+
"Title#1473:0": {
|
|
3648
|
+
"prop": "title"
|
|
3649
|
+
},
|
|
3650
|
+
"Description#1473:1": {
|
|
3651
|
+
"prop": "description"
|
|
3652
|
+
},
|
|
3653
|
+
"Show Description#1473:4": {
|
|
3654
|
+
"prop": "description",
|
|
3655
|
+
"note": "an absent prop is the switch, so false means omit description"
|
|
3656
|
+
},
|
|
3657
|
+
"Show Breadcrumb#1473:2": {
|
|
3658
|
+
"prop": "breadcrumb",
|
|
3659
|
+
"note": "pass a Breadcrumb; false means omit breadcrumb"
|
|
3660
|
+
},
|
|
3661
|
+
"Show Status#1473:3": {
|
|
3662
|
+
"prop": "status",
|
|
3663
|
+
"note": "a Badge for the record's state; false means omit status"
|
|
3664
|
+
},
|
|
3665
|
+
"Show Actions#1473:5": {
|
|
3666
|
+
"prop": "actions",
|
|
3667
|
+
"note": "Buttons, most important last, and a MenuTrigger with an icon-only Button for the rest; false means omit actions"
|
|
3668
|
+
},
|
|
3669
|
+
"Show Below#1473:6": {
|
|
3670
|
+
"prop": "children",
|
|
3671
|
+
"note": "the row beneath — the page's Tabs or its filters; false means no children"
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
},
|
|
3573
3675
|
"Pagination": {
|
|
3574
3676
|
"figmaComponent": "Pagination",
|
|
3575
3677
|
"figmaNodeId": "1291:503",
|
|
@@ -4616,15 +4718,16 @@
|
|
|
4616
4718
|
"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.",
|
|
4617
4719
|
"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.",
|
|
4618
4720
|
"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.",
|
|
4721
|
+
"Command Palette Item": "One row of the palette, drawn so Active and Disabled can be seen. There is no code export behind it and there should not be: rows are built from the palette's `commands` array, where the Label, Description, Icon and shortcut are fields of one command — `label`, `description`, `icon`, `shortcut` — and Active is the keyboard's position, not a prop. The same call Combobox Menu gets.",
|
|
4619
4722
|
"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.",
|
|
4620
4723
|
"Line": "An internal part of the Scroll Progress rail, not a component a caller composes.",
|
|
4621
|
-
"Menu Section Title": "No code counterpart yet. It is a heading inside a menu surface; nothing renders it.",
|
|
4622
4724
|
"Pagination Item": "The cell inside Pagination — a page number, an arrow or the truncation ellipsis. Figma needs it as its own set to hold the Size x State matrix; a caller never places one, so it is internal to Pagination the way Line and Progress are internal to Scroll Progress.",
|
|
4623
4725
|
"Progress": "As Line — internal to ScrollProgress.",
|
|
4624
4726
|
"Progress Heading": "As Line — internal to ScrollProgress.",
|
|
4625
4727
|
"Screen Frame": "The frame FullCard draws around its media slot. The component owns it, so there is nothing for a caller to place.",
|
|
4626
|
-
"
|
|
4627
|
-
"
|
|
4728
|
+
"Side Menu Item": "A 32-tall side-navigation row on the Side Menu page, which predates Sidebar. It shared the name Menu Item with the real one (82:217) until 25 Sep 2026, and because the export keyed on the name it silently replaced it — the mapping, the gates and the Dev Mode block all pointed here. Sidebar Item is the side-navigation row code ships.",
|
|
4729
|
+
"Side Menu Section Title": "The section heading of the same pre-Sidebar side menu. Menu Section Title (1468:271) is the menu's own, drawn on the Menu page; Sidebar Section is the side navigation's.",
|
|
4730
|
+
"Table/Cell Text": "TableCell covers Figma's Table Cell and Cell Text together; the two are never used apart in the design. Recorded in TableCell's contract."
|
|
4628
4731
|
},
|
|
4629
4732
|
"codeUnmapped": {
|
|
4630
4733
|
"DateRangePicker": "Drawn, but not as a set of its own: its field is Date Picker Type=Range and its calendar is Calendar Mode=Range. A Figma set maps to exactly one code component, and splitting one field into two sets to satisfy that would draw the same box twice. Read Date Picker’s Type note for the handoff.",
|
|
@@ -4635,6 +4738,7 @@
|
|
|
4635
4738
|
"Table": "Figma draws Table Row and Table Cell; the table itself is the caller assembling them. Density, the one property Table owns, is mapped on Table Cell.",
|
|
4636
4739
|
"TableBody": "As TableHead.",
|
|
4637
4740
|
"TableHead": "As Table — a code-side grouping element. Figma expresses a header row as a Table Row variant, not a separate component.",
|
|
4638
|
-
"ToastProvider": "Figma draws Toast, which is mapped. The provider is placement, queueing and the live region — runtime behaviour with nothing to draw."
|
|
4741
|
+
"ToastProvider": "Figma draws Toast, which is mapped. The provider is placement, queueing and the live region — runtime behaviour with nothing to draw.",
|
|
4742
|
+
"MenuTrigger": "Composition, not a drawing: a Button followed by a Menu, both already drawn and mapped. What MenuTrigger adds — open state, positioning, aria-haspopup and aria-expanded, focus on open and return on close — is runtime behaviour a static frame cannot hold, the same reason RadioGroup is here."
|
|
4639
4743
|
}
|
|
4640
4744
|
}
|
package/dist/meta/Menu.json
CHANGED
|
@@ -2,65 +2,108 @@
|
|
|
2
2
|
"name": "Menu",
|
|
3
3
|
"source": "src/components/Menu.tsx",
|
|
4
4
|
"propsType": "MenuProps",
|
|
5
|
-
"description": "Menu
|
|
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": "
|
|
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
|
-
"
|
|
11
|
-
"the rows need icons, a selected check, or
|
|
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": "
|
|
16
|
-
"use": "
|
|
17
|
-
"why": "
|
|
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
|
|
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": "
|
|
26
|
-
"use": "
|
|
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
|
-
"
|
|
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":
|
|
62
|
+
"accepts": [
|
|
63
|
+
"MenuItem",
|
|
64
|
+
"MenuSection"
|
|
65
|
+
]
|
|
39
66
|
}
|
|
40
67
|
},
|
|
41
68
|
"a11y": {
|
|
42
|
-
"role": "
|
|
69
|
+
"role": "menu",
|
|
43
70
|
"guarantees": [
|
|
44
|
-
"
|
|
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
|
-
"
|
|
48
|
-
"
|
|
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": "
|
|
54
|
-
"why": "
|
|
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": "
|
|
58
|
-
"why": "
|
|
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
|
-
"
|
|
93
|
-
"type": "
|
|
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":
|
|
100
|
-
"aria":
|
|
101
|
-
"dom":
|
|
273
|
+
"own": 2,
|
|
274
|
+
"aria": 18,
|
|
275
|
+
"dom": 0,
|
|
102
276
|
"other": 0
|
|
103
277
|
}
|
|
104
278
|
}
|