@capra/core 1.5.3 → 1.7.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 (104) hide show
  1. package/dist/index.cjs +42 -78
  2. package/dist/index.d.cts +8 -2
  3. package/dist/index.d.mts +8 -2
  4. package/dist/index.mjs +42 -78
  5. package/dist/style.css +62 -32
  6. package/docs/conventions--docs.md +186 -0
  7. package/docs/core-alert--design.md +110 -0
  8. package/docs/core-alert--usage.md +13 -0
  9. package/docs/core-anchor--design.md +39 -0
  10. package/docs/core-anchor--usage.md +39 -0
  11. package/docs/core-autocompletefield--design.md +91 -0
  12. package/docs/core-autocompletefield--usage.md +18 -0
  13. package/docs/core-badge--design.md +70 -0
  14. package/docs/core-badge--usage.md +13 -0
  15. package/docs/core-breadcrumbs--design.md +65 -0
  16. package/docs/core-breadcrumbs--usage.md +16 -0
  17. package/docs/core-button--design.md +97 -0
  18. package/docs/core-button--usage.md +17 -0
  19. package/docs/core-buttonlink--design.md +7 -0
  20. package/docs/core-buttonlink--usage.md +24 -0
  21. package/docs/core-card--design.md +100 -0
  22. package/docs/core-card--usage.md +5 -0
  23. package/docs/core-checkbox--design.md +66 -0
  24. package/docs/core-checkbox--usage.md +34 -0
  25. package/docs/core-collapse--design.md +28 -0
  26. package/docs/core-collapse--usage.md +20 -0
  27. package/docs/core-datepickerfield--design.md +71 -0
  28. package/docs/core-datepickerfield--usage.md +57 -0
  29. package/docs/core-daterangepickerfield--design.md +76 -0
  30. package/docs/core-daterangepickerfield--usage.md +62 -0
  31. package/docs/core-divider--design.md +35 -0
  32. package/docs/core-divider--usage.md +8 -0
  33. package/docs/core-drawer--design.md +87 -0
  34. package/docs/core-drawer--usage.md +9 -0
  35. package/docs/core-emptystate--design.md +45 -0
  36. package/docs/core-emptystate--usage.md +13 -0
  37. package/docs/core-helpertext--design.md +30 -0
  38. package/docs/core-helpertext--usage.md +11 -0
  39. package/docs/core-iconbutton--design.md +87 -0
  40. package/docs/core-iconbutton--usage.md +15 -0
  41. package/docs/core-inputrow--design.md +85 -0
  42. package/docs/core-inputrow--usage.md +6 -0
  43. package/docs/core-label--design.md +27 -0
  44. package/docs/core-label--usage.md +17 -0
  45. package/docs/core-link--design.md +58 -0
  46. package/docs/core-link--usage.md +16 -0
  47. package/docs/core-listitem--design.md +70 -0
  48. package/docs/core-listitem--usage.md +6 -0
  49. package/docs/core-menu--design.md +106 -0
  50. package/docs/core-menu--usage.md +16 -0
  51. package/docs/core-modal--design.md +39 -0
  52. package/docs/core-modal--usage.md +11 -0
  53. package/docs/core-numberfield--design.md +12 -0
  54. package/docs/core-numberfield--usage.md +14 -0
  55. package/docs/core-pagination--design.md +30 -0
  56. package/docs/core-pagination--usage.md +13 -0
  57. package/docs/core-passwordfield--design.md +7 -0
  58. package/docs/core-passwordfield--usage.md +3 -0
  59. package/docs/core-pill--design.md +94 -0
  60. package/docs/core-pill--usage.md +10 -0
  61. package/docs/core-popover--design.md +25 -0
  62. package/docs/core-popover--usage.md +8 -0
  63. package/docs/core-radio--design.md +39 -0
  64. package/docs/core-radio--usage.md +8 -0
  65. package/docs/core-radiogroup--design.md +5 -0
  66. package/docs/core-radiogroup--usage.md +12 -0
  67. package/docs/core-radiotile--design.md +5 -0
  68. package/docs/core-radiotile--usage.md +10 -0
  69. package/docs/core-ribbon--design.md +39 -0
  70. package/docs/core-ribbon--usage.md +12 -0
  71. package/docs/core-skeleton--design.md +88 -0
  72. package/docs/core-skeleton--usage.md +13 -0
  73. package/docs/core-skeletongroup--design.md +50 -0
  74. package/docs/core-skeletongroup--usage.md +10 -0
  75. package/docs/core-spinner--design.md +99 -0
  76. package/docs/core-spinner--usage.md +11 -0
  77. package/docs/core-switch--design.md +145 -0
  78. package/docs/core-switch--usage.md +8 -0
  79. package/docs/core-tabnav--design.md +77 -0
  80. package/docs/core-tabnav--usage.md +63 -0
  81. package/docs/core-tag--design.md +21 -0
  82. package/docs/core-tag--usage.md +11 -0
  83. package/docs/core-text--design.md +32 -0
  84. package/docs/core-text--usage.md +10 -0
  85. package/docs/core-textarea--design.md +74 -0
  86. package/docs/core-textarea--usage.md +18 -0
  87. package/docs/core-textfield--design.md +81 -0
  88. package/docs/core-textfield--usage.md +12 -0
  89. package/docs/core-textinput--design.md +72 -0
  90. package/docs/core-textinput--usage.md +19 -0
  91. package/docs/core-toast--design.md +100 -0
  92. package/docs/core-toast--usage.md +11 -0
  93. package/docs/core-tooltip--design.md +61 -0
  94. package/docs/core-tooltip--usage.md +48 -0
  95. package/docs/core-topnav--design.md +75 -0
  96. package/docs/core-topnav--usage.md +6 -0
  97. package/docs/core-verticalnavigation--design.md +31 -0
  98. package/docs/core-verticalnavigation--usage.md +17 -0
  99. package/docs/core-visuallyhidden--design.md +87 -0
  100. package/docs/core-visuallyhidden--usage.md +35 -0
  101. package/docs/history-changelogs-capra-core--docs.md +60 -0
  102. package/docs/index.md +110 -0
  103. package/docs/using-capra--docs.md +39 -0
  104. package/package.json +5 -4
@@ -0,0 +1,87 @@
1
+ # Core/IconButton - Design
2
+
3
+ Interactive element displaying a single icon.
4
+
5
+ ## Properties
6
+
7
+ ### Icon
8
+
9
+ <p>
10
+ Icon buttons are used to quickly identify available actions.
11
+ </p>
12
+
13
+ <p>
14
+ Common actions, like save or search, can omit titles and use the icon alone. Avoid using an icon alone when the meaning is ambiguous, unclear, or unfamiliar.
15
+ </p>
16
+
17
+ <p>
18
+ View available icons in the Icon library.
19
+ </p>
20
+
21
+ ### Size
22
+
23
+ <p>
24
+ Buttons are available in small, medium, and large sizes. Medium is the default size and is preferred in most situations.
25
+ </p>
26
+
27
+ <p>
28
+ Small buttons are primarily used when buttons appear inline with over components, such as in a popover and to conserve space.
29
+ </p>
30
+
31
+ ### Loading
32
+
33
+ <p>
34
+ Buttons can show a loading state for actions that take longer to respond.
35
+ </p>
36
+
37
+ <p>
38
+ The loading spinner is shown in the leading icon slot, replacing an icon if present. Button text should be updated to indicate the action currently taking place. Further interaction is disabled until the action is complete.
39
+ </p>
40
+
41
+ ## Behavior
42
+
43
+ ### Tooltips
44
+
45
+ <p>
46
+ Icon buttons reveal the label in a tooltip on hover or long-press.
47
+ </p>
48
+
49
+ <img src="images/guidelines/iconbutton/behavior-tooltip.png" />
50
+
51
+ ### Loading delay
52
+
53
+ <p>
54
+ Buttons can show a loading state for actions that take longer to respond.
55
+ </p>
56
+
57
+ <p>
58
+ The loading spinner is shown in place of the icon. Further interaction is disabled until the action is complete.
59
+ </p>
60
+
61
+ ### State
62
+
63
+ <p>
64
+ Buttons use a color shift between palette indexes for interaction states. The available sates are enabled, hover, active, focused, disabled, and pending.
65
+ </p>
66
+
67
+ <img src="images/guidelines/iconbutton/behavior-state.png" />
68
+
69
+ ## Accessibility
70
+
71
+ ### Keyboard interaction
72
+
73
+ All buttons exist in the page’s natural tab sequence, reachable via TAB and SHIFT+TAB keys. Pressing SPACEBAR or ENTER activates the focused button.
74
+
75
+ ### Labeling
76
+
77
+ <p>
78
+ For buttons with an icon and text, if the icon reinforces the text, do not add any description of the icon as it would be redundant.
79
+ </p>
80
+
81
+ <p>
82
+ If the icon adds important information that is not explained in the text, then the label of the button must begin with the text with any extra information about the icon following the text. This order supports users who control their device with speech.
83
+ </p>
84
+
85
+ <p>
86
+ Icon buttons without text must have an easily identifiable (for speech users) accessible label, such as “Download.”
87
+ </p>
@@ -0,0 +1,15 @@
1
+ # Core/IconButton - Usage
2
+
3
+ Interactive element displaying a single icon.
4
+
5
+ | Prop | Type | Required | Default | Description |
6
+ | --- | --- | --- | --- | --- |
7
+ | `icon` | `SvgIcon` | Yes | `--` | Icon to display in the button. |
8
+ | `aria-label` | `string` | Yes | `--` | Accessibility label to apply to the button. |
9
+ | `variant` | `(typeof variants)[number]` | No | 'secondary' | Which button style to use. Defaults to `secondary`. |
10
+ | `appearance` | `(typeof appearances)[number]` | No | 'default' | Appearance to apply to the button. Defaults to `default`. |
11
+ | `size` | `(typeof sizes)[number]` | No | 'md' | Size of the button. Defaults to `md`. |
12
+ | `disabled` | `boolean` | No | false | Whether the button is disabled. |
13
+ | `pending` | `boolean` | No | false | Whether the button is in a pending state. |
14
+ | `onClick` | `React.ComponentProps<'button'>['onClick']` | No | `--` | Click handler for the button. |
15
+ | `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |
@@ -0,0 +1,85 @@
1
+ # Core/InputRow - Design
2
+
3
+ ## Overview
4
+
5
+ `InputRow` is a horizontal container that visually merges one primary input with optional prefix and
6
+ suffix segments so the whole group reads as a single control. Use it for URLs, currency amounts, units, fixed
7
+ labels (for example `https://` or `.com`), and similar patterns where the value only makes
8
+ sense together with its neighbors.
9
+
10
+ ## `InputRow`
11
+
12
+ ### Role and labeling
13
+
14
+ The root is a `div` laid out as a flex row. When you pass `aria-label` or `aria-labelledby`, the row defaults to `role="group"` so assistive technologies can treat
15
+ the children as one related set. Give the row a short name that describes the combined value (for example
16
+ “Web address” or “Price”).
17
+
18
+ Order children left-to-right: leading segment, primary field, trailing segment. Capra field wrappers use `display: contents` when they are **direct** children of the row, so the inner input
19
+ participates in the flex layout and border-joining rules; keep fields and addons as immediate children of `InputRow`.
20
+
21
+ ### Visual treatment
22
+
23
+ Only the outer corners of the group use the standard field radius; shared edges between segments stay square
24
+ so borders overlap cleanly instead of doubling. Adjacent borders are collapsed with a small negative margin;
25
+ the segment that contains focus is raised in the stacking order so its focus ring stays visible.
26
+
27
+ ## `InputRow.Addon`
28
+
29
+ ### Static segments
30
+
31
+ `InputRow.Addon` is for **non-editable** content: fixed text, symbols, or decorative
32
+ icons. String children are rendered with the typography `Text` component; pass arbitrary nodes for
33
+ icons or richer content.
34
+
35
+ Addons are flex-shrink-safe strips with a muted surface and field-aligned borders so they match `TextInput` height and baseline. Place one or more addons before and/or after the field; the
36
+ primary input should remain the flexible segment in the middle when you have both sides.
37
+
38
+ ### Size
39
+
40
+ The `size` prop on `InputRow.Addon` (`md` by default, or `sm`)
41
+ controls minimum height and typography so the addon lines up with an adjacent `TextField` or `NumberField` using the same `size`.
42
+
43
+ ## Composing with Capra `*Field` components
44
+
45
+ ### Which fields to use
46
+
47
+ `TextField` and `NumberField` are the usual primary controls inside a row. Other Capra
48
+ field roots that expose `data-capra-field-root` (for example `AutocompleteField`, `DatePicker`, or `DateRangePicker`) use the same layout hook: the wrapper does not create
49
+ an extra flex box, so the inner control can share borders with addons like a plain `TextInput`.
50
+
51
+ Prefer one primary editable control per row. Pair it with `InputRow.Addon` for fixed text or icons,
52
+ or with another bordered control as a leading/trailing segment when the design calls for a separate control
53
+ (for example a unit or scheme picker), keeping that control a direct child so border overlap still applies.
54
+
55
+ ### Labels, helper text, and slots
56
+
57
+ Do not pass `label`, `helperText`, or `layout` props on Capra field wrappers
58
+ inside an `InputRow`. Those patterns reserve vertical space for label and helper rows and break the
59
+ single horizontal group.
60
+
61
+ Put the visible label (if any) *outside* the row—for example a standalone `Label` or
62
+ surrounding copy tied with `aria-labelledby` on `InputRow`. For validation or hints,
63
+ show helper text below the whole row, not on the nested field.
64
+
65
+ Avoid `leadingSlot` and `trailingSlot` on `TextField` when the same concern is
66
+ already expressed with `InputRow.Addon`; slots are meant for compact adornments on the input itself,
67
+ not for full row segments.
68
+
69
+ ### Accessible names
70
+
71
+ When `label` is omitted on nested fields, each focusable control still needs a name: use `aria-label` or `aria-labelledby` on `TextField`, `NumberField`, or
72
+ the inner input as documented for that component. The row-level `aria-label` names the group; each
73
+ control should have its own short name (“Domain”, “Amount”, “Unit”, and so on) where several tab stops exist.
74
+
75
+ ## Accessibility
76
+
77
+ ### Grouping
78
+
79
+ When the row combines multiple inputs or segments that share one label, put `aria-label` or `aria-labelledby` on `InputRow` and ensure each focusable control still has a distinct
80
+ accessible name where needed.
81
+
82
+ ### Addons
83
+
84
+ Treat `InputRow.Addon` as presentational unless the text is essential; decorative icons should use `aria-hidden`. If addon text conveys meaning not duplicated elsewhere, leave it in the accessibility
85
+ tree.
@@ -0,0 +1,6 @@
1
+ # Core/InputRow - Usage
2
+
3
+ | Prop | Type | Required | Default | Description |
4
+ | --- | --- | --- | --- | --- |
5
+ | `children` | `React.ReactNode` | No | `--` | `--` |
6
+ | `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |
@@ -0,0 +1,27 @@
1
+ # Core/Label - Design
2
+
3
+ Label text and optional required indicator for form fields, aligned with Capra field layouts.
4
+
5
+ :::warning
6
+
7
+ Prefer Capra field components—such as `TextField`, `NumberField`, `PasswordField`, `TextArea`, `DatePicker`, `DateRangePicker`, or `AutocompleteField`—which
8
+ wire labels, inputs, and helper text together with consistent layout and accessibility. Use standalone `Label` only when you are composing a custom field or integrating with primitives that do not ship a built-in label.
9
+
10
+ :::
11
+
12
+ ## Accessibility
13
+
14
+ ### Association
15
+
16
+ <p>
17
+ Pair `Label` with its control using `htmlFor` on the label and a matching `id` on
18
+ the input (or equivalent association pattern for custom widgets). Every form control should have an accessible name;
19
+ a visible `Label` is one straightforward way to provide it.
20
+ </p>
21
+
22
+ ### Required fields
23
+
24
+ <p>
25
+ The visual asterisk for <code>required</code> is marked <code>aria-hidden</code> so it is not double-announced; the
26
+ required state is also conveyed with visually hidden text for screen readers.
27
+ </p>
@@ -0,0 +1,17 @@
1
+ # Core/Label - Usage
2
+
3
+ Label text and optional required indicator for form fields, aligned with Capra field layouts.
4
+
5
+ | Prop | Type | Required | Default | Description |
6
+ | --- | --- | --- | --- | --- |
7
+ | `children` | `string` | No | `--` | Text to display in the label. |
8
+ | `required` | `boolean` | No | `--` | Whether the field the label is labeling is required (shows asterisk after label). |
9
+ | `trailingSlot` | `React.ReactNode` | No | `--` | Content after the label text. |
10
+ | `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |
11
+
12
+ ## React Aria
13
+
14
+ <p>
15
+ The component uses <code>useContextProps</code> with React Aria’s <code>LabelContext</code>, so when it sits inside
16
+ compatible React Aria structures, label props can be supplied by context as well as passed directly.
17
+ </p>
@@ -0,0 +1,58 @@
1
+ # Core/Link - Design
2
+
3
+ Links are navigational elements that take users to a new page.
4
+
5
+ ## Properties
6
+
7
+ ### Text
8
+
9
+ The text representing the link should describe its destination.
10
+
11
+ ### isExternal
12
+
13
+ External links display an icon at the trailing end of the link. They navigate to a page outside the product and open
14
+ in a new tab.
15
+
16
+ ### Client-side Routing
17
+
18
+ Links support client-side routing out of the box when Capra's `RouterProvider` is used. See the
19
+ [Conventions](/docs/conventions--docs#client-side-routing) page for more details.
20
+
21
+ ## Best Practices
22
+
23
+ **Do**
24
+
25
+ <p>
26
+ Do clearly indicate the destination of a link through its text.
27
+ </p>
28
+
29
+ **Don't**
30
+
31
+ <p>
32
+ Don't use vague instructions, such as “click here”, for links.
33
+ </p>
34
+
35
+ ## Accessibility
36
+
37
+ ### Keyboard interaction
38
+
39
+ All links exist in the page's natural tab sequence, reachable via TAB and SHIFT+TAB keys. Pressing ENTER activates
40
+ the focused link.
41
+
42
+ ### External links
43
+
44
+ External links should announce themselves as opening in a new tab. For example: "Link text, opens in a new tab."
45
+
46
+ ### Keyboard focus indicator
47
+
48
+ Links inherit the standard focus indicator standard to all focusable elements.
49
+
50
+ ## Accessibility
51
+
52
+ * Meaningful link text: describe the destination, not "click here" or "read more".
53
+ * External links: announce the new-tab behavior in the link text or `aria-label` (e.g., "Opens in new tab").
54
+
55
+ ## Related components
56
+
57
+ * [Button](?path=/docs/core-button--design)
58
+ * [Anchor](?path=/docs/core-anchor--design)
@@ -0,0 +1,16 @@
1
+ # Core/Link - Usage
2
+
3
+ Links are navigational elements that take users to a new page.
4
+
5
+ | Prop | Type | Required | Default | Description |
6
+ | --- | --- | --- | --- | --- |
7
+ | `as` | `As` | No | `--` | The underlying element rendered by the component. Defaults to `a`. |
8
+ | `isExternal` | `boolean` | No | false | Whether the Link points to an external resource.<br><br>When `true` and `as="a"`, applies `target="_blank"` and `rel="noopener noreferrer"`.<br><br>Defaults to `false`. |
9
+ | `href` | `unknown` | No | `--` | A URL to link to. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#href). |
10
+ | `hrefLang` | `string` | No | `--` | Hints at the human language of the linked URL. See[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#hreflang). |
11
+ | `target` | `HTMLAttributeAnchorTarget` | No | `--` | The target window for the link. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target). |
12
+ | `rel` | `string` | No | `--` | The relationship between the linked resource and the current page. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel). |
13
+ | `download` | `boolean \| string` | No | `--` | Causes the browser to download the linked URL. A string may be provided to suggest a file name. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download). |
14
+ | `referrerPolicy` | `HTMLAttributeReferrerPolicy` | No | `--` | How much of the referrer to send when following the link. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#referrerpolicy). |
15
+ | `routerOptions` | `unknown` | No | `--` | Options for the configured client side router. |
16
+ | `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |
@@ -0,0 +1,70 @@
1
+ # Core/ListItem - Design
2
+
3
+ ## Properties
4
+
5
+ ### Leading
6
+
7
+ Leading slots are commonly used for icons, avatars, or checkboxes.
8
+
9
+ ### Label
10
+
11
+ A label is required for all list items. Their length may vary based on application but should always be succinct.
12
+
13
+ ### Description
14
+
15
+ The description slot is used to display the description of the list item.
16
+
17
+ ### Suffix
18
+
19
+ A suffix provides space for information such as item counts.
20
+
21
+ ### Trailing
22
+
23
+ Trailing slots are most often used for components providing supplementary information, such as Pills, or controls for menus.
24
+
25
+ ## Behavior
26
+
27
+ ### Spacing
28
+
29
+ ### Overflow
30
+
31
+ Labels will wrap if they are wider than the parent container. The list item remains aligned to the top of the text
32
+ box.
33
+
34
+ ## Best Practices
35
+
36
+ **Do**
37
+
38
+ <p>
39
+ Do maintain consistent with usage of leading and trailing slots.
40
+ </p>
41
+
42
+ **Don't**
43
+
44
+ <p>
45
+ Don't mix items with and without slots.
46
+ </p>
47
+
48
+ **Do**
49
+
50
+ <p>
51
+ Do keep interaction to single action per row.
52
+ </p>
53
+
54
+ **Don't**
55
+
56
+ <p>
57
+ Avoid having multiple interactive elements in a list row.
58
+ </p>
59
+
60
+ **Do**
61
+
62
+ <p>
63
+ Do omit unnecessary visual clutter, such as dividers.
64
+ </p>
65
+
66
+ **Don't**
67
+
68
+ <p>
69
+ Don't include dividers when using a list group.
70
+ </p>
@@ -0,0 +1,6 @@
1
+ # Core/ListItem - Usage
2
+
3
+ | Prop | Type | Required | Default | Description |
4
+ | --- | --- | --- | --- | --- |
5
+ | `as` | `As` | No | `--` | `--` |
6
+ | `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |
@@ -0,0 +1,106 @@
1
+ # Core/Menu - Design
2
+
3
+ ## Properties
4
+
5
+ ### Label
6
+
7
+ A label is required for all menu items. Their length may vary based on application but should always be succinct.
8
+
9
+ ### Description
10
+
11
+ Descriptions can provide secondary information to menu items.
12
+
13
+ ### Icon
14
+
15
+ Capra does not suggest the use of icons in menu items, but an optional slot is available when an icon adds significant recognition.
16
+
17
+ ### Shortcut
18
+
19
+ Shortcuts enable users to more easily access common commands. If available, shortcuts to a command should be shown at the right. A menu does not need to be open for a shortcut to work.
20
+
21
+ ### Indent
22
+
23
+ Use `Menu.Section` to group `Menu.Item` rows. Add an optional `Menu.Header` inside the section to label the group; items in that section indent automatically to show hierarchy. A `Menu.Header` outside a section is only a label and does not indent following items—wrap the header and its items in `Menu.Section` when you want indentation. Sections without a header must be named for assistive technology with `aria-label` or `aria-labelledby`. You can still set `indent` on an item to override the default.
24
+
25
+ ## Content
26
+
27
+ ### Ellipsis
28
+
29
+ Use ellipsis to indicate when the menu item leads to additional steps. This is normally followed by a modal.
30
+
31
+ ### Divider
32
+
33
+ Dividers provide subtle separation between list items. They can be used to group items when a header is not necessary. Use `Menu.Divider` between menu items to create visual separation.
34
+
35
+ ## Selection
36
+
37
+ ### Single selection
38
+
39
+ Single selection items act as radio buttons within a menu. Use the `active` prop to indicate the current page or selected item.
40
+
41
+ ### Multiple selection
42
+
43
+ Multiple selection items act as checkboxes within a menu. Users can select more than one item. Use the `active` prop on each `Menu.Item` to indicate selected items. Manage selection state in your application.
44
+
45
+ ### Section-level selection
46
+
47
+ When single and/or multiple section options are used alongside other option types, use Sections to group each selection type.
48
+
49
+ ## Behavior
50
+
51
+ ### Focus containment (`trapFocus`)
52
+
53
+ Set **`trapFocus`** on **`Menu`** when keyboard focus must stay inside the menu panel while it is open—for example horizontal **`TabNav`** flyouts that sit next to other tab stops. The popover stays **non-modal**, so outside pointer dismiss still works. Focus **containment** turns on once focus has entered the panel (so the trigger can still move focus into the menu on open); **`restoreFocus`** returns focus to the trigger when the menu closes.
54
+
55
+ When **`trapFocus`** is omitted (**default `false`**), focus follows the usual tab sequence for a non-modal overlay.
56
+
57
+ ### Submenu
58
+
59
+ Use `Menu.Submenu` for nested flyouts: Capra requires `SubmenuTrigger` → `Popover` → `Menu` so the nested panel is positioned to the side (not stacked under the trigger). The parent row shows a trailing chevron; hover or keyboard opens the submenu. The `parent` prop on `Menu.Item` only adds the chevron for labels without a submenu.
60
+
61
+ ### Minimum and maximum width
62
+
63
+ Menu items have a minimum width of 152px and maximum width of 256px. Content that extends beyond the maximum width is truncated. An ellipsis is *not* added due to the special meaning of the ellipsis following an item label. Care should be taken to ensure menu item labels remain short and succinct to avoid running over the maximum width.
64
+
65
+ ## Best Practices
66
+
67
+ ### Menu Size
68
+
69
+ **Do**
70
+
71
+ <img className="w-full" src="images/guidelines/menu/bestpractices-size-do.png" alt="Menu with appropriate number of items" />
72
+
73
+ <p>
74
+ Do keep menus to as few items as possible, aim for no more than 5 items.
75
+ </p>
76
+
77
+ **Don't**
78
+
79
+ <img className="w-full" src="images/guidelines/menu/bestpractices-size-dont.png" alt="Overly long menu" />
80
+
81
+ <p>
82
+ Don't overload menu item choices.
83
+ </p>
84
+
85
+ ## Accessibility
86
+
87
+ ### Keyboard interaction
88
+
89
+ | Key | Function |
90
+ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
91
+ | `Tab` / `Shift + Tab` | Moves focus to, or away from, the trigger. If the menu is open, focus shifts away from the trigger and the menu closes. |
92
+ | `Enter` | If the trigger has focus: opens the menu and focuses the first item. If a menu item has focus: activates that item and closes the menu. |
93
+ | `Space` | If the trigger has focus, opens the menu and focuses the first item. |
94
+ | `Down Arrow` | If the trigger has focus: opens the menu and focuses the first item. If a menu item has focus: moves focus to the next item, wrapping from last to first. |
95
+ | `Up Arrow` | If a menu item has focus: moves focus to the previous item, wrapping from first to last. |
96
+ | `Esc` | Closes the menu and returns focus to the trigger. |
97
+ | `[a-z]` | Move focus to the next item whose label begins with that printable character. |
98
+
99
+ ### Aria considerations
100
+
101
+ * Triggers must have an accessible name (`aria-label` or `aria-labelledby`) or label.
102
+ * Triggers must have `aria-haspopup="menu"` and use `aria-expanded="true|false"`.
103
+ * Use `role="menu"` on menu container.
104
+ * Use `role="menuitem"` on each menu item.
105
+ * Use `role="separator"` if a separator is used.
106
+ * Group related items with `Menu.Section` (`role="group"`). When the section includes `Menu.Header`, the section is named via `aria-labelledby` (the header gets an id). Headerless sections must expose a name with `aria-label` or `aria-labelledby`.
@@ -0,0 +1,16 @@
1
+ # Core/Menu - Usage
2
+
3
+ | Prop | Type | Required | Default | Description |
4
+ | --- | --- | --- | --- | --- |
5
+ | `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |
6
+ | `trigger` | `React.ReactElement` | Yes | `--` | Single element that toggles the menu (e.g. button). Rendered as the menu trigger; must forward refs to a focusable DOM node (wrapped with React Aria {@link Pressable} internally). |
7
+ | `children` | `React.ReactNode` | No | `--` | Menu content. Use Menu.Item, Menu.Section, Menu.Header, Menu.Divider. |
8
+ | `contentProps` | `React.HTMLAttributes<HTMLDivElement>` | No | `--` | Optional props for the element wrapping the menu panel (e.g. pointer handlers when bridging trigger and menu). |
9
+ | `open` | `boolean` | No | `--` | Controlled open state. Omit for uncontrolled usage. |
10
+ | `onOpenChange` | `(open: boolean) => void` | No | `--` | Called when the menu should open or close. |
11
+ | `itemHoverAppearance` | `'default' \| 'accent'` | No | 'default' | Hover/selected styling for items. `accent`: TabNav submenu treatment per Tab Nav \| Vertical \| Item (Figma)—hover uses primary background + accent-hover text; selected uses accent-selected background, accent text, semibold label, inline-end accent bar. `default`: neutral grey hover only.<br>@default 'default' |
12
+ | `itemActiveAccentBar` | `boolean` | No | true | When `itemHoverAppearance` is `accent`, whether the active/selected row shows the inline-end accent bar (vertical TabNav indicator). Set to `false` for horizontal TabNav flyout menus where selection should not show that bar.<br>@default true |
13
+ | `itemActiveLabelSemibold` | `boolean` | No | true | When `itemHoverAppearance` is `accent`, whether the active/selected row uses a semibold label. Set to `false` for TabNav horizontal submenus where the active item should match normal menu weight.<br>@default true |
14
+ | `panelPadding` | `'default' \| 'none'` | No | 'default' | Inset of the menu panel (`role="menu"`). `none` uses a minimal inset so focus rings are not clipped under scroll/overflow; use for flyouts that should sit close to the popover edge (e.g. TabNav submenu).<br>@default 'default' |
15
+ | `popoverOffset` | `number` | No | 0 | Gap along the main axis between the trigger and the menu panel (React Aria `Popover` `offset`).<br>Use a small value (e.g. 1) when the panel should clear a trigger underline/border (e.g. horizontal TabNav).<br>@default 0 |
16
+ | `trapFocus` | `boolean` | No | false | When `true`, focus is contained in the menu panel while it is open (Tab cycles within the panel; focus restores on close).<br>The popover stays non-modal so outside pointer dismiss still works. Use for patterns that must not move focus to sibling controls until the menu closes (e.g. horizontal TabNav flyouts).<br>@default false |
@@ -0,0 +1,39 @@
1
+ # Core/Modal - Design
2
+
3
+ ## Properties
4
+
5
+ ### Size
6
+
7
+ Modals come in three sizes: small, medium, and large. Medium is the default size.
8
+ The height of the modal adjusts to the content, up to a maximum height.
9
+
10
+ ### Layered modals
11
+
12
+ Modals automatically stack such that the most recent modal is interactive while preserving the
13
+ backdrop of previous layers.
14
+
15
+ :::warning
16
+
17
+ Modals should never be layered. This causes accessibility and usability issues. Open modals should be closed before new ones are opened.
18
+
19
+ Current instances of layered modals in the product should be refactored to no longer be layered.
20
+
21
+ :::
22
+
23
+ ## Accessibility
24
+
25
+ ### Keyboard interaction
26
+
27
+ | Key | Function |
28
+ | ---------------------- | ------------------------------------------------------------------------------------------------------- |
29
+ | `Tab`<br />`Shift-Tab` | Moves focus to the next/previous focusable element within the modal. Focus is trapped within the modal. |
30
+ | `Escape` | Closes the modal. |
31
+ | `Enter`<br />`Space` | Activates the focused element (e.g., buttons in the footer). |
32
+
33
+ ### WAI-ARIA Roles, States, and Properties
34
+
35
+ * The modal container has `role="dialog"` and `aria-modal="true"`.
36
+ * The modal title has a unique ID and the modal container has `aria-labelledby` set to that ID.
37
+ * The modal overlay has `role="button"` and acts as a backdrop that can close the modal when clicked (if configured).
38
+ * Focus is automatically moved to the modal when it opens and restored to the trigger when it closes.
39
+ * The `body` element has `overflow: hidden` applied when the modal is open to prevent background scrolling.
@@ -0,0 +1,11 @@
1
+ # Core/Modal - Usage
2
+
3
+ ### Modal
4
+
5
+ | Prop | Type | Required | Default | Description |
6
+ | --- | --- | --- | --- | --- |
7
+ | `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |
8
+ | `size` | `string` | No | 'md' | `--` |
9
+ | `isDismissible` | `boolean` | No | true | `--` |
10
+ | `confirmButtonText` | `string` | No | 'OK' | `--` |
11
+ | `cancelButtonText` | `string` | No | 'Cancel' | `--` |
@@ -0,0 +1,12 @@
1
+ # Core/NumberField - Design
2
+
3
+ Number field built on React Aria `NumberField`, with custom increment/decrement controls (native spinners hidden).
4
+
5
+ ## Anatomy
6
+
7
+ Single-line numeric field with custom increment/decrement controls. Use `min`, `max`, and `step` for native constraint and stepping behavior.
8
+
9
+ ## Accessibility
10
+
11
+ * The input is a text field with `aria-roledescription` of “Number field”. Keyboard users can adjust values with arrow keys where supported.
12
+ * Set `aria-invalid` via `appearance="danger"`, and `aria-required` when `required` is set.
@@ -0,0 +1,14 @@
1
+ # Core/NumberField - Usage
2
+
3
+ Number field built on React Aria `NumberField`, with custom increment/decrement controls (native spinners hidden).
4
+
5
+ | Prop | Type | Required | Default | Description |
6
+ | --- | --- | --- | --- | --- |
7
+ | `onChange` | `(value: number) => void` | No | `--` | Called with the unformatted number value when the number changes. |
8
+ | `formatOptions` | `Intl.NumberFormatOptions` | No | `--` | Locale-aware display and parsing for the displayed value (see https://react-aria.adobe.com/NumberField#format-options) |
9
+ | `min` | `number` | No | `--` | Minimum value |
10
+ | `max` | `number` | No | `--` | Maximum value |
11
+ | `step` | `number` | No | `--` | Step increment. When omitted, defaults to `1` (same as native `input type="number"`). |
12
+ | `helperText` | `string` | No | `--` | Helper text below the field. Replaced by error message when status is error. Use for requirements, disclaimers. |
13
+ | `label` | `string` | No | `--` | Label for the field. Required for accessibility; use aria-label if another element acts as label. |
14
+ | `layout` | `'vertical' \| 'horizontal'` | No | `--` | Label and field layout: vertical (label above) or horizontal (label on leading side). Prefer vertical; use horizontal when space is limited. |
@@ -0,0 +1,30 @@
1
+ # Core/Pagination - Design
2
+
3
+ Pagination component for navigating through paged content. Renders prev/next buttons and a page number input with total pages indicator.
4
+
5
+ ## Properties
6
+
7
+ ### Total Pages
8
+
9
+ The total number of pages.
10
+
11
+ ## Behavior
12
+
13
+ ### Page Updates
14
+
15
+ Page updates occur immediately when clicking the forward or backward buttons. Entering a value in the input field
16
+ will update when pressing Enter or when focus is moved.
17
+
18
+ ## Accessibility
19
+
20
+ ### Keyboard interaction
21
+
22
+ | Key | Function |
23
+ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
+ | `Tab`<br />`Shift + Tab` | - Moves focus to the next/previous focusable element. |
25
+ | `Enter` | - If an action button is focused: activates that button.<br />- If the page input field is focused: updates the entered page. Focus remains on the input field. |
26
+
27
+ ### Aria considerations
28
+
29
+ * Use the `nav` element to wrap the pagination.
30
+ * The `nav` element must have an accessible name (`aria-label` or `aria-labelledby`) or label.
@@ -0,0 +1,13 @@
1
+ # Core/Pagination - Usage
2
+
3
+ Pagination component for navigating through paged content. Renders prev/next buttons and a page number input with total pages indicator.
4
+
5
+ | Prop | Type | Required | Default | Description |
6
+ | --- | --- | --- | --- | --- |
7
+ | `total` | `number` | Yes | `--` | Total number of data items. Used with `pageSize` to compute total pages. |
8
+ | `current` | `number` | Yes | `--` | Current page number (1-based). |
9
+ | `pageSize` | `number` | No | 10 | Number of items per page. Defaults to `10`. |
10
+ | `onChange` | `(page: number, pageSize: number) => void` | No | `--` | Callback when page changes. |
11
+ | `disabled` | `boolean` | No | false | Whether the pagination is disabled. |
12
+ | `aria-label` | `string` | Yes | `--` | Accessible name for the navigation. Required for accessibility. |
13
+ | `FORCE__className` | `string` | No | `--` | 🚨 This prop is meant to be an escape hatch. 🚨<br><br>If the desired style cannot be achieved using component props, use this as a last resort. The inner workings of Capra components are implementation details and this escape hatch gives one access to those implementation details. We cannot make any guarantees that styles will applied correctly across version updates. Please use it responsibly.<br><br>Add a CSS class to the component. |