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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "ionbase-ui",
3
- "version": "0.81.1",
3
+ "version": "0.84.0",
4
4
  "generated": "by scripts/build-meta.mjs — do not edit; intent lives in meta/*.json",
5
5
  "hooks": [
6
6
  "useAgentRun",
@@ -7046,65 +7046,575 @@
7046
7046
  "name": "Menu",
7047
7047
  "source": "src/components/Menu.tsx",
7048
7048
  "propsType": "MenuProps",
7049
- "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.",
7049
+ "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.",
7050
7050
  "import": "import { Menu } from 'ionbase-ui';",
7051
7051
  "status": "stable",
7052
- "summary": "The list surface only — no trigger, no anchor, no open state. Positioning it is the caller's job.",
7052
+ "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.",
7053
7053
  "useWhen": [
7054
- "rendering a list of actions or options as a surface you have already positioned",
7055
- "the rows need icons, a selected check, or two lines — more than a native <select> can hold"
7054
+ "a list of actions or choices for the thing the user is on — row actions, a workspace switcher, a sort order",
7055
+ "the rows need icons, a selected check, or grouping under headings — more than a native <select> can hold"
7056
7056
  ],
7057
7057
  "useInstead": [
7058
7058
  {
7059
- "when": "you want a self-contained dropdown with a trigger and open state",
7060
- "use": "Popover",
7061
- "why": "Menu is the surface alone; Popover owns the trigger, positioning, focus containment and Escape"
7059
+ "when": "a button opens it",
7060
+ "use": "MenuTrigger",
7061
+ "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"
7062
+ },
7063
+ {
7064
+ "when": "one value is picked for a form field from a modest list of plain text options",
7065
+ "use": "Select",
7066
+ "why": "a form value is a listbox, not a menu; the native picker brings type-ahead and the mobile platform picker for free"
7067
+ },
7068
+ {
7069
+ "when": "the user types to narrow a long list down to one value",
7070
+ "use": "Combobox"
7071
+ },
7072
+ {
7073
+ "when": "it is primary navigation rather than a list of actions",
7074
+ "use": "NavItem",
7075
+ "why": "a menu's rows are actions; links to pages belong in the document's navigation, where a screen reader's landmarks find them"
7076
+ },
7077
+ {
7078
+ "when": "any action or page should be reachable by searching",
7079
+ "use": "CommandPalette"
7080
+ }
7081
+ ],
7082
+ "composition": {
7083
+ "order": [
7084
+ "Menu",
7085
+ "MenuSection",
7086
+ "MenuItem"
7087
+ ],
7088
+ "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.",
7089
+ "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>"
7090
+ },
7091
+ "variants": {
7092
+ "selectionMode": {
7093
+ "none": {
7094
+ "use": "the default — a list of actions. Rows are `menuitem`, and there is no check slot"
7095
+ },
7096
+ "single": {
7097
+ "use": "Figma's Type=Single — one current choice, such as a sort order or the active workspace. Rows are `menuitemradio`"
7098
+ },
7099
+ "multiple": {
7100
+ "use": "Figma's Type=Multi — independent toggles, such as visible columns. Rows are `menuitemcheckbox`"
7101
+ }
7102
+ }
7103
+ },
7104
+ "slots": {
7105
+ "children": {
7106
+ "accepts": [
7107
+ "MenuItem",
7108
+ "MenuSection"
7109
+ ]
7110
+ }
7111
+ },
7112
+ "a11y": {
7113
+ "role": "menu",
7114
+ "guarantees": [
7115
+ "one tab stop; arrow keys move between rows, Home and End jump, and typing a letter moves to the next row starting with it",
7116
+ "disabled rows are listed and announced as unavailable, and the arrow keys skip them",
7117
+ "with a selection mode, rows are `menuitemradio` or `menuitemcheckbox` and announce `aria-checked` — the check glyph is never the only signal",
7118
+ "the pointer and the keyboard share one highlighted row: hovering a row focuses it"
7119
+ ],
7120
+ "requires": [
7121
+ "an accessible name — `aria-label` or `aria-labelledby` naming what the actions are for"
7122
+ ],
7123
+ "notes": [
7124
+ "A menu is not a form control. It has no `name` and submits nothing; `selectedKeys` is state you hold.",
7125
+ "Titled sections are named groups. An untitled section needs `aria-label`, and is set off by a rule.",
7126
+ "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."
7127
+ ]
7128
+ },
7129
+ "antiPatterns": [
7130
+ {
7131
+ "dont": "wrapping MenuItems in a <div>, a fragment or your own component inside Menu",
7132
+ "why": "Menu reads its collection from its direct children; a wrapped row is invisible to it and renders nothing"
7133
+ },
7134
+ {
7135
+ "dont": "an `onClick` on MenuItem",
7136
+ "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"
7137
+ },
7138
+ {
7139
+ "dont": "using Menu for a form field's value",
7140
+ "why": "a screen reader announces a menu as actions, and a form cannot read it. Use Select or Combobox"
7141
+ },
7142
+ {
7143
+ "dont": "putting links to other pages in a Menu",
7144
+ "why": "they vanish from the page's link list and landmarks. Navigation belongs in NavItem or Sidebar"
7145
+ }
7146
+ ],
7147
+ "stylesheet": "src/styles/menu.css",
7148
+ "tokens": [
7149
+ "--border-focus",
7150
+ "--border-strong",
7151
+ "--border-subtle",
7152
+ "--border-width-default",
7153
+ "--border-width-thick",
7154
+ "--font-family-sans",
7155
+ "--font-weight-regular",
7156
+ "--icon-default",
7157
+ "--icon-disabled",
7158
+ "--icon-primary",
7159
+ "--icon-size-sm",
7160
+ "--ion-duration-base",
7161
+ "--ion-ease-out",
7162
+ "--ion-menu-min-width",
7163
+ "--ion-shadow-shadow-lg",
7164
+ "--radius-sm",
7165
+ "--radius-xl",
7166
+ "--spacing-12",
7167
+ "--spacing-2",
7168
+ "--spacing-4",
7169
+ "--spacing-40",
7170
+ "--spacing-6",
7171
+ "--spacing-8",
7172
+ "--surface-default",
7173
+ "--surface-hover",
7174
+ "--surface-primary-subtle",
7175
+ "--text-disabled",
7176
+ "--text-primary",
7177
+ "--text-secondary",
7178
+ "--text-tertiary",
7179
+ "--type-body",
7180
+ "--type-body-line-height",
7181
+ "--type-caption",
7182
+ "--type-caption-line-height"
7183
+ ],
7184
+ "props": {
7185
+ "className": {
7186
+ "type": "string | undefined",
7187
+ "required": false,
7188
+ "origin": "own"
7189
+ },
7190
+ "style": {
7191
+ "type": "React.CSSProperties | undefined",
7192
+ "required": false,
7193
+ "origin": "own"
7194
+ },
7195
+ "escapeKeyBehavior": {
7196
+ "type": "\"none\" | \"clearSelection\" | undefined",
7197
+ "required": false,
7198
+ "origin": "aria",
7199
+ "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.",
7200
+ "values": [
7201
+ "none",
7202
+ "clearSelection"
7203
+ ],
7204
+ "tags": {
7205
+ "default": "'clearSelection'"
7206
+ }
7207
+ },
7208
+ "autoFocus": {
7209
+ "type": "boolean | FocusStrategy | undefined",
7210
+ "required": false,
7211
+ "origin": "aria",
7212
+ "description": "Where the focus should be set."
7213
+ },
7214
+ "shouldFocusWrap": {
7215
+ "type": "boolean | undefined",
7216
+ "required": false,
7217
+ "origin": "aria",
7218
+ "description": "Whether keyboard navigation is circular."
7219
+ },
7220
+ "onAction": {
7221
+ "type": "((key: Key, value: T) => void) | undefined",
7222
+ "required": false,
7223
+ "origin": "aria",
7224
+ "description": "Handler that is called when an item is selected."
7225
+ },
7226
+ "onClose": {
7227
+ "type": "(() => void) | undefined",
7228
+ "required": false,
7229
+ "origin": "aria",
7230
+ "description": "Handler that is called when the menu should close after selecting an item."
7231
+ },
7232
+ "children": {
7233
+ "type": "CollectionChildren<T>",
7234
+ "required": true,
7235
+ "origin": "aria",
7236
+ "description": "The contents of the collection."
7237
+ },
7238
+ "items": {
7239
+ "type": "Iterable<T> | undefined",
7240
+ "required": false,
7241
+ "origin": "aria",
7242
+ "description": "Item objects in the collection."
7243
+ },
7244
+ "disabledKeys": {
7245
+ "type": "Iterable<Key> | undefined",
7246
+ "required": false,
7247
+ "origin": "aria",
7248
+ "description": "The item keys that are disabled. These items cannot be selected, focused, or otherwise\ninteracted with."
7249
+ },
7250
+ "selectionMode": {
7251
+ "type": "SelectionMode | undefined",
7252
+ "required": false,
7253
+ "origin": "aria",
7254
+ "description": "The type of selection that is allowed in the collection.",
7255
+ "values": [
7256
+ "multiple",
7257
+ "none",
7258
+ "single"
7259
+ ]
7260
+ },
7261
+ "disallowEmptySelection": {
7262
+ "type": "boolean | undefined",
7263
+ "required": false,
7264
+ "origin": "aria",
7265
+ "description": "Whether the collection allows empty selection."
7266
+ },
7267
+ "selectedKeys": {
7268
+ "type": "Iterable<Key> | \"all\" | undefined",
7269
+ "required": false,
7270
+ "origin": "aria",
7271
+ "description": "The currently selected keys in the collection (controlled)."
7272
+ },
7273
+ "defaultSelectedKeys": {
7274
+ "type": "Iterable<Key> | \"all\" | undefined",
7275
+ "required": false,
7276
+ "origin": "aria",
7277
+ "description": "The initial selected keys in the collection (uncontrolled)."
7278
+ },
7279
+ "onSelectionChange": {
7280
+ "type": "((keys: Selection) => void) | undefined",
7281
+ "required": false,
7282
+ "origin": "aria",
7283
+ "description": "Handler that is called when the selection changes."
7284
+ },
7285
+ "id": {
7286
+ "type": "string | undefined",
7287
+ "required": false,
7288
+ "origin": "aria",
7289
+ "description": "The element's unique identifier. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)."
7290
+ },
7291
+ "aria-label": {
7292
+ "type": "string | undefined",
7293
+ "required": false,
7294
+ "origin": "aria",
7295
+ "description": "Defines a string value that labels the current element."
7296
+ },
7297
+ "aria-labelledby": {
7298
+ "type": "string | undefined",
7299
+ "required": false,
7300
+ "origin": "aria",
7301
+ "description": "Identifies the element (or elements) that labels the current element."
7302
+ },
7303
+ "aria-describedby": {
7304
+ "type": "string | undefined",
7305
+ "required": false,
7306
+ "origin": "aria",
7307
+ "description": "Identifies the element (or elements) that describes the object."
7308
+ },
7309
+ "aria-details": {
7310
+ "type": "string | undefined",
7311
+ "required": false,
7312
+ "origin": "aria",
7313
+ "description": "Identifies the element (or elements) that provide a detailed, extended description for the\nobject."
7314
+ }
7315
+ },
7316
+ "propCounts": {
7317
+ "own": 2,
7318
+ "aria": 18,
7319
+ "dom": 0,
7320
+ "other": 0
7321
+ }
7322
+ },
7323
+ "MenuItem": {
7324
+ "name": "MenuItem",
7325
+ "source": "src/components/Menu.tsx",
7326
+ "propsType": "MenuItemProps",
7327
+ "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.",
7328
+ "import": "import { MenuItem } from 'ionbase-ui';",
7329
+ "status": "stable",
7330
+ "summary": "One row of a Menu. A collection element: Menu reads its props and draws the row as `menuitem`, `menuitemradio` or `menuitemcheckbox`.",
7331
+ "useWhen": [
7332
+ "a row in a Menu or a MenuSection — it is not usable anywhere else"
7333
+ ],
7334
+ "useInstead": [
7335
+ {
7336
+ "when": "it is a top-level navigation destination",
7337
+ "use": "NavItem"
7338
+ },
7339
+ {
7340
+ "when": "it is a standalone action outside a list",
7341
+ "use": "Button"
7342
+ }
7343
+ ],
7344
+ "composition": {
7345
+ "order": [
7346
+ "Menu",
7347
+ "MenuItem"
7348
+ ],
7349
+ "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`.",
7350
+ "example": "<MenuItem key=\"duplicate\" icon={<Icon as={Copy} />}>Duplicate</MenuItem>\n<MenuItem key=\"move\" title=\"Move to\"><MenuItem key=\"archive\">Archive</MenuItem></MenuItem>"
7351
+ },
7352
+ "slots": {
7353
+ "icon": {
7354
+ "accepts": "Icon",
7355
+ "note": "leading icon; omit its `label` — the row's text names it"
7356
+ },
7357
+ "children": {
7358
+ "accepts": "text",
7359
+ "note": "the row label"
7360
+ },
7361
+ "title": {
7362
+ "accepts": "text",
7363
+ "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"
7364
+ }
7365
+ },
7366
+ "a11y": {
7367
+ "guarantees": [
7368
+ "the role, `aria-checked` and `aria-disabled` are supplied by Menu from its selection mode and keys, not by this element",
7369
+ "the check glyph occupies its slot whenever the menu has a selection mode, so rows never reflow as the selection moves"
7370
+ ],
7371
+ "requires": [
7372
+ "a stable `key`",
7373
+ "text in `children`, or `textValue` when the children are not plain text — typeahead matches against it"
7374
+ ]
7375
+ },
7376
+ "antiPatterns": [
7377
+ {
7378
+ "dont": "using MenuItem outside a Menu",
7379
+ "why": "it renders nothing on its own"
7380
+ },
7381
+ {
7382
+ "dont": "an icon-only MenuItem with no children",
7383
+ "why": "the row announces nothing and typeahead cannot reach it"
7384
+ },
7385
+ {
7386
+ "dont": "array indexes as keys in a list that can change",
7387
+ "why": "selection and actions are expressed in keys, so the selected row silently becomes a different row"
7388
+ }
7389
+ ],
7390
+ "deprecated": [
7391
+ {
7392
+ "prop": "disabled",
7393
+ "replacement": "isDisabled"
7394
+ },
7395
+ {
7396
+ "prop": "isSelected",
7397
+ "note": "Put the item's key in Menu's `selectedKeys` and set its `selectionMode`."
7398
+ }
7399
+ ],
7400
+ "stylesheet": "src/styles/menu.css",
7401
+ "tokens": [
7402
+ "--border-focus",
7403
+ "--border-strong",
7404
+ "--border-subtle",
7405
+ "--border-width-default",
7406
+ "--border-width-thick",
7407
+ "--font-family-sans",
7408
+ "--font-weight-regular",
7409
+ "--icon-default",
7410
+ "--icon-disabled",
7411
+ "--icon-primary",
7412
+ "--icon-size-sm",
7413
+ "--ion-duration-base",
7414
+ "--ion-ease-out",
7415
+ "--ion-menu-min-width",
7416
+ "--ion-shadow-shadow-lg",
7417
+ "--radius-sm",
7418
+ "--radius-xl",
7419
+ "--spacing-12",
7420
+ "--spacing-2",
7421
+ "--spacing-4",
7422
+ "--spacing-40",
7423
+ "--spacing-6",
7424
+ "--spacing-8",
7425
+ "--surface-default",
7426
+ "--surface-hover",
7427
+ "--surface-primary-subtle",
7428
+ "--text-disabled",
7429
+ "--text-primary",
7430
+ "--text-secondary",
7431
+ "--text-tertiary",
7432
+ "--type-body",
7433
+ "--type-body-line-height",
7434
+ "--type-caption",
7435
+ "--type-caption-line-height"
7436
+ ],
7437
+ "props": {
7438
+ "title": {
7439
+ "type": "React.ReactNode",
7440
+ "required": false,
7441
+ "origin": "own",
7442
+ "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."
7443
+ },
7444
+ "icon": {
7445
+ "type": "React.ReactNode",
7446
+ "required": false,
7447
+ "origin": "own",
7448
+ "description": "Figma's `Show Leading Icon` + `Leading Icon` swap."
7449
+ },
7450
+ "isDisabled": {
7451
+ "type": "boolean | undefined",
7452
+ "required": false,
7453
+ "origin": "own",
7454
+ "description": "Whether the item is disabled. Listed, skipped by the arrow keys."
7455
+ },
7456
+ "disabled": {
7457
+ "type": "boolean | undefined",
7458
+ "required": false,
7459
+ "origin": "own",
7460
+ "tags": {
7461
+ "deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
7462
+ }
7463
+ },
7464
+ "isSelected": {
7465
+ "type": "boolean | undefined",
7466
+ "required": false,
7467
+ "origin": "own",
7468
+ "tags": {
7469
+ "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."
7470
+ }
7471
+ },
7472
+ "children": {
7473
+ "type": "ReactNode",
7474
+ "required": true,
7475
+ "origin": "aria",
7476
+ "description": "Rendered contents of the item or child items."
7477
+ },
7478
+ "textValue": {
7479
+ "type": "string | undefined",
7480
+ "required": false,
7481
+ "origin": "aria",
7482
+ "description": "A string representation of the item's contents, used for features like typeahead."
7483
+ },
7484
+ "aria-label": {
7485
+ "type": "string | undefined",
7486
+ "required": false,
7487
+ "origin": "aria",
7488
+ "description": "An accessibility label for this item."
7489
+ },
7490
+ "childItems": {
7491
+ "type": "Iterable<T> | undefined",
7492
+ "required": false,
7493
+ "origin": "aria",
7494
+ "description": "A list of child item objects. Used for dynamic collections."
7495
+ },
7496
+ "hasChildItems": {
7497
+ "type": "boolean | undefined",
7498
+ "required": false,
7499
+ "origin": "aria",
7500
+ "description": "Whether this item has children, even if not loaded yet."
7501
+ },
7502
+ "href": {
7503
+ "type": "string | undefined",
7504
+ "required": false,
7505
+ "origin": "aria",
7506
+ "description": "A URL to link to. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#href)."
7507
+ },
7508
+ "hrefLang": {
7509
+ "type": "string | undefined",
7510
+ "required": false,
7511
+ "origin": "aria",
7512
+ "description": "Hints at the human language of the linked URL.\nSee[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#hreflang)."
7513
+ },
7514
+ "target": {
7515
+ "type": "HTMLAttributeAnchorTarget | undefined",
7516
+ "required": false,
7517
+ "origin": "aria",
7518
+ "description": "The target window for the link. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target)."
7519
+ },
7520
+ "rel": {
7521
+ "type": "string | undefined",
7522
+ "required": false,
7523
+ "origin": "aria",
7524
+ "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)."
7525
+ },
7526
+ "download": {
7527
+ "type": "string | boolean | undefined",
7528
+ "required": false,
7529
+ "origin": "aria",
7530
+ "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)."
7531
+ },
7532
+ "ping": {
7533
+ "type": "string | undefined",
7534
+ "required": false,
7535
+ "origin": "aria",
7536
+ "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)."
7062
7537
  },
7063
- {
7064
- "when": "one value is picked from a modest list of plain text options",
7065
- "use": "Select",
7066
- "why": "the native picker brings keyboard handling, type-ahead and the mobile platform picker for free"
7538
+ "referrerPolicy": {
7539
+ "type": "HTMLAttributeReferrerPolicy | undefined",
7540
+ "required": false,
7541
+ "origin": "aria",
7542
+ "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).",
7543
+ "values": [
7544
+ "",
7545
+ "origin",
7546
+ "no-referrer",
7547
+ "no-referrer-when-downgrade",
7548
+ "origin-when-cross-origin",
7549
+ "same-origin",
7550
+ "strict-origin",
7551
+ "strict-origin-when-cross-origin",
7552
+ "unsafe-url"
7553
+ ]
7067
7554
  },
7555
+ "routerOptions": {
7556
+ "type": "undefined",
7557
+ "required": false,
7558
+ "origin": "aria",
7559
+ "description": "Options for the configured client side router."
7560
+ }
7561
+ },
7562
+ "propCounts": {
7563
+ "own": 5,
7564
+ "aria": 13,
7565
+ "dom": 0,
7566
+ "other": 0
7567
+ }
7568
+ },
7569
+ "MenuSection": {
7570
+ "name": "MenuSection",
7571
+ "source": "../../node_modules/.pnpm/react-stately@3.48.0_react@19.2.8/node_modules/react-stately/dist/types/src/collections/Section.d.ts",
7572
+ "propsType": null,
7573
+ "import": "import { MenuSection } from 'ionbase-ui';",
7574
+ "status": "stable",
7575
+ "summary": "A named group of MenuItems. Re-exported from react-stately's collection Section — `title` is Figma's Menu Section Title.",
7576
+ "useWhen": [
7577
+ "a Menu has more than one kind of action, such as editing actions and destructive ones",
7578
+ "the rows fall into groups the user scans by name"
7579
+ ],
7580
+ "useInstead": [
7068
7581
  {
7069
- "when": "it is primary navigation rather than a dropdown",
7070
- "use": "NavItem"
7582
+ "when": "the menu has one group",
7583
+ "use": "MenuItem",
7584
+ "why": "a single section adds a heading the user must hear before every menu, and says nothing the menu's own label does not"
7071
7585
  }
7072
7586
  ],
7073
7587
  "composition": {
7074
7588
  "order": [
7075
7589
  "Menu",
7590
+ "MenuSection",
7076
7591
  "MenuItem"
7077
7592
  ],
7078
- "example": "<Menu><MenuItem icon={<Icon as={Copy} />}>Duplicate</MenuItem><MenuItem isSelected>Archive</MenuItem></Menu>"
7079
- },
7080
- "slots": {
7081
- "children": {
7082
- "accepts": "MenuItem"
7083
- }
7593
+ "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.",
7594
+ "example": "<MenuSection title=\"Sort by\"><MenuItem key=\"name\">Name</MenuItem><MenuItem key=\"updated\">Last updated</MenuItem></MenuSection>"
7084
7595
  },
7085
7596
  "a11y": {
7086
- "role": "none — it is a plain <ul>",
7597
+ "role": "group",
7087
7598
  "guarantees": [
7088
- "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"
7599
+ "the group is named by its title, so a screen reader announces it on entering the first row"
7600
+ ],
7601
+ "requires": [
7602
+ "a `title`; an untitled section still needs a label for the group, or it is announced as an unnamed group"
7089
7603
  ],
7090
7604
  "notes": [
7091
- "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.",
7092
- "The role arrives when the popover that owns it does."
7605
+ "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."
7093
7606
  ]
7094
7607
  },
7095
7608
  "antiPatterns": [
7096
7609
  {
7097
- "dont": "adding `role=\"menu\"` yourself",
7098
- "why": "the keyboard behaviour that role promises is not implemented; an honest list is better for a screen-reader user than a lying menu"
7099
- },
7100
- {
7101
- "dont": "using Menu as a dropdown without positioning it",
7102
- "why": "it renders in flow — it has no anchor logic of its own"
7610
+ "dont": "nesting a MenuSection inside another",
7611
+ "why": "a menu has one level of grouping; a section inside a section renders nothing"
7103
7612
  }
7104
7613
  ],
7105
7614
  "stylesheet": "src/styles/menu.css",
7106
7615
  "tokens": [
7107
7616
  "--border-focus",
7617
+ "--border-strong",
7108
7618
  "--border-subtle",
7109
7619
  "--border-width-default",
7110
7620
  "--border-width-thick",
@@ -7116,10 +7626,13 @@
7116
7626
  "--icon-size-sm",
7117
7627
  "--ion-duration-base",
7118
7628
  "--ion-ease-out",
7629
+ "--ion-menu-min-width",
7630
+ "--ion-shadow-shadow-lg",
7119
7631
  "--radius-sm",
7120
7632
  "--radius-xl",
7121
7633
  "--spacing-12",
7122
7634
  "--spacing-2",
7635
+ "--spacing-4",
7123
7636
  "--spacing-40",
7124
7637
  "--spacing-6",
7125
7638
  "--spacing-8",
@@ -7129,82 +7642,116 @@
7129
7642
  "--text-disabled",
7130
7643
  "--text-primary",
7131
7644
  "--text-secondary",
7645
+ "--text-tertiary",
7132
7646
  "--type-body",
7133
- "--type-body-line-height"
7647
+ "--type-body-line-height",
7648
+ "--type-caption",
7649
+ "--type-caption-line-height"
7134
7650
  ],
7135
- "props": {
7136
- "children": {
7137
- "type": "React.ReactNode",
7138
- "required": false,
7139
- "origin": "own"
7140
- }
7141
- },
7651
+ "props": {},
7142
7652
  "propCounts": {
7143
- "own": 1,
7653
+ "own": 0,
7144
7654
  "aria": 0,
7145
- "dom": 277,
7655
+ "dom": 0,
7146
7656
  "other": 0
7147
7657
  }
7148
7658
  },
7149
- "MenuItem": {
7150
- "name": "MenuItem",
7659
+ "MenuTrigger": {
7660
+ "name": "MenuTrigger",
7151
7661
  "source": "src/components/Menu.tsx",
7152
- "propsType": "MenuItemProps",
7153
- "import": "import { MenuItem } from 'ionbase-ui';",
7662
+ "propsType": "MenuTriggerProps",
7663
+ "description": "MenuTrigger — a Button that opens a Menu.\n\nThe \"⋯\" overflow menu is this with an icon-only Button; there is no separate\ncomponent for it, because the only difference is the Button's content and\nits required aria-label.\n\n`useMenuTrigger` does what a Popover wrapped round a Menu could not: the\ntrigger announces `aria-haspopup=\"menu\"` and `aria-expanded`, the menu is\nnamed by the trigger, ArrowDown and ArrowUp open it with focus on the first\nor last row, and choosing an action closes it and returns focus to the\ntrigger.",
7664
+ "import": "import { MenuTrigger } from 'ionbase-ui';",
7154
7665
  "status": "stable",
7155
- "summary": "One row in a Menu. A real <button> inside an <li>, with an optional leading icon and a trailing selected check.",
7666
+ "summary": "A Button that opens a Menu. The \"⋯\" overflow menu is this with an icon-only Button. Owns open state, positioning, focus, and the ARIA link between the two.",
7156
7667
  "useWhen": [
7157
- "a row in a Menu surface"
7668
+ "a button opens a list of actions — row actions, an overflow \"⋯\", a \"New\" button with several kinds of new",
7669
+ "a button opens a list of choices applied immediately, such as a sort order",
7670
+ "the actions nest one level or more — submenus open only inside a MenuTrigger"
7158
7671
  ],
7159
7672
  "useInstead": [
7160
7673
  {
7161
- "when": "it is a top-level navigation destination",
7162
- "use": "NavItem"
7674
+ "when": "the button opens a form, a filter panel or anything that is not a list of rows",
7675
+ "use": "Popover",
7676
+ "why": "a menu promises arrow keys between rows and nothing else; a field inside it cannot be reached"
7163
7677
  },
7164
7678
  {
7165
- "when": "it is a standalone action outside a list",
7166
- "use": "Button"
7679
+ "when": "the choice is a form field's value",
7680
+ "use": "Select",
7681
+ "why": "a form value is a listbox the form can read, not a menu of actions"
7682
+ },
7683
+ {
7684
+ "when": "there are only two or three actions and room to show them",
7685
+ "use": "Button",
7686
+ "why": "hiding actions behind a menu costs a click and makes them undiscoverable; show them when they fit"
7167
7687
  }
7168
7688
  ],
7689
+ "composition": {
7690
+ "order": [
7691
+ "MenuTrigger",
7692
+ "Button",
7693
+ "Menu"
7694
+ ],
7695
+ "note": "Exactly two children, in this order: the Button, then the Menu. The Menu is named by the Button unless it has its own aria-label. A MenuItem with a `title` and MenuItem children opens a submenu; `onAction` on the root Menu receives actions from every level.",
7696
+ "example": "<MenuTrigger><Button variant=\"tertiary\" aria-label=\"Actions for Payroll\" startIcon={<Icon as={Ellipsis} />} /><Menu onAction={(key) => run(key)}><MenuItem key=\"rename\">Rename</MenuItem><MenuItem key=\"move\" title=\"Move to\"><MenuItem key=\"archive\">Archive</MenuItem><MenuItem key=\"trash\">Trash</MenuItem></MenuItem></Menu></MenuTrigger>"
7697
+ },
7698
+ "variants": {
7699
+ "placement": {
7700
+ "bottom start": {
7701
+ "use": "the default — below, aligned to the trigger's start edge"
7702
+ },
7703
+ "bottom end": {
7704
+ "use": "a trigger at the end of a row or toolbar, so the menu does not run off the edge"
7705
+ },
7706
+ "top start": {
7707
+ "use": "a trigger near the bottom of the viewport, such as a footer"
7708
+ },
7709
+ "top end": {
7710
+ "use": "as top start, for a trigger at the end of its row"
7711
+ }
7712
+ }
7713
+ },
7169
7714
  "slots": {
7170
- "icon": {
7171
- "accepts": "Icon",
7172
- "note": "leading icon; omit its `label` — the row's text names it"
7173
- },
7174
7715
  "children": {
7175
- "accepts": "text",
7176
- "note": "the row label"
7716
+ "accepts": [
7717
+ "Button",
7718
+ "Menu"
7719
+ ],
7720
+ "note": "the Button first, the Menu second"
7177
7721
  }
7178
7722
  },
7179
7723
  "a11y": {
7180
- "role": "button",
7724
+ "role": "none — the Button gets aria-haspopup=\"menu\" and aria-expanded; the Menu is the menu",
7725
+ "namesChild": true,
7181
7726
  "guarantees": [
7182
- "`isSelected` sets `aria-pressed`, so the selected state is announced and not only drawn",
7183
- "the check glyph always occupies its slot, so rows never reflow as the selection moves"
7727
+ "Enter, Space and ArrowDown open the menu with focus on its first row; ArrowUp opens it on the last",
7728
+ "choosing an action closes every open level and returns focus to the trigger; so do Escape and an outside click",
7729
+ "the menu is named by the trigger unless it has its own aria-label",
7730
+ "a submenu opens with the right arrow, Enter or Space and closes with the left arrow or Escape, which puts focus back on the row that opened it",
7731
+ "submenus are non-modal: the parent menu stays on screen and hoverable, so the pointer can move between levels"
7184
7732
  ],
7185
7733
  "requires": [
7186
- "a text label in `children`"
7734
+ "an icon-only trigger Button needs its own aria-label — it names the menu too"
7187
7735
  ]
7188
7736
  },
7189
7737
  "antiPatterns": [
7190
7738
  {
7191
- "dont": "using MenuItem outside a Menu",
7192
- "why": "it renders an <li>, which is only valid inside a list"
7739
+ "dont": "wrapping a Menu in a Popover to make a dropdown",
7740
+ "why": "the trigger then announces a dialog, not a menu, the arrow keys cannot open it, and choosing an action does not close it. That is exactly what MenuTrigger exists to replace"
7193
7741
  },
7194
7742
  {
7195
- "dont": "an icon-only MenuItem with no children",
7196
- "why": "the row announces nothing"
7197
- }
7198
- ],
7199
- "deprecated": [
7743
+ "dont": "a plain <button> as the trigger",
7744
+ "why": "the trigger must accept react-aria press props and a ref; IonBase's Button does, a DOM button silently never opens"
7745
+ },
7200
7746
  {
7201
- "prop": "disabled",
7202
- "replacement": "isDisabled"
7747
+ "dont": "more than two levels of submenu",
7748
+ "why": "each level is a hover target narrower than the last; past two, the pointer falls off the path and the menu closes. Flatten with sections instead"
7203
7749
  }
7204
7750
  ],
7205
7751
  "stylesheet": "src/styles/menu.css",
7206
7752
  "tokens": [
7207
7753
  "--border-focus",
7754
+ "--border-strong",
7208
7755
  "--border-subtle",
7209
7756
  "--border-width-default",
7210
7757
  "--border-width-thick",
@@ -7216,10 +7763,13 @@
7216
7763
  "--icon-size-sm",
7217
7764
  "--ion-duration-base",
7218
7765
  "--ion-ease-out",
7766
+ "--ion-menu-min-width",
7767
+ "--ion-shadow-shadow-lg",
7219
7768
  "--radius-sm",
7220
7769
  "--radius-xl",
7221
7770
  "--spacing-12",
7222
7771
  "--spacing-2",
7772
+ "--spacing-4",
7223
7773
  "--spacing-40",
7224
7774
  "--spacing-6",
7225
7775
  "--spacing-8",
@@ -7229,46 +7779,57 @@
7229
7779
  "--text-disabled",
7230
7780
  "--text-primary",
7231
7781
  "--text-secondary",
7782
+ "--text-tertiary",
7232
7783
  "--type-body",
7233
- "--type-body-line-height"
7784
+ "--type-body-line-height",
7785
+ "--type-caption",
7786
+ "--type-caption-line-height"
7234
7787
  ],
7235
7788
  "props": {
7236
- "isSelected": {
7237
- "type": "boolean | undefined",
7238
- "required": false,
7789
+ "children": {
7790
+ "type": "[React.ReactElement<unknown, string | React.JSXElementConstructor<any>>, React.ReactElement<unknown, string | React.JSXElementConstructor<any>>]",
7791
+ "required": true,
7239
7792
  "origin": "own",
7240
- "description": "Figma's `Selected` / `Selected-hover` states. Shows the trailing check."
7793
+ "description": "Exactly two children: the Button that opens the menu, then the Menu. The\nButton must accept a ref and react-aria press props — IonBase's Button\ndoes; a plain `<button>` does not."
7241
7794
  },
7242
- "icon": {
7243
- "type": "React.ReactNode",
7795
+ "placement": {
7796
+ "type": "MenuTriggerPlacement | undefined",
7244
7797
  "required": false,
7245
7798
  "origin": "own",
7246
- "description": "Figma's `Show Leading Icon` + `Leading Icon` swap."
7799
+ "description": "Where the menu opens, relative to the trigger. A preference, not a\nguarantee: it flips when there is no room.",
7800
+ "values": [
7801
+ "bottom start",
7802
+ "bottom end",
7803
+ "top start",
7804
+ "top end"
7805
+ ]
7247
7806
  },
7248
7807
  "isDisabled": {
7249
7808
  "type": "boolean | undefined",
7250
7809
  "required": false,
7251
7810
  "origin": "own",
7252
- "description": "Whether the item is disabled."
7811
+ "description": "Whether the trigger is disabled."
7253
7812
  },
7254
- "disabled": {
7813
+ "isOpen": {
7255
7814
  "type": "boolean | undefined",
7256
7815
  "required": false,
7257
- "origin": "own",
7258
- "tags": {
7259
- "deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
7260
- }
7816
+ "origin": "own"
7261
7817
  },
7262
- "children": {
7263
- "type": "React.ReactNode",
7818
+ "defaultOpen": {
7819
+ "type": "boolean | undefined",
7820
+ "required": false,
7821
+ "origin": "own"
7822
+ },
7823
+ "onOpenChange": {
7824
+ "type": "((isOpen: boolean) => void) | undefined",
7264
7825
  "required": false,
7265
7826
  "origin": "own"
7266
7827
  }
7267
7828
  },
7268
7829
  "propCounts": {
7269
- "own": 5,
7830
+ "own": 6,
7270
7831
  "aria": 0,
7271
- "dom": 285,
7832
+ "dom": 0,
7272
7833
  "other": 0
7273
7834
  }
7274
7835
  },
@@ -8063,6 +8624,175 @@
8063
8624
  "other": 2
8064
8625
  }
8065
8626
  },
8627
+ "PageHeader": {
8628
+ "name": "PageHeader",
8629
+ "source": "src/components/PageHeader.tsx",
8630
+ "propsType": "PageHeaderProps",
8631
+ "description": "PageHeader — the top of a page: where you are, what it is, and what you can\ndo to it.\n\nPromoted from the demo app, where five screens hand-wrote it in three\ndifferent shapes (`.demo-page__header`, `.demo-run-header`, and a bare\n`<div>`), each with its own gap and its own idea of where the actions\naligned. Every enterprise system ships one — Carbon's PageHeader,\nLightning's page headers — because every page has one.\n\nNOT A LANDMARK\n\nIt renders a `<div>`, not a `<header>`. A `<header>` that is a child of\n`<body>` is the page's banner, and the app shell's Header already is that.\nThe page's landmark is `<main>`, named by this title: pass `titleId` and\npoint `<main aria-labelledby>` at it.\n\nNo `'use client'`: `useId` resolves on the server, and nothing here is\ninteractive. Interactive parts arrive through the slots.",
8632
+ "import": "import { PageHeader } from 'ionbase-ui';",
8633
+ "status": "stable",
8634
+ "summary": "The top of a page: breadcrumb, the page's h1, a description, the record's status, and the page's actions. Not a landmark — main is, named by this title.",
8635
+ "useWhen": [
8636
+ "the top of every page inside the app shell — list pages, record pages, settings, wizards",
8637
+ "the page has a title and actions that act on the whole page, such as New agent or Pause"
8638
+ ],
8639
+ "useInstead": [
8640
+ {
8641
+ "when": "it is the bar across the top of the whole app, with the logo and the account menu",
8642
+ "use": "Header",
8643
+ "why": "Header is the banner landmark, rendered once by the shell. PageHeader is inside main and changes with each page"
8644
+ },
8645
+ {
8646
+ "when": "it titles one section of a page rather than the page",
8647
+ "use": "Card",
8648
+ "why": "a Card's title is an h2 for a named region; a page has one PageHeader and one h1"
8649
+ },
8650
+ {
8651
+ "when": "the page is empty or failed to load",
8652
+ "use": "EmptyState",
8653
+ "why": "keep the PageHeader so the user still knows where they are, and put the EmptyState beneath it with headingLevel 2"
8654
+ }
8655
+ ],
8656
+ "composition": {
8657
+ "order": [
8658
+ "PageHeader",
8659
+ "Breadcrumb",
8660
+ "Badge",
8661
+ "Button",
8662
+ "MenuTrigger",
8663
+ "Tabs"
8664
+ ],
8665
+ "note": "Slots, not children: `breadcrumb` above, `status` beside the title, `actions` at the end of the title row, and `children` as a row beneath for the page's Tabs or filters. Pass `titleId` and point `<main aria-labelledby>` at it.",
8666
+ "example": "<main aria-labelledby=\"page-title\"><PageHeader titleId=\"page-title\" title=\"Payroll reconciler\" description=\"Matches payroll exports against the ledger every night.\" breadcrumb={<Breadcrumb><BreadcrumbItem href=\"/agents\">Agents</BreadcrumbItem><BreadcrumbItem isCurrent>Payroll reconciler</BreadcrumbItem></Breadcrumb>} status={<Badge intent=\"warning\">Paused</Badge>} actions={<><MenuTrigger><Button variant=\"tertiary\" aria-label=\"More actions\" startIcon={<Icon as={Ellipsis} />} /><Menu onAction={run}><MenuItem key=\"delete\">Delete…</MenuItem></Menu></MenuTrigger><Button variant=\"primary-brand\">Resume</Button></>} /></main>"
8667
+ },
8668
+ "slots": {
8669
+ "breadcrumb": {
8670
+ "accepts": "Breadcrumb"
8671
+ },
8672
+ "status": {
8673
+ "accepts": [
8674
+ "Badge",
8675
+ "Tag"
8676
+ ],
8677
+ "note": "the record's state. Never an action, and never colour alone — a Badge carries its label"
8678
+ },
8679
+ "actions": {
8680
+ "accepts": [
8681
+ "Button",
8682
+ "MenuTrigger",
8683
+ "Link"
8684
+ ],
8685
+ "note": "most important last, so the primary action sits at the end of the row. One primary Button at most; beyond two or three actions, put the rest in a MenuTrigger"
8686
+ },
8687
+ "children": {
8688
+ "accepts": [
8689
+ "Tabs",
8690
+ "SegmentedControl"
8691
+ ],
8692
+ "note": "a row that belongs to the header: the page's own tabs, or the filters its table answers to"
8693
+ }
8694
+ },
8695
+ "a11y": {
8696
+ "role": "none — a <div>. The page's landmark is <main>, named by this title",
8697
+ "guarantees": [
8698
+ "the title is a real heading, h1 by default, with a stable id for aria-labelledby",
8699
+ "actions keep their DOM order when they wrap beneath the title on a narrow screen, so reading order matches visual order"
8700
+ ],
8701
+ "notes": [
8702
+ "`headingLevel` is 1 by default. Use 2 only for a header on a pane that is not the page — the detail half of a list-detail layout, under the list's h1.",
8703
+ "It is deliberately not a <header>: a <header> directly inside <body> is the banner, and the app shell's Header already is that."
8704
+ ]
8705
+ },
8706
+ "antiPatterns": [
8707
+ {
8708
+ "dont": "two PageHeaders on one page",
8709
+ "why": "two h1s, and two answers to where am I. Sections below the header are Cards with h2 titles"
8710
+ },
8711
+ {
8712
+ "dont": "dropping the PageHeader while the page loads or fails",
8713
+ "why": "the user loses where they are exactly when something went wrong. Keep the title; put Skeleton or EmptyState beneath it"
8714
+ },
8715
+ {
8716
+ "dont": "putting filters or a search field in `actions`",
8717
+ "why": "actions act on the page; filters narrow what it shows. Filters go in `children`, the row beneath"
8718
+ },
8719
+ {
8720
+ "dont": "several primary Buttons in `actions`",
8721
+ "why": "a page has one next step. The one-primary-action lint rule counts them"
8722
+ }
8723
+ ],
8724
+ "stylesheet": "src/styles/page-header.css",
8725
+ "tokens": [
8726
+ "--font-family-sans",
8727
+ "--font-weight-semibold",
8728
+ "--ion-page-header-heading-basis",
8729
+ "--spacing-16",
8730
+ "--spacing-4",
8731
+ "--spacing-8",
8732
+ "--text-default",
8733
+ "--text-secondary",
8734
+ "--type-body",
8735
+ "--type-body-line-height",
8736
+ "--type-h4",
8737
+ "--type-h4-line-height"
8738
+ ],
8739
+ "props": {
8740
+ "title": {
8741
+ "type": "React.ReactNode",
8742
+ "required": true,
8743
+ "origin": "own",
8744
+ "description": "The page's title. Rendered as the `h1`."
8745
+ },
8746
+ "titleId": {
8747
+ "type": "string | undefined",
8748
+ "required": false,
8749
+ "origin": "own",
8750
+ "description": "The title's id. Pass it when something else points at the heading —\n`<main aria-labelledby>` is the usual one. Generated when omitted."
8751
+ },
8752
+ "headingLevel": {
8753
+ "type": "PageHeaderHeadingLevel | undefined",
8754
+ "required": false,
8755
+ "origin": "own",
8756
+ "description": "Heading element for the title. Defaults to `1`."
8757
+ },
8758
+ "description": {
8759
+ "type": "React.ReactNode",
8760
+ "required": false,
8761
+ "origin": "own",
8762
+ "description": "One or two sentences under the title: what this page is for."
8763
+ },
8764
+ "breadcrumb": {
8765
+ "type": "React.ReactNode",
8766
+ "required": false,
8767
+ "origin": "own",
8768
+ "description": "A Breadcrumb, above the title."
8769
+ },
8770
+ "status": {
8771
+ "type": "React.ReactNode",
8772
+ "required": false,
8773
+ "origin": "own",
8774
+ "description": "Beside the title: a Badge or two for the record's state — \"Paused\",\n\"Draft\". State, not actions."
8775
+ },
8776
+ "actions": {
8777
+ "type": "React.ReactNode",
8778
+ "required": false,
8779
+ "origin": "own",
8780
+ "description": "At the end of the title row: the page's actions, most important last.\nOne primary Button at most; several more go in a MenuTrigger."
8781
+ },
8782
+ "children": {
8783
+ "type": "React.ReactNode",
8784
+ "required": false,
8785
+ "origin": "own",
8786
+ "description": "A row beneath, that belongs to the header rather than the page's\ncontent: the page's Tabs, or the filters its table answers to."
8787
+ }
8788
+ },
8789
+ "propCounts": {
8790
+ "own": 8,
8791
+ "aria": 0,
8792
+ "dom": 276,
8793
+ "other": 0
8794
+ }
8795
+ },
8066
8796
  "Pagination": {
8067
8797
  "name": "Pagination",
8068
8798
  "source": "src/components/Pagination.tsx",