@commercetools/nimbus-mcp 3.5.1 → 3.6.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 (119) hide show
  1. package/data/docs/route-manifest.json +275 -9
  2. package/data/docs/routes/components-buttons-toggle-button-group.json +143 -18
  3. package/data/docs/routes/components-buttons-toggle-button.json +72 -15
  4. package/data/docs/routes/components-chat.json +36 -0
  5. package/data/docs/routes/components-content.json +36 -0
  6. package/data/docs/routes/components-data-display-data-table.json +1 -1
  7. package/data/docs/routes/components-feedback-popover.json +643 -0
  8. package/data/docs/routes/components-inputs-combo-box.json +33 -11
  9. package/data/docs/routes/components-inputs-search-input.json +29 -7
  10. package/data/docs/routes/components-inputs-select-input.json +23 -1
  11. package/data/docs/routes/components-layout-stack.json +1 -1
  12. package/data/docs/routes/components-navigation-toolbar.json +1 -1
  13. package/data/docs/routes/components-navigation-tree.json +2 -2
  14. package/data/docs/routes/home-contribute.json +29 -8
  15. package/data/docs/routes/home-getting-started-collaboration.json +657 -0
  16. package/data/docs/search-index.json +1 -1
  17. package/data/docs/types/AccordionContent.json +12 -12
  18. package/data/docs/types/AccordionHeader.json +46 -46
  19. package/data/docs/types/AccordionItem.json +20 -20
  20. package/data/docs/types/AccordionRoot.json +12 -12
  21. package/data/docs/types/ActivityIndicator.json +3 -2
  22. package/data/docs/types/AlertDismissButton.json +42 -42
  23. package/data/docs/types/Button.json +47 -46
  24. package/data/docs/types/Calendar.json +43 -42
  25. package/data/docs/types/Checkbox.json +30 -29
  26. package/data/docs/types/Code.json +2 -1
  27. package/data/docs/types/ComboBoxListBox.json +34 -34
  28. package/data/docs/types/ComboBoxOption.json +20 -20
  29. package/data/docs/types/ComboBoxPopover.json +67 -86
  30. package/data/docs/types/ComboBoxRoot.json +15 -0
  31. package/data/docs/types/ComboBoxSection.json +14 -14
  32. package/data/docs/types/DataTableBody.json +10 -10
  33. package/data/docs/types/DataTableCell.json +18 -18
  34. package/data/docs/types/DataTableColumn.json +28 -28
  35. package/data/docs/types/DataTableHeader.json +10 -10
  36. package/data/docs/types/DataTableManager.json +3 -5
  37. package/data/docs/types/DataTableRow.json +24 -24
  38. package/data/docs/types/DateInput.json +33 -32
  39. package/data/docs/types/DatePicker.json +32 -32
  40. package/data/docs/types/DateRangePicker.json +46 -46
  41. package/data/docs/types/DateRangePickerField.json +46 -46
  42. package/data/docs/types/DialogCloseTrigger.json +42 -42
  43. package/data/docs/types/DraggableListField.json +28 -28
  44. package/data/docs/types/DraggableListItem.json +18 -18
  45. package/data/docs/types/DraggableListRoot.json +30 -30
  46. package/data/docs/types/DrawerCloseTrigger.json +42 -42
  47. package/data/docs/types/DropZone.json +14 -14
  48. package/data/docs/types/FloatingActionButton.json +44 -44
  49. package/data/docs/types/Group.json +9 -7
  50. package/data/docs/types/Heading.json +3 -2
  51. package/data/docs/types/Icon.json +3 -2
  52. package/data/docs/types/IconButton.json +47 -46
  53. package/data/docs/types/IconToggleButton.json +71 -35
  54. package/data/docs/types/Link.json +3 -2
  55. package/data/docs/types/LoadingSpinner.json +3 -2
  56. package/data/docs/types/LocalizedField.json +3 -2
  57. package/data/docs/types/MakeElementFocusable.json +2 -2
  58. package/data/docs/types/MenuItem.json +22 -22
  59. package/data/docs/types/MenuRoot.json +31 -31
  60. package/data/docs/types/MenuSection.json +16 -16
  61. package/data/docs/types/MenuSubmenuTrigger.json +4 -4
  62. package/data/docs/types/MenuTrigger.json +46 -46
  63. package/data/docs/types/MoneyInput.json +4 -2
  64. package/data/docs/types/MultilineTextInput.json +27 -26
  65. package/data/docs/types/MultilineTextInputField.json +27 -26
  66. package/data/docs/types/NumberInput.json +14 -12
  67. package/data/docs/types/NumberInputField.json +10 -10
  68. package/data/docs/types/PasswordInput.json +24 -24
  69. package/data/docs/types/PasswordInputField.json +24 -24
  70. package/data/docs/types/Popover.json +13 -0
  71. package/data/docs/types/PopoverContent.json +42 -0
  72. package/data/docs/types/PopoverRoot.json +651 -0
  73. package/data/docs/types/PopoverTrigger.json +914 -0
  74. package/data/docs/types/ProgressBar.json +17 -15
  75. package/data/docs/types/RadioInputOption.json +17 -17
  76. package/data/docs/types/RadioInputRoot.json +10 -10
  77. package/data/docs/types/RangeCalendar.json +42 -42
  78. package/data/docs/types/RangeSlider.json +14 -14
  79. package/data/docs/types/Region.json +3 -2
  80. package/data/docs/types/RichTextInput.json +4 -2
  81. package/data/docs/types/SearchInput.json +60 -28
  82. package/data/docs/types/SearchInputField.json +60 -28
  83. package/data/docs/types/SelectOption.json +20 -20
  84. package/data/docs/types/SelectOptionGroup.json +14 -14
  85. package/data/docs/types/SelectOptions.json +34 -34
  86. package/data/docs/types/SelectRoot.json +67 -52
  87. package/data/docs/types/Separator.json +4 -2
  88. package/data/docs/types/Slider.json +18 -16
  89. package/data/docs/types/SplitButton.json +12 -10
  90. package/data/docs/types/Switch.json +11 -10
  91. package/data/docs/types/TagGroupRoot.json +12 -12
  92. package/data/docs/types/TagGroupTag.json +16 -16
  93. package/data/docs/types/TagGroupTagList.json +12 -12
  94. package/data/docs/types/TextInput.json +27 -26
  95. package/data/docs/types/TextInputField.json +27 -26
  96. package/data/docs/types/TimeInput.json +30 -28
  97. package/data/docs/types/ToastOutlet.json +4 -2
  98. package/data/docs/types/ToggleButton.json +74 -37
  99. package/data/docs/types/ToggleButtonGroup.json +4 -2
  100. package/data/docs/types/ToggleButtonGroupButton.json +547 -55
  101. package/data/docs/types/ToggleButtonGroupRoot.json +48 -16
  102. package/data/docs/types/Toolbar.json +11 -9
  103. package/data/docs/types/Tooltip.json +3 -2
  104. package/data/docs/types/TooltipContent.json +26 -26
  105. package/data/docs/types/TooltipRoot.json +16 -16
  106. package/data/docs/types/TreeIndicator.json +40 -40
  107. package/data/docs/types/TreeItem.json +20 -20
  108. package/data/docs/types/TreeRoot.json +26 -26
  109. package/data/docs/types/VisuallyHidden.json +4 -4
  110. package/data/docs/types/createItemsFromCsvDrop.json +2 -2
  111. package/data/docs/types/createItemsFromDirectoryDrop.json +2 -2
  112. package/data/docs/types/createItemsFromFileDrop.json +2 -2
  113. package/data/docs/types/createItemsFromImageDrop.json +2 -2
  114. package/data/docs/types/createItemsFromJsonDrop.json +2 -2
  115. package/data/docs/types/manifest.json +4 -0
  116. package/data/docs/types/useTree.json +8 -8
  117. package/data/style-props-summary.json +408 -0
  118. package/dist/index.js +156 -43
  119. package/package.json +8 -8
@@ -86,6 +86,29 @@
86
86
  ],
87
87
  "parent": "root"
88
88
  },
89
+ {
90
+ "value": "Subtle",
91
+ "href": "#subtle",
92
+ "depth": 4,
93
+ "numbering": [
94
+ 1,
95
+ 2,
96
+ 1,
97
+ 3
98
+ ],
99
+ "parent": "root"
100
+ },
101
+ {
102
+ "value": "Active fill",
103
+ "href": "#active-fill",
104
+ "depth": 3,
105
+ "numbering": [
106
+ 1,
107
+ 2,
108
+ 2
109
+ ],
110
+ "parent": "root"
111
+ },
89
112
  {
90
113
  "value": "Color palette",
91
114
  "href": "#color-palette",
@@ -93,7 +116,7 @@
93
116
  "numbering": [
94
117
  1,
95
118
  2,
96
- 2
119
+ 3
97
120
  ],
98
121
  "parent": "root"
99
122
  },
@@ -104,7 +127,7 @@
104
127
  "numbering": [
105
128
  1,
106
129
  2,
107
- 2,
130
+ 3,
108
131
  1
109
132
  ],
110
133
  "parent": "root"
@@ -116,7 +139,7 @@
116
139
  "numbering": [
117
140
  1,
118
141
  2,
119
- 2,
142
+ 3,
120
143
  2
121
144
  ],
122
145
  "parent": "root"
@@ -128,7 +151,7 @@
128
151
  "numbering": [
129
152
  1,
130
153
  2,
131
- 2,
154
+ 3,
132
155
  3
133
156
  ],
134
157
  "parent": "root"
@@ -140,7 +163,7 @@
140
163
  "numbering": [
141
164
  1,
142
165
  2,
143
- 2,
166
+ 3,
144
167
  4
145
168
  ],
146
169
  "parent": "root"
@@ -171,10 +194,10 @@
171
194
  }
172
195
  ]
173
196
  },
174
- "mdx": "\n## Overview\n\nA toggle button is used similarly to a checkbox or a radio button, but supports\na smaller interactive component that can be used to give a binary active state\nchoice to users that can be used alone or in combination with other choices. A\ntoggle button or toggle icon button gives a user a new way of visualizing the\ninformation in the interface. It does not typically perform an action. Please\nuse a button or an icon button for these uses.\n\n### Resources\n\nDeep dive into implementation details and access the Nimbus design library.\n\n[Figma library](https://www.figma.com/design/AvtPX6g7OGGCRvNlatGOIY/NIMBUS-design-system?node-id=5707-16294&m=dev)\n\n## Variables\n\nGet familiar with the features.\n\n### Visuals\n\n#### Outlined\n\nMost common styling of the toggle button.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"outline\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n#### Ghost\n\nGhost styled buttons are helpful for UI simplification.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"ghost\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n### Color palette\n\n#### Primary (default)\n\nThe default colorPalette for most toggle buttons.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton>\n Primary\n </ToggleButton>\n <ToggleButton isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Neutral\n\nUse for secondary or less prominent toggles.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"neutral\">\n Neutral\n </ToggleButton>\n <ToggleButton colorPalette=\"neutral\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Critical\n\nUse for toggles that represent destructive or warning states.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"critical\">\n Critical\n </ToggleButton>\n <ToggleButton colorPalette=\"critical\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Info\n\nUse for informational or help-related toggles.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"info\">\n Info\n </ToggleButton>\n <ToggleButton colorPalette=\"info\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n",
197
+ "mdx": "\n## Overview\n\nA toggle button is used similarly to a checkbox or a radio button, but supports\na smaller interactive component that can be used to give a binary active state\nchoice to users that can be used alone or in combination with other choices. A\ntoggle button or toggle icon button gives a user a new way of visualizing the\ninformation in the interface. It does not typically perform an action. Please\nuse a button or an icon button for these uses.\n\n### Resources\n\nDeep dive into implementation details and access the Nimbus design library.\n\n[Figma library](https://www.figma.com/design/AvtPX6g7OGGCRvNlatGOIY/NIMBUS-design-system?node-id=5707-16294&m=dev)\n\n## Variables\n\nGet familiar with the features.\n\n### Visuals\n\n#### Outlined\n\nMost common styling of the toggle button.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"outline\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n#### Ghost\n\nGhost styled buttons are helpful for UI simplification.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"ghost\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n#### Subtle\n\nA filled neutral chip at rest — useful when the control should read as an\naffordance even before it is selected.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"subtle\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n### Active fill\n\nThe `activeFillStyle` prop sets the weight of the active (selected) fill,\nindependent of the resting `variant`. Use `tint` (default) for multi-select sets\nand `solid` when a single choice should stand out.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"primary\" activeFillStyle=\"tint\" isSelected>\n Tint (default)\n </ToggleButton>\n <ToggleButton colorPalette=\"primary\" activeFillStyle=\"solid\" isSelected>\n Solid\n </ToggleButton>\n </Stack>\n);\n```\n\n### Color palette\n\nThe resting toggle button is always neutral; `colorPalette` tints the active\n(selected) state, so each palette below is shown unselected and selected.\n\n#### Primary (default)\n\nThe default colorPalette for most toggle buttons.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton>\n Primary\n </ToggleButton>\n <ToggleButton isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Neutral\n\nUse for secondary or less prominent toggles.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"neutral\">\n Neutral\n </ToggleButton>\n <ToggleButton colorPalette=\"neutral\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Critical\n\nUse for toggles that represent destructive or warning states.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"critical\">\n Critical\n </ToggleButton>\n <ToggleButton colorPalette=\"critical\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Info\n\nUse for informational or help-related toggles.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"info\">\n Info\n </ToggleButton>\n <ToggleButton colorPalette=\"info\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n",
175
198
  "views": {
176
199
  "overview": {
177
- "mdx": "\n## Overview\n\nA toggle button is used similarly to a checkbox or a radio button, but supports\na smaller interactive component that can be used to give a binary active state\nchoice to users that can be used alone or in combination with other choices. A\ntoggle button or toggle icon button gives a user a new way of visualizing the\ninformation in the interface. It does not typically perform an action. Please\nuse a button or an icon button for these uses.\n\n### Resources\n\nDeep dive into implementation details and access the Nimbus design library.\n\n[Figma library](https://www.figma.com/design/AvtPX6g7OGGCRvNlatGOIY/NIMBUS-design-system?node-id=5707-16294&m=dev)\n\n## Variables\n\nGet familiar with the features.\n\n### Visuals\n\n#### Outlined\n\nMost common styling of the toggle button.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"outline\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n#### Ghost\n\nGhost styled buttons are helpful for UI simplification.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"ghost\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n### Color palette\n\n#### Primary (default)\n\nThe default colorPalette for most toggle buttons.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton>\n Primary\n </ToggleButton>\n <ToggleButton isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Neutral\n\nUse for secondary or less prominent toggles.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"neutral\">\n Neutral\n </ToggleButton>\n <ToggleButton colorPalette=\"neutral\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Critical\n\nUse for toggles that represent destructive or warning states.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"critical\">\n Critical\n </ToggleButton>\n <ToggleButton colorPalette=\"critical\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Info\n\nUse for informational or help-related toggles.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"info\">\n Info\n </ToggleButton>\n <ToggleButton colorPalette=\"info\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n",
200
+ "mdx": "\n## Overview\n\nA toggle button is used similarly to a checkbox or a radio button, but supports\na smaller interactive component that can be used to give a binary active state\nchoice to users that can be used alone or in combination with other choices. A\ntoggle button or toggle icon button gives a user a new way of visualizing the\ninformation in the interface. It does not typically perform an action. Please\nuse a button or an icon button for these uses.\n\n### Resources\n\nDeep dive into implementation details and access the Nimbus design library.\n\n[Figma library](https://www.figma.com/design/AvtPX6g7OGGCRvNlatGOIY/NIMBUS-design-system?node-id=5707-16294&m=dev)\n\n## Variables\n\nGet familiar with the features.\n\n### Visuals\n\n#### Outlined\n\nMost common styling of the toggle button.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"outline\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n#### Ghost\n\nGhost styled buttons are helpful for UI simplification.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"ghost\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n#### Subtle\n\nA filled neutral chip at rest — useful when the control should read as an\naffordance even before it is selected.\n\n```jsx live\nconst App = () => (\n <ToggleButton variant=\"subtle\">\n <Icons.PushPin />\n Product categories\n </ToggleButton>\n)\n```\n\n### Active fill\n\nThe `activeFillStyle` prop sets the weight of the active (selected) fill,\nindependent of the resting `variant`. Use `tint` (default) for multi-select sets\nand `solid` when a single choice should stand out.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"primary\" activeFillStyle=\"tint\" isSelected>\n Tint (default)\n </ToggleButton>\n <ToggleButton colorPalette=\"primary\" activeFillStyle=\"solid\" isSelected>\n Solid\n </ToggleButton>\n </Stack>\n);\n```\n\n### Color palette\n\nThe resting toggle button is always neutral; `colorPalette` tints the active\n(selected) state, so each palette below is shown unselected and selected.\n\n#### Primary (default)\n\nThe default colorPalette for most toggle buttons.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton>\n Primary\n </ToggleButton>\n <ToggleButton isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Neutral\n\nUse for secondary or less prominent toggles.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"neutral\">\n Neutral\n </ToggleButton>\n <ToggleButton colorPalette=\"neutral\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Critical\n\nUse for toggles that represent destructive or warning states.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"critical\">\n Critical\n </ToggleButton>\n <ToggleButton colorPalette=\"critical\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n\n#### Info\n\nUse for informational or help-related toggles.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"400\" align=\"center\" direction=\"row\">\n <ToggleButton colorPalette=\"info\">\n Info\n </ToggleButton>\n <ToggleButton colorPalette=\"info\" isSelected>\n Selected\n </ToggleButton>\n </Stack>\n);\n```\n",
178
201
  "toc": [
179
202
  {
180
203
  "value": "Overview",
@@ -242,6 +265,29 @@
242
265
  ],
243
266
  "parent": "root"
244
267
  },
268
+ {
269
+ "value": "Subtle",
270
+ "href": "#subtle",
271
+ "depth": 4,
272
+ "numbering": [
273
+ 1,
274
+ 2,
275
+ 1,
276
+ 3
277
+ ],
278
+ "parent": "root"
279
+ },
280
+ {
281
+ "value": "Active fill",
282
+ "href": "#active-fill",
283
+ "depth": 3,
284
+ "numbering": [
285
+ 1,
286
+ 2,
287
+ 2
288
+ ],
289
+ "parent": "root"
290
+ },
245
291
  {
246
292
  "value": "Color palette",
247
293
  "href": "#color-palette",
@@ -249,7 +295,7 @@
249
295
  "numbering": [
250
296
  1,
251
297
  2,
252
- 2
298
+ 3
253
299
  ],
254
300
  "parent": "root"
255
301
  },
@@ -260,7 +306,7 @@
260
306
  "numbering": [
261
307
  1,
262
308
  2,
263
- 2,
309
+ 3,
264
310
  1
265
311
  ],
266
312
  "parent": "root"
@@ -272,7 +318,7 @@
272
318
  "numbering": [
273
319
  1,
274
320
  2,
275
- 2,
321
+ 3,
276
322
  2
277
323
  ],
278
324
  "parent": "root"
@@ -284,7 +330,7 @@
284
330
  "numbering": [
285
331
  1,
286
332
  2,
287
- 2,
333
+ 3,
288
334
  3
289
335
  ],
290
336
  "parent": "root"
@@ -296,7 +342,7 @@
296
342
  "numbering": [
297
343
  1,
298
344
  2,
299
- 2,
345
+ 3,
300
346
  4
301
347
  ],
302
348
  "parent": "root"
@@ -330,7 +376,7 @@
330
376
  ]
331
377
  },
332
378
  "dev": {
333
- "mdx": "\n## Getting started\n\n### Import\n\n```tsx\nimport { ToggleButton, type ToggleButtonProps } from '@commercetools/nimbus';\n```\n\n### Basic usage\n\nThe simplest implementation uses the uncontrolled mode with `defaultSelected`:\n\n```jsx live-dev\nconst App = () => (\n <ToggleButton\n defaultSelected={false}\n onChange={(isSelected) => alert(`Selected: ${isSelected}`)}\n >\n Toggle Me\n </ToggleButton>\n)\n```\n\nThe component starts in the unselected state and manages its own state internally. The `onChange` callback is called whenever the selection state changes.\n\n## Usage examples\n\n### Controlled mode\n\nControl the toggle state externally using `isSelected` and `onChange`:\n\n```jsx live-dev\nconst App = () => {\n const [isSelected, setIsSelected] = useState<ToggleButtonProps[\"isSelected\"]>(false);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <ToggleButton isSelected={isSelected} onChange={setIsSelected}>\n {isSelected ? \"Selected\" : \"Not Selected\"}\n </ToggleButton>\n <Text fontSize=\"sm\">\n Current state: {isSelected ? \"Selected\" : \"Not Selected\"}\n </Text>\n </Stack>\n );\n}\n```\n\n### With icons\n\nAdd icons to provide visual context for the toggle action:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton onChange={(selected) => alert(`Liked: ${selected}`)}>\n <Icons.ThumbUp />\n Like\n </ToggleButton>\n\n <ToggleButton onChange={(selected) => alert(`Favorited: ${selected}`)}>\n <Icons.Star />\n Favorite\n </ToggleButton>\n\n <ToggleButton onChange={(selected) => alert(`Saved: ${selected}`)}>\n <Icons.Bookmark />\n Save\n </ToggleButton>\n\n <ToggleButton onChange={(selected) => alert(`Notified: ${selected}`)}>\n <Icons.Notifications />\n Notify\n </ToggleButton>\n </Stack>\n)\n```\n\n### Size variants\n\nThe component supports three size variants to match your interface density:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"row\" gap=\"400\" alignItems=\"center\" wrap=\"wrap\">\n <ToggleButton size=\"2xs\">\n 2x Small\n </ToggleButton>\n\n <ToggleButton size=\"xs\">\n Extra Small\n </ToggleButton>\n\n <ToggleButton size=\"md\">\n Medium (default)\n </ToggleButton>\n </Stack>\n)\n```\n\n### Visual variants\n\nChoose between visual variants to match your design context:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton variant=\"outline\">\n Outline (default)\n </ToggleButton>\n\n <ToggleButton variant=\"outline\" isSelected>\n Outline Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton variant=\"ghost\">\n Ghost\n </ToggleButton>\n\n <ToggleButton variant=\"ghost\" isSelected>\n Ghost Selected\n </ToggleButton>\n </Stack>\n </Stack>\n)\n```\n\n### Color palettes\n\nUse different color palettes to indicate different types of actions:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"primary\">\n Primary\n </ToggleButton>\n <ToggleButton colorPalette=\"primary\" isSelected>\n Primary Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"neutral\">\n Neutral\n </ToggleButton>\n <ToggleButton colorPalette=\"neutral\" isSelected>\n Neutral Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"critical\">\n Critical\n </ToggleButton>\n <ToggleButton colorPalette=\"critical\" isSelected>\n Critical Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"info\">\n Info\n </ToggleButton>\n <ToggleButton colorPalette=\"info\" isSelected>\n Info Selected\n </ToggleButton>\n </Stack>\n </Stack>\n)\n```\n\n### Disabled state\n\nDisable the toggle button to prevent user interaction:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton isDisabled>\n Disabled Unselected\n </ToggleButton>\n\n <ToggleButton isDisabled isSelected>\n Disabled Selected\n </ToggleButton>\n\n <ToggleButton isDisabled variant=\"ghost\">\n <Icons.Star />\n Disabled Ghost\n </ToggleButton>\n </Stack>\n)\n```\n\n## Component requirements\n\n## Accessibility\n\nThe ToggleButton component is built on React Aria's ToggleButton, which provides robust accessibility features out of the box.\n\n**Role**: The component uses the `button` role with `aria-pressed` attribute to communicate toggle state.\n\n**Labeling**: The button's label is determined by its children content. For icon-only buttons, provide an `aria-label`:\n\n```tsx\n<ToggleButton aria-label=\"Add to favorites\">\n <Icons.Star />\n</ToggleButton>\n```\n\nIf your use case requires tracking and analytics for this component, it is good practice to add a **persistent**, **unique** id to the component:\n\n```tsx\nconst PERSISTENT_ID = \"like-button-toggle\";\n\nexport const LikeButton = () => (\n <ToggleButton\n id={PERSISTENT_ID}\n aria-label=\"Like this post\"\n onChange={handleLikeToggle}\n >\n <Icons.ThumbUp />\n </ToggleButton>\n);\n```\n\n#### Keyboard navigation\n\nThe component supports full keyboard interaction:\n- `Tab`: Move focus to/from the toggle button\n- `Enter` or `Space`: Toggle the selected state\n\n## API reference\n\n<PropsTable id=\"ToggleButton\" />\n\n## Common patterns\n\n### Like/Favorite functionality\n\nCommon pattern for like or favorite actions with visual feedback:\n\n```jsx live-dev\nconst App = () => {\n const [liked, setLiked] = useState(false);\n const [favorited, setFavorited] = useState(false);\n const [saved, setSaved] = useState(false);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"row\" gap=\"400\" alignItems=\"center\">\n <ToggleButton\n isSelected={liked}\n onChange={setLiked}\n colorPalette=\"critical\"\n aria-label=\"Like post\"\n >\n <Icons.ThumbUp />\n {liked ? \"Liked\" : \"Like\"}\n </ToggleButton>\n {liked && (\n <Text fontSize=\"sm\" color=\"critical.11\">\n Thank you for your feedback!\n </Text>\n )}\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" alignItems=\"center\">\n <ToggleButton\n isSelected={favorited}\n onChange={setFavorited}\n colorPalette=\"info\"\n aria-label=\"Add to favorites\"\n >\n <Icons.Star />\n {favorited ? \"Favorited\" : \"Favorite\"}\n </ToggleButton>\n {favorited && (\n <Text fontSize=\"sm\" color=\"info.11\">\n Added to your favorites\n </Text>\n )}\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" alignItems=\"center\">\n <ToggleButton\n isSelected={saved}\n onChange={setSaved}\n aria-label=\"Save for later\"\n >\n <Icons.Bookmark />\n {saved ? \"Saved\" : \"Save\"}\n </ToggleButton>\n {saved && (\n <Text fontSize=\"sm\" color=\"neutral.11\">\n Saved for later\n </Text>\n )}\n </Stack>\n </Stack>\n );\n}\n```\n\n### Filter toggles\n\nUse toggle buttons as filter controls in a toolbar or filter panel:\n\n```jsx live-dev\nconst App = () => {\n const [showActive, setShowActive] = useState(true);\n const [showInactive, setShowInactive] = useState(false);\n const [showArchived, setShowArchived] = useState(false);\n\n const getStatusText = () => {\n const statuses = [];\n if (showActive) statuses.push(\"Active\");\n if (showInactive) statuses.push(\"Inactive\");\n if (showArchived) statuses.push(\"Archived\");\n return statuses.length > 0 ? statuses.join(\", \") : \"None\";\n };\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Text fontWeight=\"semibold\">Filter by status:</Text>\n <Stack direction=\"row\" gap=\"300\" wrap=\"wrap\">\n <ToggleButton\n size=\"xs\"\n variant=\"outline\"\n isSelected={showActive}\n onChange={setShowActive}\n colorPalette=\"primary\"\n >\n Active\n </ToggleButton>\n\n <ToggleButton\n size=\"xs\"\n variant=\"outline\"\n isSelected={showInactive}\n onChange={setShowInactive}\n colorPalette=\"primary\"\n >\n Inactive\n </ToggleButton>\n\n <ToggleButton\n size=\"xs\"\n variant=\"outline\"\n isSelected={showArchived}\n onChange={setShowArchived}\n colorPalette=\"primary\"\n >\n Archived\n </ToggleButton>\n </Stack>\n <Text fontSize=\"sm\" color=\"neutral.11\">\n Showing: {getStatusText()}\n </Text>\n </Stack>\n );\n}\n```\n\n### Settings toggles\n\nPattern for settings or preferences with immediate visual feedback:\n\n```jsx live-dev\nconst App = () => {\n const [emailNotifications, setEmailNotifications] = useState(true);\n const [pushNotifications, setPushNotifications] = useState(false);\n const [weeklyDigest, setWeeklyDigest] = useState(true);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Text fontWeight=\"semibold\">Notification Preferences</Text>\n\n <Stack direction=\"row\" gap=\"300\" alignItems=\"center\">\n <ToggleButton\n variant=\"ghost\"\n size=\"xs\"\n isSelected={emailNotifications}\n onChange={setEmailNotifications}\n aria-label=\"Toggle email notifications\"\n >\n <Icons.Email />\n </ToggleButton>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"medium\">\n Email Notifications\n </Text>\n <Text fontSize=\"xs\" color=\"neutral.11\">\n {emailNotifications ? \"Enabled\" : \"Disabled\"}\n </Text>\n </Stack>\n </Stack>\n\n <Stack direction=\"row\" gap=\"300\" alignItems=\"center\">\n <ToggleButton\n variant=\"ghost\"\n size=\"xs\"\n isSelected={pushNotifications}\n onChange={setPushNotifications}\n aria-label=\"Toggle push notifications\"\n >\n <Icons.Notifications />\n </ToggleButton>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"medium\">\n Push Notifications\n </Text>\n <Text fontSize=\"xs\" color=\"neutral.11\">\n {pushNotifications ? \"Enabled\" : \"Disabled\"}\n </Text>\n </Stack>\n </Stack>\n\n <Stack direction=\"row\" gap=\"300\" alignItems=\"center\">\n <ToggleButton\n variant=\"ghost\"\n size=\"xs\"\n isSelected={weeklyDigest}\n onChange={setWeeklyDigest}\n aria-label=\"Toggle weekly digest\"\n >\n <Icons.CalendarToday />\n </ToggleButton>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"medium\">\n Weekly Digest\n </Text>\n <Text fontSize=\"xs\" color=\"neutral.11\">\n {weeklyDigest ? \"Enabled\" : \"Disabled\"}\n </Text>\n </Stack>\n </Stack>\n </Stack>\n );\n}\n```\n\n## Testing your implementation\n\nThese examples demonstrate how to test your implementation when using ToggleButton within your application. As the component's internal functionality is already tested by Nimbus, these patterns help you verify your integration and application-specific logic.\n\n### Basic rendering tests\n\nVerify the component renders with expected elements and states\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Basic rendering\", () => {\n it(\"renders toggle button with text content\", () => {\n render(\n <NimbusProvider>\n <ToggleButton>Toggle Me</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\", { name: /toggle me/i });\n expect(button).toBeInTheDocument();\n });\n\n it(\"renders in unselected state by default\", () => {\n render(\n <NimbusProvider>\n <ToggleButton>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n });\n\n it(\"renders with icon and text\", () => {\n render(\n <NimbusProvider>\n <ToggleButton>\n <svg data-testid=\"test-icon\" />\n Like\n </ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByTestId(\"test-icon\")).toBeInTheDocument();\n expect(screen.getByRole(\"button\", { name: /like/i })).toBeInTheDocument();\n });\n\n it(\"renders with different sizes\", () => {\n const { rerender } = render(\n <NimbusProvider>\n <ToggleButton size=\"2xs\">Extra Small</ToggleButton>\n </NimbusProvider>\n );\n\n let button = screen.getByRole(\"button\");\n expect(button).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton size=\"xs\">Small</ToggleButton>\n </NimbusProvider>\n );\n\n button = screen.getByRole(\"button\");\n expect(button).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton size=\"md\">Medium</ToggleButton>\n </NimbusProvider>\n );\n\n button = screen.getByRole(\"button\");\n expect(button).toBeInTheDocument();\n });\n});\n```\n\n### Interaction Tests\n\nTest user interactions with the toggle button\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Interactions\", () => {\n it(\"toggles state when clicked\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton onChange={handleChange}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n\n // Click to select\n await user.click(button);\n expect(handleChange).toHaveBeenCalledWith(true);\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n\n // Click to unselect\n await user.click(button);\n expect(handleChange).toHaveBeenCalledWith(false);\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n });\n\n it(\"toggles with keyboard (Enter)\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton onChange={handleChange}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n // Use userEvent.tab() instead of element.focus() to avoid act() warnings\n await user.tab();\n await user.keyboard(\"{Enter}\");\n expect(handleChange).toHaveBeenCalledWith(true);\n });\n\n it(\"toggles with keyboard (Space)\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton onChange={handleChange}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n // Use userEvent.tab() instead of element.focus() to avoid act() warnings\n await user.tab();\n await user.keyboard(\" \");\n expect(handleChange).toHaveBeenCalledWith(true);\n });\n\n it(\"is focusable with Tab key\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <ToggleButton>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).not.toHaveFocus();\n\n await user.tab();\n expect(button).toHaveFocus();\n });\n});\n```\n\n### Controlled Mode Tests\n\nTest controlled toggle button behavior\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Controlled mode\", () => {\n it(\"respects controlled isSelected prop\", () => {\n const { rerender } = render(\n <NimbusProvider>\n <ToggleButton isSelected={false} onChange={vi.fn()}>\n Toggle\n </ToggleButton>\n </NimbusProvider>\n );\n\n let button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n\n rerender(\n <NimbusProvider>\n <ToggleButton isSelected={true} onChange={vi.fn()}>\n Toggle\n </ToggleButton>\n </NimbusProvider>\n );\n\n button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n\n it(\"calls onChange when clicked in controlled mode\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton isSelected={false} onChange={handleChange}>\n Toggle\n </ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n await user.click(button);\n\n expect(handleChange).toHaveBeenCalledWith(true);\n });\n});\n```\n\n### Uncontrolled Mode Tests\n\nTest uncontrolled toggle button behavior\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Uncontrolled mode\", () => {\n it(\"starts with defaultSelected value\", () => {\n render(\n <NimbusProvider>\n <ToggleButton defaultSelected={true}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n\n it(\"manages internal state when uncontrolled\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton defaultSelected={false} onChange={handleChange}>\n Toggle\n </ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n\n await user.click(button);\n expect(handleChange).toHaveBeenCalledWith(true);\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n\n await user.click(button);\n expect(handleChange).toHaveBeenCalledWith(false);\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n });\n});\n```\n\n### State Tests\n\nTest different states like disabled\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - States\", () => {\n it(\"renders disabled state\", () => {\n render(\n <NimbusProvider>\n <ToggleButton isDisabled>Disabled</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toBeDisabled();\n });\n\n it(\"does not respond to clicks when disabled\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton isDisabled onChange={handleChange}>\n Disabled\n </ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n await user.click(button);\n\n expect(handleChange).not.toHaveBeenCalled();\n });\n\n it(\"cannot receive focus when disabled\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <ToggleButton isDisabled>Disabled</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n await user.tab();\n\n expect(button).not.toHaveFocus();\n });\n\n it(\"renders selected state\", () => {\n render(\n <NimbusProvider>\n <ToggleButton isSelected>Selected</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n});\n```\n\n### Visual Variant Tests\n\nTest different visual variants and color palettes\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Variants\", () => {\n it(\"renders outline variant\", () => {\n render(\n <NimbusProvider>\n <ToggleButton variant=\"outline\">Outline</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n\n it(\"renders ghost variant\", () => {\n render(\n <NimbusProvider>\n <ToggleButton variant=\"ghost\">Ghost</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n\n it(\"renders with different color palettes\", () => {\n const { rerender } = render(\n <NimbusProvider>\n <ToggleButton colorPalette=\"primary\">Primary</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton colorPalette=\"neutral\">Neutral</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton colorPalette=\"critical\">Critical</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton colorPalette=\"info\">Info</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n});\n```\n\n### Accessibility Tests\n\nTest ARIA attributes and keyboard accessibility\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Accessibility\", () => {\n it(\"has proper button role\", () => {\n render(\n <NimbusProvider>\n <ToggleButton>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n\n it(\"has aria-pressed attribute\", () => {\n render(\n <NimbusProvider>\n <ToggleButton isSelected={false}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n });\n\n it(\"updates aria-pressed when toggled\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <ToggleButton defaultSelected={false}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n\n await user.click(button);\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n\n it(\"supports aria-label for icon-only buttons\", () => {\n render(\n <NimbusProvider>\n <ToggleButton aria-label=\"Add to favorites\">\n <svg data-testid=\"icon\" />\n </ToggleButton>\n </NimbusProvider>\n );\n\n expect(\n screen.getByRole(\"button\", { name: /add to favorites/i })\n ).toBeInTheDocument();\n });\n\n it(\"is keyboard accessible\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton onChange={handleChange}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n\n // Focus with Tab\n await user.tab();\n expect(button).toHaveFocus();\n\n // Activate with Enter\n await user.keyboard(\"{Enter}\");\n expect(handleChange).toHaveBeenCalledWith(true);\n });\n});\n```\n\n\n## Resources\n\n- [Storybook](https://nimbus-storybook.vercel.app/?path=/docs/components-buttons-togglebutton--docs)\n- [React Aria ToggleButton](https://react-spectrum.adobe.com/react-aria/ToggleButton.html)\n- [ARIA Button Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/button/)\n- [Button Component](/components/buttons/button)\n",
379
+ "mdx": "\n## Getting started\n\n### Import\n\n```tsx\nimport { ToggleButton, type ToggleButtonProps } from '@commercetools/nimbus';\n```\n\n### Basic usage\n\nThe simplest implementation uses the uncontrolled mode with `defaultSelected`:\n\n```jsx live-dev\nconst App = () => (\n <ToggleButton\n defaultSelected={false}\n onChange={(isSelected) => alert(`Selected: ${isSelected}`)}\n >\n Toggle Me\n </ToggleButton>\n)\n```\n\nThe component starts in the unselected state and manages its own state internally. The `onChange` callback is called whenever the selection state changes.\n\n## Usage examples\n\n### Controlled mode\n\nControl the toggle state externally using `isSelected` and `onChange`:\n\n```jsx live-dev\nconst App = () => {\n const [isSelected, setIsSelected] = useState<ToggleButtonProps[\"isSelected\"]>(false);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <ToggleButton isSelected={isSelected} onChange={setIsSelected}>\n {isSelected ? \"Selected\" : \"Not Selected\"}\n </ToggleButton>\n <Text fontSize=\"sm\">\n Current state: {isSelected ? \"Selected\" : \"Not Selected\"}\n </Text>\n </Stack>\n );\n}\n```\n\n### With icons\n\nAdd icons to provide visual context for the toggle action:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton onChange={(selected) => alert(`Liked: ${selected}`)}>\n <Icons.ThumbUp />\n Like\n </ToggleButton>\n\n <ToggleButton onChange={(selected) => alert(`Favorited: ${selected}`)}>\n <Icons.Star />\n Favorite\n </ToggleButton>\n\n <ToggleButton onChange={(selected) => alert(`Saved: ${selected}`)}>\n <Icons.Bookmark />\n Save\n </ToggleButton>\n\n <ToggleButton onChange={(selected) => alert(`Notified: ${selected}`)}>\n <Icons.Notifications />\n Notify\n </ToggleButton>\n </Stack>\n)\n```\n\n### Size variants\n\nThe component supports five size variants (`2xs`, `xs`, `sm`, `md`, `xl`) to\nmatch your interface density — the same scale as `Button`:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"row\" gap=\"400\" alignItems=\"center\" wrap=\"wrap\">\n <ToggleButton size=\"2xs\">\n 2x Small\n </ToggleButton>\n\n <ToggleButton size=\"xs\">\n Extra Small\n </ToggleButton>\n\n <ToggleButton size=\"sm\">\n Small\n </ToggleButton>\n\n <ToggleButton size=\"md\">\n Medium (default)\n </ToggleButton>\n\n <ToggleButton size=\"xl\">\n Extra Large\n </ToggleButton>\n </Stack>\n)\n```\n\n### Visual variants\n\nThe `variant` prop controls the resting chrome. In every variant the resting\nbutton is neutral — `colorPalette` is reserved for the active (selected) state\n(see \"Color palettes\" below). Choose the variant that matches your surface:\n\n- `outline` (default): a neutral border over a transparent fill.\n- `ghost`: no border and no fill until hover — good for dense toolbars.\n- `subtle`: a filled neutral chip at rest.\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton variant=\"outline\">\n Outline (default)\n </ToggleButton>\n\n <ToggleButton variant=\"outline\" isSelected>\n Outline Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton variant=\"ghost\">\n Ghost\n </ToggleButton>\n\n <ToggleButton variant=\"ghost\" isSelected>\n Ghost Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton variant=\"subtle\">\n Subtle\n </ToggleButton>\n\n <ToggleButton variant=\"subtle\" isSelected>\n Subtle Selected\n </ToggleButton>\n </Stack>\n </Stack>\n)\n```\n\n### Active fill style\n\n`activeFillStyle` controls the weight of the active (selected) fill. It is\nindependent of `variant`, which only styles the resting state.\n\n- `tint` (default): a light accent wash — `colorPalette.5` fill with\n `colorPalette.12` text.\n- `solid`: a full accent fill — `colorPalette.9` fill with contrast text.\n\nUse `tint` for multi-select sets where several buttons can be on at once, and\n`solid` when a single choice should stand out.\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton activeFillStyle=\"tint\" isSelected>\n Tint (default)\n </ToggleButton>\n\n <ToggleButton activeFillStyle=\"solid\" isSelected>\n Solid\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"primary\" activeFillStyle=\"tint\" isSelected>\n Primary tint\n </ToggleButton>\n\n <ToggleButton colorPalette=\"primary\" activeFillStyle=\"solid\" isSelected>\n Primary solid\n </ToggleButton>\n </Stack>\n </Stack>\n)\n```\n\n### Color palettes\n\n`colorPalette` tints the **active (selected)** state — the resting button stays\nneutral, so the palette only shows once a button is selected. Use different color\npalettes to indicate different types of actions:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"primary\">\n Primary\n </ToggleButton>\n <ToggleButton colorPalette=\"primary\" isSelected>\n Primary Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"neutral\">\n Neutral\n </ToggleButton>\n <ToggleButton colorPalette=\"neutral\" isSelected>\n Neutral Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"critical\">\n Critical\n </ToggleButton>\n <ToggleButton colorPalette=\"critical\" isSelected>\n Critical Selected\n </ToggleButton>\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton colorPalette=\"info\">\n Info\n </ToggleButton>\n <ToggleButton colorPalette=\"info\" isSelected>\n Info Selected\n </ToggleButton>\n </Stack>\n </Stack>\n)\n```\n\n### Disabled state\n\nDisable the toggle button to prevent user interaction:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"row\" gap=\"400\" wrap=\"wrap\">\n <ToggleButton isDisabled>\n Disabled Unselected\n </ToggleButton>\n\n <ToggleButton isDisabled isSelected>\n Disabled Selected\n </ToggleButton>\n\n <ToggleButton isDisabled variant=\"ghost\">\n <Icons.Star />\n Disabled Ghost\n </ToggleButton>\n </Stack>\n)\n```\n\n## Component requirements\n\n## Accessibility\n\nThe ToggleButton component is built on React Aria's ToggleButton, which provides robust accessibility features out of the box.\n\n**Role**: The component uses the `button` role with `aria-pressed` attribute to communicate toggle state.\n\n**Labeling**: The button's label is determined by its children content. For icon-only buttons, provide an `aria-label`:\n\n```tsx\n<ToggleButton aria-label=\"Add to favorites\">\n <Icons.Star />\n</ToggleButton>\n```\n\nIf your use case requires tracking and analytics for this component, it is good practice to add a **persistent**, **unique** id to the component:\n\n```tsx\nconst PERSISTENT_ID = \"like-button-toggle\";\n\nexport const LikeButton = () => (\n <ToggleButton\n id={PERSISTENT_ID}\n aria-label=\"Like this post\"\n onChange={handleLikeToggle}\n >\n <Icons.ThumbUp />\n </ToggleButton>\n);\n```\n\n#### Keyboard navigation\n\nThe component supports full keyboard interaction:\n- `Tab`: Move focus to/from the toggle button\n- `Enter` or `Space`: Toggle the selected state\n\n## API reference\n\n<PropsTable id=\"ToggleButton\" />\n\n## Common patterns\n\n### Like/Favorite functionality\n\nCommon pattern for like or favorite actions with visual feedback:\n\n```jsx live-dev\nconst App = () => {\n const [liked, setLiked] = useState(false);\n const [favorited, setFavorited] = useState(false);\n const [saved, setSaved] = useState(false);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"row\" gap=\"400\" alignItems=\"center\">\n <ToggleButton\n isSelected={liked}\n onChange={setLiked}\n colorPalette=\"critical\"\n aria-label=\"Like post\"\n >\n <Icons.ThumbUp />\n {liked ? \"Liked\" : \"Like\"}\n </ToggleButton>\n {liked && (\n <Text fontSize=\"sm\" color=\"critical.11\">\n Thank you for your feedback!\n </Text>\n )}\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" alignItems=\"center\">\n <ToggleButton\n isSelected={favorited}\n onChange={setFavorited}\n colorPalette=\"info\"\n aria-label=\"Add to favorites\"\n >\n <Icons.Star />\n {favorited ? \"Favorited\" : \"Favorite\"}\n </ToggleButton>\n {favorited && (\n <Text fontSize=\"sm\" color=\"info.11\">\n Added to your favorites\n </Text>\n )}\n </Stack>\n\n <Stack direction=\"row\" gap=\"400\" alignItems=\"center\">\n <ToggleButton\n isSelected={saved}\n onChange={setSaved}\n aria-label=\"Save for later\"\n >\n <Icons.Bookmark />\n {saved ? \"Saved\" : \"Save\"}\n </ToggleButton>\n {saved && (\n <Text fontSize=\"sm\" color=\"neutral.11\">\n Saved for later\n </Text>\n )}\n </Stack>\n </Stack>\n );\n}\n```\n\n### Filter toggles\n\nUse toggle buttons as filter controls in a toolbar or filter panel:\n\n```jsx live-dev\nconst App = () => {\n const [showActive, setShowActive] = useState(true);\n const [showInactive, setShowInactive] = useState(false);\n const [showArchived, setShowArchived] = useState(false);\n\n const getStatusText = () => {\n const statuses = [];\n if (showActive) statuses.push(\"Active\");\n if (showInactive) statuses.push(\"Inactive\");\n if (showArchived) statuses.push(\"Archived\");\n return statuses.length > 0 ? statuses.join(\", \") : \"None\";\n };\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Text fontWeight=\"semibold\">Filter by status:</Text>\n <Stack direction=\"row\" gap=\"300\" wrap=\"wrap\">\n <ToggleButton\n size=\"xs\"\n variant=\"outline\"\n isSelected={showActive}\n onChange={setShowActive}\n colorPalette=\"primary\"\n >\n Active\n </ToggleButton>\n\n <ToggleButton\n size=\"xs\"\n variant=\"outline\"\n isSelected={showInactive}\n onChange={setShowInactive}\n colorPalette=\"primary\"\n >\n Inactive\n </ToggleButton>\n\n <ToggleButton\n size=\"xs\"\n variant=\"outline\"\n isSelected={showArchived}\n onChange={setShowArchived}\n colorPalette=\"primary\"\n >\n Archived\n </ToggleButton>\n </Stack>\n <Text fontSize=\"sm\" color=\"neutral.11\">\n Showing: {getStatusText()}\n </Text>\n </Stack>\n );\n}\n```\n\n### Settings toggles\n\nPattern for settings or preferences with immediate visual feedback:\n\n```jsx live-dev\nconst App = () => {\n const [emailNotifications, setEmailNotifications] = useState(true);\n const [pushNotifications, setPushNotifications] = useState(false);\n const [weeklyDigest, setWeeklyDigest] = useState(true);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Text fontWeight=\"semibold\">Notification Preferences</Text>\n\n <Stack direction=\"row\" gap=\"300\" alignItems=\"center\">\n <ToggleButton\n variant=\"ghost\"\n size=\"xs\"\n isSelected={emailNotifications}\n onChange={setEmailNotifications}\n aria-label=\"Toggle email notifications\"\n >\n <Icons.Email />\n </ToggleButton>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"medium\">\n Email Notifications\n </Text>\n <Text fontSize=\"xs\" color=\"neutral.11\">\n {emailNotifications ? \"Enabled\" : \"Disabled\"}\n </Text>\n </Stack>\n </Stack>\n\n <Stack direction=\"row\" gap=\"300\" alignItems=\"center\">\n <ToggleButton\n variant=\"ghost\"\n size=\"xs\"\n isSelected={pushNotifications}\n onChange={setPushNotifications}\n aria-label=\"Toggle push notifications\"\n >\n <Icons.Notifications />\n </ToggleButton>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"medium\">\n Push Notifications\n </Text>\n <Text fontSize=\"xs\" color=\"neutral.11\">\n {pushNotifications ? \"Enabled\" : \"Disabled\"}\n </Text>\n </Stack>\n </Stack>\n\n <Stack direction=\"row\" gap=\"300\" alignItems=\"center\">\n <ToggleButton\n variant=\"ghost\"\n size=\"xs\"\n isSelected={weeklyDigest}\n onChange={setWeeklyDigest}\n aria-label=\"Toggle weekly digest\"\n >\n <Icons.CalendarToday />\n </ToggleButton>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"medium\">\n Weekly Digest\n </Text>\n <Text fontSize=\"xs\" color=\"neutral.11\">\n {weeklyDigest ? \"Enabled\" : \"Disabled\"}\n </Text>\n </Stack>\n </Stack>\n </Stack>\n );\n}\n```\n\n## Testing your implementation\n\nThese examples demonstrate how to test your implementation when using ToggleButton within your application. As the component's internal functionality is already tested by Nimbus, these patterns help you verify your integration and application-specific logic.\n\n### Basic rendering tests\n\nVerify the component renders with expected elements and states\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Basic rendering\", () => {\n it(\"renders toggle button with text content\", () => {\n render(\n <NimbusProvider>\n <ToggleButton>Toggle Me</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\", { name: /toggle me/i });\n expect(button).toBeInTheDocument();\n });\n\n it(\"renders in unselected state by default\", () => {\n render(\n <NimbusProvider>\n <ToggleButton>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n });\n\n it(\"renders with icon and text\", () => {\n render(\n <NimbusProvider>\n <ToggleButton>\n <svg data-testid=\"test-icon\" />\n Like\n </ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByTestId(\"test-icon\")).toBeInTheDocument();\n expect(screen.getByRole(\"button\", { name: /like/i })).toBeInTheDocument();\n });\n\n it(\"renders with different sizes\", () => {\n const { rerender } = render(\n <NimbusProvider>\n <ToggleButton size=\"2xs\">Extra Small</ToggleButton>\n </NimbusProvider>\n );\n\n let button = screen.getByRole(\"button\");\n expect(button).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton size=\"xs\">Small</ToggleButton>\n </NimbusProvider>\n );\n\n button = screen.getByRole(\"button\");\n expect(button).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton size=\"md\">Medium</ToggleButton>\n </NimbusProvider>\n );\n\n button = screen.getByRole(\"button\");\n expect(button).toBeInTheDocument();\n });\n});\n```\n\n### Interaction Tests\n\nTest user interactions with the toggle button\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Interactions\", () => {\n it(\"toggles state when clicked\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton onChange={handleChange}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n\n // Click to select\n await user.click(button);\n expect(handleChange).toHaveBeenCalledWith(true);\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n\n // Click to unselect\n await user.click(button);\n expect(handleChange).toHaveBeenCalledWith(false);\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n });\n\n it(\"toggles with keyboard (Enter)\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton onChange={handleChange}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n // Use userEvent.tab() instead of element.focus() to avoid act() warnings\n await user.tab();\n await user.keyboard(\"{Enter}\");\n expect(handleChange).toHaveBeenCalledWith(true);\n });\n\n it(\"toggles with keyboard (Space)\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton onChange={handleChange}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n // Use userEvent.tab() instead of element.focus() to avoid act() warnings\n await user.tab();\n await user.keyboard(\" \");\n expect(handleChange).toHaveBeenCalledWith(true);\n });\n\n it(\"is focusable with Tab key\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <ToggleButton>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).not.toHaveFocus();\n\n await user.tab();\n expect(button).toHaveFocus();\n });\n});\n```\n\n### Controlled Mode Tests\n\nTest controlled toggle button behavior\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Controlled mode\", () => {\n it(\"respects controlled isSelected prop\", () => {\n const { rerender } = render(\n <NimbusProvider>\n <ToggleButton isSelected={false} onChange={vi.fn()}>\n Toggle\n </ToggleButton>\n </NimbusProvider>\n );\n\n let button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n\n rerender(\n <NimbusProvider>\n <ToggleButton isSelected={true} onChange={vi.fn()}>\n Toggle\n </ToggleButton>\n </NimbusProvider>\n );\n\n button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n\n it(\"calls onChange when clicked in controlled mode\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton isSelected={false} onChange={handleChange}>\n Toggle\n </ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n await user.click(button);\n\n expect(handleChange).toHaveBeenCalledWith(true);\n });\n});\n```\n\n### Uncontrolled Mode Tests\n\nTest uncontrolled toggle button behavior\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Uncontrolled mode\", () => {\n it(\"starts with defaultSelected value\", () => {\n render(\n <NimbusProvider>\n <ToggleButton defaultSelected={true}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n\n it(\"manages internal state when uncontrolled\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton defaultSelected={false} onChange={handleChange}>\n Toggle\n </ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n\n await user.click(button);\n expect(handleChange).toHaveBeenCalledWith(true);\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n\n await user.click(button);\n expect(handleChange).toHaveBeenCalledWith(false);\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n });\n});\n```\n\n### State Tests\n\nTest different states like disabled\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - States\", () => {\n it(\"renders disabled state\", () => {\n render(\n <NimbusProvider>\n <ToggleButton isDisabled>Disabled</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toBeDisabled();\n });\n\n it(\"does not respond to clicks when disabled\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton isDisabled onChange={handleChange}>\n Disabled\n </ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n await user.click(button);\n\n expect(handleChange).not.toHaveBeenCalled();\n });\n\n it(\"cannot receive focus when disabled\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <ToggleButton isDisabled>Disabled</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n await user.tab();\n\n expect(button).not.toHaveFocus();\n });\n\n it(\"renders selected state\", () => {\n render(\n <NimbusProvider>\n <ToggleButton isSelected>Selected</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n});\n```\n\n### Visual Variant Tests\n\nTest different visual variants and color palettes\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Variants\", () => {\n it(\"renders outline variant\", () => {\n render(\n <NimbusProvider>\n <ToggleButton variant=\"outline\">Outline</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n\n it(\"renders ghost variant\", () => {\n render(\n <NimbusProvider>\n <ToggleButton variant=\"ghost\">Ghost</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n\n it(\"renders subtle variant\", () => {\n render(\n <NimbusProvider>\n <ToggleButton variant=\"subtle\">Subtle</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n\n it(\"renders both active fill styles when selected\", () => {\n const { rerender } = render(\n <NimbusProvider>\n <ToggleButton activeFillStyle=\"tint\" isSelected>\n Tint\n </ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toHaveAttribute(\"aria-pressed\", \"true\");\n\n rerender(\n <NimbusProvider>\n <ToggleButton activeFillStyle=\"solid\" isSelected>\n Solid\n </ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n\n it(\"renders with different color palettes\", () => {\n const { rerender } = render(\n <NimbusProvider>\n <ToggleButton colorPalette=\"primary\">Primary</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton colorPalette=\"neutral\">Neutral</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton colorPalette=\"critical\">Critical</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <ToggleButton colorPalette=\"info\">Info</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n});\n```\n\n### Accessibility Tests\n\nTest ARIA attributes and keyboard accessibility\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { ToggleButton, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"ToggleButton - Accessibility\", () => {\n it(\"has proper button role\", () => {\n render(\n <NimbusProvider>\n <ToggleButton>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"button\")).toBeInTheDocument();\n });\n\n it(\"has aria-pressed attribute\", () => {\n render(\n <NimbusProvider>\n <ToggleButton isSelected={false}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n });\n\n it(\"updates aria-pressed when toggled\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <ToggleButton defaultSelected={false}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n expect(button).toHaveAttribute(\"aria-pressed\", \"false\");\n\n await user.click(button);\n expect(button).toHaveAttribute(\"aria-pressed\", \"true\");\n });\n\n it(\"supports aria-label for icon-only buttons\", () => {\n render(\n <NimbusProvider>\n <ToggleButton aria-label=\"Add to favorites\">\n <svg data-testid=\"icon\" />\n </ToggleButton>\n </NimbusProvider>\n );\n\n expect(\n screen.getByRole(\"button\", { name: /add to favorites/i })\n ).toBeInTheDocument();\n });\n\n it(\"is keyboard accessible\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n\n render(\n <NimbusProvider>\n <ToggleButton onChange={handleChange}>Toggle</ToggleButton>\n </NimbusProvider>\n );\n\n const button = screen.getByRole(\"button\");\n\n // Focus with Tab\n await user.tab();\n expect(button).toHaveFocus();\n\n // Activate with Enter\n await user.keyboard(\"{Enter}\");\n expect(handleChange).toHaveBeenCalledWith(true);\n });\n});\n```\n\n\n## Resources\n\n- [Storybook](https://nimbus-storybook.vercel.app/?path=/docs/components-buttons-togglebutton--docs)\n- [React Aria ToggleButton](https://react-spectrum.adobe.com/react-aria/ToggleButton.html)\n- [ARIA Button Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/button/)\n- [Button Component](/components/buttons/button)\n",
334
380
  "toc": [
335
381
  {
336
382
  "value": "Getting started",
@@ -418,6 +464,17 @@
418
464
  ],
419
465
  "parent": "root"
420
466
  },
467
+ {
468
+ "value": "Active fill style",
469
+ "href": "#active-fill-style",
470
+ "depth": 3,
471
+ "numbering": [
472
+ 1,
473
+ 2,
474
+ 5
475
+ ],
476
+ "parent": "root"
477
+ },
421
478
  {
422
479
  "value": "Color palettes",
423
480
  "href": "#color-palettes",
@@ -425,7 +482,7 @@
425
482
  "numbering": [
426
483
  1,
427
484
  2,
428
- 5
485
+ 6
429
486
  ],
430
487
  "parent": "root"
431
488
  },
@@ -436,7 +493,7 @@
436
493
  "numbering": [
437
494
  1,
438
495
  2,
439
- 6
496
+ 7
440
497
  ],
441
498
  "parent": "root"
442
499
  },
@@ -0,0 +1,36 @@
1
+ {
2
+ "meta": {
3
+ "id": "Components-Chat",
4
+ "title": "Chat",
5
+ "description": "Components for building AI chat conversations.",
6
+ "order": 999,
7
+ "repoPath": "packages/nimbus/src/docs/chat.mdx",
8
+ "menu": [
9
+ "Components",
10
+ "Chat"
11
+ ],
12
+ "route": "components/chat",
13
+ "tags": [
14
+ "chat",
15
+ "ai",
16
+ "conversation"
17
+ ],
18
+ "toc": [],
19
+ "icon": "Forum",
20
+ "layout": "app-frame",
21
+ "tabs": [
22
+ {
23
+ "key": "overview",
24
+ "title": "Overview",
25
+ "order": 0
26
+ }
27
+ ]
28
+ },
29
+ "mdx": "\n# Chat\n\nComponents for building AI chat conversations.\n\n<CategoryOverview variant=\"list\" />\n",
30
+ "views": {
31
+ "overview": {
32
+ "mdx": "\n# Chat\n\nComponents for building AI chat conversations.\n\n<CategoryOverview variant=\"list\" />\n",
33
+ "toc": []
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "meta": {
3
+ "id": "Components-Content",
4
+ "title": "Content",
5
+ "description": "Components for rendering and displaying rich content.",
6
+ "order": 999,
7
+ "repoPath": "packages/nimbus/src/docs/content.mdx",
8
+ "menu": [
9
+ "Components",
10
+ "Content"
11
+ ],
12
+ "route": "components/content",
13
+ "tags": [
14
+ "content",
15
+ "markdown",
16
+ "rendering"
17
+ ],
18
+ "toc": [],
19
+ "icon": "Article",
20
+ "layout": "app-frame",
21
+ "tabs": [
22
+ {
23
+ "key": "overview",
24
+ "title": "Overview",
25
+ "order": 0
26
+ }
27
+ ]
28
+ },
29
+ "mdx": "\n# Content\n\nComponents for rendering and displaying rich content.\n\n<CategoryOverview variant=\"list\" />\n",
30
+ "views": {
31
+ "overview": {
32
+ "mdx": "\n# Content\n\nComponents for rendering and displaying rich content.\n\n<CategoryOverview variant=\"list\" />\n",
33
+ "toc": []
34
+ }
35
+ }
36
+ }