@commercetools/nimbus-mcp 3.3.0 → 3.5.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 (199) hide show
  1. package/data/docs/route-manifest.json +714 -14
  2. package/data/docs/routes/components-data-display-data-table.json +172 -14
  3. package/data/docs/routes/components-data-display-item-group.json +413 -0
  4. package/data/docs/routes/components-data-display-item.json +611 -0
  5. package/data/docs/routes/components-feedback-skeleton.json +481 -0
  6. package/data/docs/routes/components-feedback-skeletoncircle.json +429 -0
  7. package/data/docs/routes/components-feedback-skeletontext.json +417 -0
  8. package/data/docs/routes/components-inputs-range-slider.json +633 -0
  9. package/data/docs/routes/components-inputs-slider.json +611 -0
  10. package/data/docs/routes/components-navigation-breadcrumbs.json +565 -0
  11. package/data/docs/routes/home-getting-started-installation.json +2 -2
  12. package/data/docs/routes/icons.json +3 -3
  13. package/data/docs/search-index.json +1 -1
  14. package/data/docs/types/AccordionContent.json +27 -27
  15. package/data/docs/types/AccordionHeader.json +89 -89
  16. package/data/docs/types/AccordionItem.json +22 -22
  17. package/data/docs/types/AccordionRoot.json +14 -14
  18. package/data/docs/types/ActivityIndicator.json +2 -2
  19. package/data/docs/types/AlertDescription.json +8 -8
  20. package/data/docs/types/AlertDismissButton.json +80 -80
  21. package/data/docs/types/AlertTitle.json +8 -8
  22. package/data/docs/types/Avatar.json +2 -2
  23. package/data/docs/types/Badge.json +3 -3
  24. package/data/docs/types/Body.json +6 -6
  25. package/data/docs/types/Box.json +6 -6
  26. package/data/docs/types/Breadcrumbs.json +12 -0
  27. package/data/docs/types/BreadcrumbsItem.json +296 -0
  28. package/data/docs/types/BreadcrumbsItemProps.json +9 -0
  29. package/data/docs/types/BreadcrumbsProps.json +9 -0
  30. package/data/docs/types/BreadcrumbsRoot.json +110 -0
  31. package/data/docs/types/Button.json +88 -88
  32. package/data/docs/types/Calendar.json +56 -56
  33. package/data/docs/types/Caption.json +6 -6
  34. package/data/docs/types/CardRoot.json +2 -2
  35. package/data/docs/types/Cell.json +20 -20
  36. package/data/docs/types/ChatMessageAvatar.json +2 -2
  37. package/data/docs/types/ChatMessageListRoot.json +2 -2
  38. package/data/docs/types/ChatMessageRoot.json +2 -2
  39. package/data/docs/types/Checkbox.json +88 -88
  40. package/data/docs/types/Code.json +10 -10
  41. package/data/docs/types/CollapsibleMotionContent.json +2 -2
  42. package/data/docs/types/CollapsibleMotionRoot.json +2 -2
  43. package/data/docs/types/CollapsibleMotionTrigger.json +4 -4
  44. package/data/docs/types/Column.json +8 -8
  45. package/data/docs/types/ColumnGroup.json +8 -8
  46. package/data/docs/types/ColumnHeader.json +18 -18
  47. package/data/docs/types/ComboBoxListBox.json +70 -70
  48. package/data/docs/types/ComboBoxOption.json +64 -64
  49. package/data/docs/types/ComboBoxPopover.json +148 -72
  50. package/data/docs/types/ComboBoxRoot.json +8 -8
  51. package/data/docs/types/ComboBoxSection.json +25 -25
  52. package/data/docs/types/ComboBoxTrigger.json +6 -6
  53. package/data/docs/types/Content.json +2 -2
  54. package/data/docs/types/DataTable.json +38 -23
  55. package/data/docs/types/DataTableBody.json +60 -79
  56. package/data/docs/types/DataTableCell.json +434 -0
  57. package/data/docs/types/DataTableColumn.json +540 -0
  58. package/data/docs/types/DataTableHeader.json +62 -85
  59. package/data/docs/types/DataTableRoot.json +38 -23
  60. package/data/docs/types/DataTableRow.json +790 -0
  61. package/data/docs/types/DataTableTable.json +20 -20
  62. package/data/docs/types/DateInput.json +72 -72
  63. package/data/docs/types/DatePicker.json +58 -58
  64. package/data/docs/types/DateRangePicker.json +86 -86
  65. package/data/docs/types/DateRangePickerField.json +86 -86
  66. package/data/docs/types/DefaultPageBackLink.json +16 -16
  67. package/data/docs/types/DefaultPageRoot.json +2 -2
  68. package/data/docs/types/DialogCloseTrigger.json +78 -78
  69. package/data/docs/types/DialogTrigger.json +2 -2
  70. package/data/docs/types/DraggableListField.json +62 -62
  71. package/data/docs/types/DraggableListItem.json +100 -53
  72. package/data/docs/types/DraggableListRoot.json +62 -62
  73. package/data/docs/types/DrawerCloseTrigger.json +78 -78
  74. package/data/docs/types/DrawerTrigger.json +2 -2
  75. package/data/docs/types/DropZone.json +14 -14
  76. package/data/docs/types/FieldErrors.json +2 -2
  77. package/data/docs/types/Flex.json +22 -22
  78. package/data/docs/types/FloatingActionButton.json +88 -88
  79. package/data/docs/types/Footer.json +6 -6
  80. package/data/docs/types/FormFieldRoot.json +2 -2
  81. package/data/docs/types/Grid.json +24 -24
  82. package/data/docs/types/Group.json +12 -12
  83. package/data/docs/types/Header.json +6 -6
  84. package/data/docs/types/Heading.json +8 -8
  85. package/data/docs/types/Icon.json +4 -4
  86. package/data/docs/types/IconButton.json +88 -88
  87. package/data/docs/types/IconToggleButton.json +72 -72
  88. package/data/docs/types/Image.json +30 -30
  89. package/data/docs/types/Indicator.json +6 -6
  90. package/data/docs/types/InlineSvg.json +2 -2
  91. package/data/docs/types/Item.json +6 -6
  92. package/data/docs/types/ItemActions.json +27 -0
  93. package/data/docs/types/ItemContent.json +27 -0
  94. package/data/docs/types/ItemDescription.json +27 -0
  95. package/data/docs/types/ItemFooter.json +27 -0
  96. package/data/docs/types/ItemGroup.json +12 -0
  97. package/data/docs/types/ItemGroupRoot.json +27 -0
  98. package/data/docs/types/ItemGroupSeparator.json +27 -0
  99. package/data/docs/types/ItemHeader.json +27 -0
  100. package/data/docs/types/ItemMedia.json +56 -0
  101. package/data/docs/types/ItemRoot.json +239 -0
  102. package/data/docs/types/ItemTitle.json +27 -0
  103. package/data/docs/types/Kbd.json +8 -8
  104. package/data/docs/types/Link.json +30 -30
  105. package/data/docs/types/ListIndicator.json +6 -6
  106. package/data/docs/types/ListItem.json +6 -6
  107. package/data/docs/types/ListRoot.json +10 -10
  108. package/data/docs/types/LoadingSpinner.json +2 -2
  109. package/data/docs/types/MakeElementFocusable.json +18 -18
  110. package/data/docs/types/Markdown.json +6 -6
  111. package/data/docs/types/MenuItem.json +63 -63
  112. package/data/docs/types/MenuRoot.json +56 -56
  113. package/data/docs/types/MenuSection.json +31 -31
  114. package/data/docs/types/MenuSubmenuTrigger.json +4 -4
  115. package/data/docs/types/MenuTrigger.json +89 -89
  116. package/data/docs/types/MultilineTextInput.json +104 -104
  117. package/data/docs/types/MultilineTextInputField.json +102 -102
  118. package/data/docs/types/NumberInput.json +86 -86
  119. package/data/docs/types/NumberInputField.json +82 -82
  120. package/data/docs/types/PageContentColumn.json +6 -6
  121. package/data/docs/types/PageContentRoot.json +6 -6
  122. package/data/docs/types/PasswordInput.json +100 -100
  123. package/data/docs/types/PasswordInputField.json +100 -100
  124. package/data/docs/types/ProgressBar.json +13 -13
  125. package/data/docs/types/RadioInputOption.json +56 -56
  126. package/data/docs/types/RadioInputRoot.json +48 -48
  127. package/data/docs/types/RangeCalendar.json +58 -58
  128. package/data/docs/types/RangeSlider.json +337 -0
  129. package/data/docs/types/RangeSliderProps.json +9 -0
  130. package/data/docs/types/Region.json +6 -6
  131. package/data/docs/types/RegionTarget.json +6 -6
  132. package/data/docs/types/RichTextInput.json +2 -2
  133. package/data/docs/types/Root.json +10 -10
  134. package/data/docs/types/Row.json +6 -6
  135. package/data/docs/types/ScrollArea.json +2 -2
  136. package/data/docs/types/SearchInput.json +106 -106
  137. package/data/docs/types/SearchInputField.json +102 -102
  138. package/data/docs/types/SelectOption.json +54 -54
  139. package/data/docs/types/SelectOptionGroup.json +18 -18
  140. package/data/docs/types/SelectOptions.json +64 -64
  141. package/data/docs/types/SelectRoot.json +92 -92
  142. package/data/docs/types/Separator.json +4 -4
  143. package/data/docs/types/SimpleGrid.json +28 -28
  144. package/data/docs/types/Skeleton.json +129 -0
  145. package/data/docs/types/SkeletonCircle.json +103 -0
  146. package/data/docs/types/SkeletonCircleProps.json +9 -0
  147. package/data/docs/types/SkeletonProps.json +9 -0
  148. package/data/docs/types/SkeletonText.json +62 -0
  149. package/data/docs/types/SkeletonTextProps.json +9 -0
  150. package/data/docs/types/Slider.json +337 -0
  151. package/data/docs/types/SplitButton.json +10 -10
  152. package/data/docs/types/Stack.json +2 -2
  153. package/data/docs/types/StepsNextTrigger.json +2 -2
  154. package/data/docs/types/StepsPrevTrigger.json +2 -2
  155. package/data/docs/types/StepsRoot.json +2 -2
  156. package/data/docs/types/StepsTrigger.json +2 -2
  157. package/data/docs/types/Switch.json +36 -36
  158. package/data/docs/types/TabNavItem.json +18 -18
  159. package/data/docs/types/TabNavRoot.json +2 -2
  160. package/data/docs/types/TableBody.json +6 -6
  161. package/data/docs/types/TableCaption.json +6 -6
  162. package/data/docs/types/TableCell.json +20 -20
  163. package/data/docs/types/TableColumn.json +8 -8
  164. package/data/docs/types/TableColumnGroup.json +8 -8
  165. package/data/docs/types/TableColumnHeader.json +18 -18
  166. package/data/docs/types/TableFooter.json +6 -6
  167. package/data/docs/types/TableHeader.json +6 -6
  168. package/data/docs/types/TableRoot.json +32 -32
  169. package/data/docs/types/TableRow.json +6 -6
  170. package/data/docs/types/TableScrollArea.json +6 -6
  171. package/data/docs/types/TabsTab.json +2 -2
  172. package/data/docs/types/TagGroupRoot.json +24 -24
  173. package/data/docs/types/TagGroupTag.json +56 -56
  174. package/data/docs/types/TagGroupTagList.json +15 -15
  175. package/data/docs/types/Text.json +8 -8
  176. package/data/docs/types/TextInput.json +102 -102
  177. package/data/docs/types/TextInputField.json +100 -100
  178. package/data/docs/types/TimeInput.json +68 -68
  179. package/data/docs/types/ToggleButton.json +74 -74
  180. package/data/docs/types/ToggleButtonGroupButton.json +32 -32
  181. package/data/docs/types/ToggleButtonGroupRoot.json +20 -20
  182. package/data/docs/types/Toolbar.json +9 -9
  183. package/data/docs/types/TooltipContent.json +28 -28
  184. package/data/docs/types/TooltipRoot.json +16 -16
  185. package/data/docs/types/TreeIndicator.json +82 -82
  186. package/data/docs/types/TreeItem.json +100 -51
  187. package/data/docs/types/TreeRoot.json +57 -57
  188. package/data/docs/types/Trigger.json +4 -4
  189. package/data/docs/types/VisuallyHidden.json +6 -6
  190. package/data/docs/types/createItemsFromCsvDrop.json +4 -4
  191. package/data/docs/types/createItemsFromDirectoryDrop.json +4 -4
  192. package/data/docs/types/createItemsFromFileDrop.json +4 -4
  193. package/data/docs/types/createItemsFromImageDrop.json +4 -4
  194. package/data/docs/types/createItemsFromJsonDrop.json +4 -4
  195. package/data/docs/types/manifest.json +28 -0
  196. package/data/docs/types/useRegion.json +2 -2
  197. package/data/docs/types/useTree.json +24 -24
  198. package/data/tokens.json +42 -0
  199. package/package.json +7 -7
@@ -0,0 +1,611 @@
1
+ {
2
+ "meta": {
3
+ "id": "Components-Slider",
4
+ "title": "Slider",
5
+ "exportName": "Slider",
6
+ "description": "A slider lets users select a numeric value, or a numeric range, by dragging a handle along a track.",
7
+ "lifecycleState": "Beta",
8
+ "order": 999,
9
+ "repoPath": "packages/nimbus/src/components/slider/slider.mdx",
10
+ "menu": [
11
+ "Components",
12
+ "Inputs",
13
+ "Slider"
14
+ ],
15
+ "route": "components/inputs/slider",
16
+ "tags": [
17
+ "component",
18
+ "slider",
19
+ "range slider",
20
+ "input",
21
+ "numeric",
22
+ "range"
23
+ ],
24
+ "toc": [
25
+ {
26
+ "value": "Overview",
27
+ "href": "#overview",
28
+ "depth": 2,
29
+ "numbering": [
30
+ 1,
31
+ 1
32
+ ],
33
+ "parent": "root"
34
+ },
35
+ {
36
+ "value": "Key features",
37
+ "href": "#key-features",
38
+ "depth": 3,
39
+ "numbering": [
40
+ 1,
41
+ 1,
42
+ 1
43
+ ],
44
+ "parent": "root"
45
+ },
46
+ {
47
+ "value": "Resources",
48
+ "href": "#resources",
49
+ "depth": 3,
50
+ "numbering": [
51
+ 1,
52
+ 1,
53
+ 2
54
+ ],
55
+ "parent": "root"
56
+ },
57
+ {
58
+ "value": "Variables",
59
+ "href": "#variables",
60
+ "depth": 2,
61
+ "numbering": [
62
+ 1,
63
+ 2
64
+ ],
65
+ "parent": "root"
66
+ },
67
+ {
68
+ "value": "Size",
69
+ "href": "#size",
70
+ "depth": 3,
71
+ "numbering": [
72
+ 1,
73
+ 2,
74
+ 1
75
+ ],
76
+ "parent": "root"
77
+ },
78
+ {
79
+ "value": "Variants",
80
+ "href": "#variants",
81
+ "depth": 3,
82
+ "numbering": [
83
+ 1,
84
+ 2,
85
+ 2
86
+ ],
87
+ "parent": "root"
88
+ },
89
+ {
90
+ "value": "Orientation",
91
+ "href": "#orientation",
92
+ "depth": 3,
93
+ "numbering": [
94
+ 1,
95
+ 2,
96
+ 3
97
+ ],
98
+ "parent": "root"
99
+ },
100
+ {
101
+ "value": "Ticks",
102
+ "href": "#ticks",
103
+ "depth": 3,
104
+ "numbering": [
105
+ 1,
106
+ 2,
107
+ 4
108
+ ],
109
+ "parent": "root"
110
+ },
111
+ {
112
+ "value": "Range",
113
+ "href": "#range",
114
+ "depth": 3,
115
+ "numbering": [
116
+ 1,
117
+ 2,
118
+ 5
119
+ ],
120
+ "parent": "root"
121
+ }
122
+ ],
123
+ "layout": "app-frame",
124
+ "tabs": [
125
+ {
126
+ "key": "overview",
127
+ "title": "Overview",
128
+ "order": 0
129
+ },
130
+ {
131
+ "key": "guidelines",
132
+ "title": "Guidelines",
133
+ "order": 2
134
+ },
135
+ {
136
+ "key": "dev",
137
+ "title": "Implementation",
138
+ "order": 3
139
+ },
140
+ {
141
+ "key": "a11y",
142
+ "title": "Accessibility",
143
+ "order": 4
144
+ }
145
+ ]
146
+ },
147
+ "mdx": "\n## Overview\n\nA slider lets people choose a value by dragging a handle along a track, instead\nof typing a number. It's a good fit whenever the exact number matters less than\nits position relative to the whole scale, such as volume, zoom, opacity, or\nbrightness.\n\n`Slider` selects a single value. To select a range — a lower and an upper bound\nat once — use the [Range Slider](/components/inputs/range-slider), which shares\nthe same track, handle, and tick styling, so a page that mixes single and range\nsliders still looks consistent.\n\nThe slider draws no label or static \"current value\" readout of its own. The\ncurrent value appears in a small tooltip above the handle while it's hovered,\nfocused, or being dragged — the track stays visually quiet the rest of the time.\nThe label comes from the surrounding `FormField`, or from an `aria-label` when\nthe slider is used on its own.\n\n### Key features\n\n- **Tooltip value display:** the current value shows above the handle on hover,\n focus, or drag — there's no permanent number next to the track.\n- **Range selection:** the [Range Slider](/components/inputs/range-slider) uses\n two handles that can't be dragged past each other, for choosing a min–max\n range.\n- **Tick marks:** an optional row of marks along the track for scales where the\n discrete steps matter (e.g. star ratings, quality levels).\n- **Horizontal and vertical:** either orientation is available for layouts where\n a vertical control reads more naturally (e.g. a mixing-desk-style fader).\n\n### Resources\n\n- [W3C ARIA Authoring Practices: Slider pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/)\n\n## Variables\n\n### Size\n\n`md` is the default size. `sm` is available for denser layouts.\n\n```jsx live\nconst App = () => (\n <Stack direction=\"horizontal\" gap=\"600\" alignItems=\"center\">\n <Slider aria-label=\"Small\" size=\"sm\" defaultValue={30} />\n <Slider aria-label=\"Medium (default)\" size=\"md\" defaultValue={30} />\n </Stack>\n);\n```\n\n### Variants\n\n`filled` is the default. Two additional variants are available for contexts that\ncall for a different visual weight:\n\n- **Filled** (default) — a standard thin track with a colored progress fill. The\n safest choice for most forms and settings panels.\n- **Minimal** — a thin neutral track carrying a single-color handle; the track\n grows to full width on hover or focus. For low-emphasis controls where a full\n colored progress bar would over-emphasize the value, such as a thumbnail-size\n picker.\n- **Enclosed** — a thick, contained bar with the handle inset inside it (an\n iOS-style control). Good for touch-first contexts or standalone controls that\n benefit from a larger, more tactile target.\n\n```jsx live\nconst App = () => (\n <Stack direction=\"horizontal\" gap=\"600\" alignItems=\"center\">\n <Slider aria-label=\"Filled (default)\" variant=\"filled\" defaultValue={60} />\n <Slider aria-label=\"Minimal\" variant=\"minimal\" defaultValue={60} />\n <Slider aria-label=\"Enclosed\" variant=\"enclosed\" defaultValue={75} />\n </Stack>\n);\n```\n\n### Orientation\n\n`horizontal` is the default. `vertical` is useful for fader-style controls or\nwhen horizontal space is limited.\n\n```jsx live\nconst App = () => (\n <Stack direction=\"horizontal\" gap=\"600\" alignItems=\"flex-start\">\n <Slider aria-label=\"Horizontal\" defaultValue={40} />\n <Slider aria-label=\"Vertical\" defaultValue={40} orientation=\"vertical\" />\n </Stack>\n);\n```\n\n### Ticks\n\nTurn on `showTicks` to mark discrete steps along the track. `tickStep` (or\n`step`, if `tickStep` is omitted) controls how far apart the ticks are.\n\n```jsx live\nconst App = () => (\n <Slider\n aria-label=\"Rating\"\n defaultValue={50}\n minValue={0}\n maxValue={100}\n step={25}\n showTicks\n />\n);\n```\n\n### Range\n\nTo select a range — a lower and an upper bound — with two handles, use the\n[Range Slider](/components/inputs/range-slider). It shares the same size,\nvariant, orientation, and tick options shown above.\n",
148
+ "views": {
149
+ "overview": {
150
+ "mdx": "\n## Overview\n\nA slider lets people choose a value by dragging a handle along a track, instead\nof typing a number. It's a good fit whenever the exact number matters less than\nits position relative to the whole scale, such as volume, zoom, opacity, or\nbrightness.\n\n`Slider` selects a single value. To select a range — a lower and an upper bound\nat once — use the [Range Slider](/components/inputs/range-slider), which shares\nthe same track, handle, and tick styling, so a page that mixes single and range\nsliders still looks consistent.\n\nThe slider draws no label or static \"current value\" readout of its own. The\ncurrent value appears in a small tooltip above the handle while it's hovered,\nfocused, or being dragged — the track stays visually quiet the rest of the time.\nThe label comes from the surrounding `FormField`, or from an `aria-label` when\nthe slider is used on its own.\n\n### Key features\n\n- **Tooltip value display:** the current value shows above the handle on hover,\n focus, or drag — there's no permanent number next to the track.\n- **Range selection:** the [Range Slider](/components/inputs/range-slider) uses\n two handles that can't be dragged past each other, for choosing a min–max\n range.\n- **Tick marks:** an optional row of marks along the track for scales where the\n discrete steps matter (e.g. star ratings, quality levels).\n- **Horizontal and vertical:** either orientation is available for layouts where\n a vertical control reads more naturally (e.g. a mixing-desk-style fader).\n\n### Resources\n\n- [W3C ARIA Authoring Practices: Slider pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/)\n\n## Variables\n\n### Size\n\n`md` is the default size. `sm` is available for denser layouts.\n\n```jsx live\nconst App = () => (\n <Stack direction=\"horizontal\" gap=\"600\" alignItems=\"center\">\n <Slider aria-label=\"Small\" size=\"sm\" defaultValue={30} />\n <Slider aria-label=\"Medium (default)\" size=\"md\" defaultValue={30} />\n </Stack>\n);\n```\n\n### Variants\n\n`filled` is the default. Two additional variants are available for contexts that\ncall for a different visual weight:\n\n- **Filled** (default) — a standard thin track with a colored progress fill. The\n safest choice for most forms and settings panels.\n- **Minimal** — a thin neutral track carrying a single-color handle; the track\n grows to full width on hover or focus. For low-emphasis controls where a full\n colored progress bar would over-emphasize the value, such as a thumbnail-size\n picker.\n- **Enclosed** — a thick, contained bar with the handle inset inside it (an\n iOS-style control). Good for touch-first contexts or standalone controls that\n benefit from a larger, more tactile target.\n\n```jsx live\nconst App = () => (\n <Stack direction=\"horizontal\" gap=\"600\" alignItems=\"center\">\n <Slider aria-label=\"Filled (default)\" variant=\"filled\" defaultValue={60} />\n <Slider aria-label=\"Minimal\" variant=\"minimal\" defaultValue={60} />\n <Slider aria-label=\"Enclosed\" variant=\"enclosed\" defaultValue={75} />\n </Stack>\n);\n```\n\n### Orientation\n\n`horizontal` is the default. `vertical` is useful for fader-style controls or\nwhen horizontal space is limited.\n\n```jsx live\nconst App = () => (\n <Stack direction=\"horizontal\" gap=\"600\" alignItems=\"flex-start\">\n <Slider aria-label=\"Horizontal\" defaultValue={40} />\n <Slider aria-label=\"Vertical\" defaultValue={40} orientation=\"vertical\" />\n </Stack>\n);\n```\n\n### Ticks\n\nTurn on `showTicks` to mark discrete steps along the track. `tickStep` (or\n`step`, if `tickStep` is omitted) controls how far apart the ticks are.\n\n```jsx live\nconst App = () => (\n <Slider\n aria-label=\"Rating\"\n defaultValue={50}\n minValue={0}\n maxValue={100}\n step={25}\n showTicks\n />\n);\n```\n\n### Range\n\nTo select a range — a lower and an upper bound — with two handles, use the\n[Range Slider](/components/inputs/range-slider). It shares the same size,\nvariant, orientation, and tick options shown above.\n",
151
+ "toc": [
152
+ {
153
+ "value": "Overview",
154
+ "href": "#overview",
155
+ "depth": 2,
156
+ "numbering": [
157
+ 1,
158
+ 1
159
+ ],
160
+ "parent": "root"
161
+ },
162
+ {
163
+ "value": "Key features",
164
+ "href": "#key-features",
165
+ "depth": 3,
166
+ "numbering": [
167
+ 1,
168
+ 1,
169
+ 1
170
+ ],
171
+ "parent": "root"
172
+ },
173
+ {
174
+ "value": "Resources",
175
+ "href": "#resources",
176
+ "depth": 3,
177
+ "numbering": [
178
+ 1,
179
+ 1,
180
+ 2
181
+ ],
182
+ "parent": "root"
183
+ },
184
+ {
185
+ "value": "Variables",
186
+ "href": "#variables",
187
+ "depth": 2,
188
+ "numbering": [
189
+ 1,
190
+ 2
191
+ ],
192
+ "parent": "root"
193
+ },
194
+ {
195
+ "value": "Size",
196
+ "href": "#size",
197
+ "depth": 3,
198
+ "numbering": [
199
+ 1,
200
+ 2,
201
+ 1
202
+ ],
203
+ "parent": "root"
204
+ },
205
+ {
206
+ "value": "Variants",
207
+ "href": "#variants",
208
+ "depth": 3,
209
+ "numbering": [
210
+ 1,
211
+ 2,
212
+ 2
213
+ ],
214
+ "parent": "root"
215
+ },
216
+ {
217
+ "value": "Orientation",
218
+ "href": "#orientation",
219
+ "depth": 3,
220
+ "numbering": [
221
+ 1,
222
+ 2,
223
+ 3
224
+ ],
225
+ "parent": "root"
226
+ },
227
+ {
228
+ "value": "Ticks",
229
+ "href": "#ticks",
230
+ "depth": 3,
231
+ "numbering": [
232
+ 1,
233
+ 2,
234
+ 4
235
+ ],
236
+ "parent": "root"
237
+ },
238
+ {
239
+ "value": "Range",
240
+ "href": "#range",
241
+ "depth": 3,
242
+ "numbering": [
243
+ 1,
244
+ 2,
245
+ 5
246
+ ],
247
+ "parent": "root"
248
+ }
249
+ ]
250
+ },
251
+ "a11y": {
252
+ "mdx": "\n## Accessibility\n\nAccessibility ensures that digital content and functionality are usable by\neveryone, including people with disabilities, by addressing visual, auditory,\ncognitive, and physical limitations.\n\n`Slider` renders no visible label of its own, so an accessible name must always\ncome from somewhere — either `FormField.Label` when composed inside a form\nfield, or an `aria-label` / `aria-labelledby` when used standalone.\n\n```jsx live\nconst App = () => (\n <Slider aria-label=\"Volume\" defaultValue={30} minValue={0} maxValue={100} />\n);\n```\n\n### Accessibility standards\n\n- Always give the slider an accessible name: `aria-label` (or\n `aria-labelledby`) standalone, or `FormField.Label` when composed inside\n `FormField.Root`. A slider with no accessible name is unusable with a screen\n reader.\n- For selecting a range with two handles, see the\n [Range Slider](/components/inputs/range-slider), which has its own per-handle\n labeling requirements (`thumbLabels`).\n- The current value is exposed to assistive technology through the handle's\n native value, not just the visual tooltip — screen readers announce it\n without needing the tooltip to be open.\n- Support full keyboard interaction: `Tab` to focus a handle, `Arrow` keys to\n adjust by `step`, and `Home` / `End` to jump to the minimum / maximum.\n- Ensure sufficient color contrast for the track, fill, and handle in every\n state (default, hover, focus, dragging, disabled, invalid).\n- Communicate the invalid state with both a visual cue and a\n `FormField.Error` message — never color alone.\n- The invalid visual cue comes from `data-invalid` on the root element, not\n from `aria-invalid` on the underlying range input — React Aria's `Slider`\n has no validation-state concept of its own (unlike text-style inputs).\n Assistive technology instead picks up the invalid state through the\n associated `FormField.Error` text, which the slider's group references via\n `aria-describedby`.\n- Clearly indicate the focused handle with a visible focus ring.\n\n### Resources\n\n- [React Aria Slider](https://react-spectrum.adobe.com/react-aria/Slider.html)\n- [W3C ARIA Authoring Practices Guide (APG): Slider pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/)\n",
253
+ "toc": [
254
+ {
255
+ "value": "Accessibility",
256
+ "href": "#accessibility",
257
+ "depth": 2,
258
+ "numbering": [
259
+ 1,
260
+ 1
261
+ ],
262
+ "parent": "root"
263
+ },
264
+ {
265
+ "value": "Accessibility standards",
266
+ "href": "#accessibility-standards",
267
+ "depth": 3,
268
+ "numbering": [
269
+ 1,
270
+ 1,
271
+ 1
272
+ ],
273
+ "parent": "root"
274
+ },
275
+ {
276
+ "value": "Resources",
277
+ "href": "#resources",
278
+ "depth": 3,
279
+ "numbering": [
280
+ 1,
281
+ 1,
282
+ 2
283
+ ],
284
+ "parent": "root"
285
+ }
286
+ ]
287
+ },
288
+ "dev": {
289
+ "mdx": "\n## Getting started\n\n### Import\n\n```tsx\nimport { Slider, type SliderProps } from \"@commercetools/nimbus\";\n```\n\n### Basic usage\n\n`Slider` selects a single `number`. It renders no visible label and no static\nvalue readout — the current value appears in a tooltip above the handle while\nit's hovered, focused, or dragged, so an accessible name must be supplied\nseparately (see [Accessibility](#accessibility) below).\n\n```jsx live-dev\nconst App = () => (\n <Slider aria-label=\"Volume\" defaultValue={30} minValue={0} maxValue={100} />\n);\n```\n\n> Need to select a range with two handles instead of a single value? See the\n> [Range Slider](/components/inputs/range-slider) component — it shares the same\n> track, handle, and tick styling.\n\n## Usage examples\n\n### Size options\n\n`sm` and `md` size variants are available to match surrounding density.\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"600\">\n <Slider aria-label=\"Small\" size=\"sm\" defaultValue={30} />\n <Slider aria-label=\"Medium (default)\" size=\"md\" defaultValue={30} />\n </Stack>\n);\n```\n\n### Visual variants\n\n`variant` changes the track/progress/thumb treatment. `filled` (the default) is\nthe standard thin track with a colored progress fill; `minimal` is a thin\nneutral track with a single-color handle that grows to full width on hover/focus\n(a single slider shows no progress fill), for low-emphasis controls such as a\nthumbnail-size picker; `enclosed` is a thick, contained bar\nwith the thumb inset inside it. The same variants apply to the\n[Range Slider](/components/inputs/range-slider), since they share the same\nrecipe.\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"600\">\n <Slider aria-label=\"Filled\" variant=\"filled\" defaultValue={60} />\n <Slider aria-label=\"Minimal\" variant=\"minimal\" defaultValue={60} />\n <Slider aria-label=\"Enclosed\" variant=\"enclosed\" defaultValue={75} />\n </Stack>\n);\n```\n\n### Orientation\n\nSet `orientation=\"vertical\"` for a vertical track. The vertical track has a\nbuilt-in default length, so no explicit `height` is required.\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"row\" gap=\"600\" alignItems=\"flex-start\">\n <Slider aria-label=\"Horizontal\" defaultValue={40} />\n <Slider aria-label=\"Vertical\" defaultValue={40} orientation=\"vertical\" />\n </Stack>\n);\n```\n\n### Tick marks\n\nSet `showTicks` to render a mark at every `tickStep` interval (falling back to\n`step` when `tickStep` is omitted). Useful for scales where the discrete stops\nthemselves are meaningful, such as ratings.\n\n```jsx live-dev\nconst App = () => (\n <Slider\n aria-label=\"Rating\"\n defaultValue={50}\n minValue={0}\n maxValue={100}\n step={25}\n showTicks\n />\n);\n```\n\n**Behavioral notes:**\n\n- `tickStep` controls the spacing between ticks; it defaults to `step` when\n `showTicks` is set and `tickStep` is omitted.\n- Ticks are purely visual — they don't constrain which values the handle can\n land on. Use `step` for that.\n- Ticks are spaced evenly starting from `minValue`. When `(maxValue - minValue)`\n isn't evenly divisible by the tick step, the last tick lands on the final full\n step short of `maxValue`, not on `maxValue` itself.\n\n### Value formatting\n\n`formatOptions` (an `Intl.NumberFormatOptions` object) formats the value shown\nin the handle's tooltip, without changing the underlying numeric value.\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"600\">\n <Slider\n aria-label=\"Discount\"\n defaultValue={0.2}\n minValue={0}\n maxValue={1}\n step={0.01}\n formatOptions={{ style: \"percent\" }}\n />\n <Slider\n aria-label=\"Price\"\n defaultValue={49}\n minValue={0}\n maxValue={200}\n formatOptions={{ style: \"currency\", currency: \"USD\" }}\n />\n </Stack>\n);\n```\n\n### Disabled state\n\nDisable interaction with `isDisabled`.\n\n```jsx live-dev\nconst App = () => (\n <Slider\n aria-label=\"Volume\"\n defaultValue={30}\n minValue={0}\n maxValue={100}\n isDisabled\n />\n);\n```\n\n### Uncontrolled mode\n\nFor simpler use cases, use uncontrolled mode with `defaultValue` and `onChange`.\nThe `Text` element below is a stand-in for **your own** application code\nreacting to the live value (e.g. updating a preview elsewhere on the page) —\nit's a demo of what `onChange` gives you, not a recommended \"value readout\nbeside the track\" pattern; the slider's own tooltip already shows the value on\nhover, focus, and drag (see the Guidelines tab).\n\n```jsx live-dev\nconst App = () => {\n const [value, setValue] = useState(30);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Slider\n aria-label=\"Volume\"\n defaultValue={30}\n minValue={0}\n maxValue={100}\n onChange={setValue}\n />\n <Text fontSize=\"sm\">Current value (for demo purposes): {value}</Text>\n </Stack>\n );\n};\n```\n\n**Note:** `Slider`'s `onChange` receives the numeric value directly, not an\nevent object. `onChangeEnd` fires once when the interaction (drag or key press)\nsettles, rather than on every intermediate change.\n\n### Controlled mode\n\nFor scenarios requiring programmatic control, use controlled mode:\n\n```jsx live-dev\nconst App = () => {\n const [value, setValue] = useState(50);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Slider\n aria-label=\"Zoom\"\n value={value}\n onChange={setValue}\n minValue={0}\n maxValue={100}\n />\n <Stack direction=\"row\" gap=\"300\">\n <Button onPress={() => setValue(0)}>Reset</Button>\n <Button onPress={() => setValue(50)}>Set to 50</Button>\n <Button onPress={() => setValue(100)}>Set to 100</Button>\n </Stack>\n </Stack>\n );\n};\n```\n\n## Component requirements\n\n### Accessibility\n\n`Slider` handles keyboard, pointer, touch, and RTL behavior internally via React\nAria. However, unlike most Nimbus inputs, **it renders no visible label or a\nstatic value readout** — the current value is only ever shown in a tooltip above\nthe handle while it's hovered, focused, or dragged. You must always supply an\naccessible name through one of the following:\n\n- Composing inside `FormField.Root` with `FormField.Label` (recommended for\n forms):\n\n```tsx\n<FormField.Root>\n <FormField.Label>Opacity</FormField.Label>\n <FormField.Input>\n <Slider defaultValue={80} minValue={0} maxValue={100} />\n </FormField.Input>\n</FormField.Root>\n```\n\n- Passing `aria-label` directly, for standalone use where no visible label is\n part of the design:\n\n```tsx\n<Slider aria-label=\"Opacity\" defaultValue={80} minValue={0} maxValue={100} />\n```\n\n- Associating an existing `<label>` element via `aria-labelledby`:\n\n```tsx\n<label id=\"opacity-label\">Opacity</label>\n<Slider aria-labelledby=\"opacity-label\" defaultValue={80} minValue={0} maxValue={100} />\n```\n\nIf your use case requires tracking and analytics for this component, it is good\npractice to add a **persistent**, **unique** id:\n\n```tsx\nconst PERSISTENT_ID = \"settings-opacity-slider\";\n\nexport const OpacitySlider = () => (\n <Slider id={PERSISTENT_ID} minValue={0} maxValue={100} />\n);\n```\n\n#### Keyboard navigation\n\nThe component supports full keyboard interaction:\n\n- `Tab` / `Shift+Tab`: move focus to/from the handle.\n- `Arrow Left` / `Arrow Right` (or `Arrow Down` / `Arrow Up` when\n `orientation=\"vertical\"`): decrement/increment the handle's value by `step`.\n- `Page Down` / `Page Up`: decrement/increment by a larger amount.\n- `Home`: jump the handle to `minValue`.\n- `End`: jump the handle to `maxValue`.\n\n## API reference\n\n<PropsTable id=\"Slider\" />\n\nThe [Range Slider](/components/inputs/range-slider) has its own API reference on\nits Implementation tab.\n\n## Common patterns\n\n### Slider inside a form field with validation\n\n`FormField.Input` clones its React-Aria-named props (`aria-labelledby`,\n`aria-describedby`, `isInvalid`, `isDisabled`, `isRequired`, `isReadOnly`) onto\nthe slider, so the label, description, and error state all associate\nautomatically.\n\n```jsx live-dev\nconst App = () => (\n <FormField.Root isInvalid>\n <FormField.Label>Opacity</FormField.Label>\n <FormField.Input>\n <Slider defaultValue={50} minValue={0} maxValue={100} />\n </FormField.Input>\n <FormField.Description>Adjust layer opacity</FormField.Description>\n <FormField.Error>Value is out of range</FormField.Error>\n </FormField.Root>\n);\n```\n\n## Testing your implementation\n\nThese examples demonstrate how to test your implementation when using Slider\nwithin your application. As the component's internal functionality is already\ntested by Nimbus, these patterns help you verify your integration and\napplication-specific logic.\n\n### Basic Rendering Tests\n\nVerify the slider renders with expected elements and no visible label\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 { Slider, FormField, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"Slider - Basic rendering\", () => {\n it(\"renders a slider handle with the given accessible name and initial value\", () => {\n render(\n <NimbusProvider>\n <Slider\n aria-label=\"Volume\"\n defaultValue={30}\n minValue={0}\n maxValue={100}\n />\n </NimbusProvider>\n );\n\n const thumb = screen.getByRole(\"slider\", { name: /volume/i });\n expect(thumb).toBeInTheDocument();\n expect(thumb).toHaveValue(\"30\");\n });\n\n it(\"renders no visible label or static value output\", () => {\n render(\n <NimbusProvider>\n <Slider\n aria-label=\"Volume\"\n defaultValue={30}\n minValue={0}\n maxValue={100}\n />\n </NimbusProvider>\n );\n\n // The accessible name comes from aria-label; no visible \"Volume\" text\n // or standalone \"30\" readout is rendered next to the track.\n expect(screen.queryByText(\"Volume\")).not.toBeInTheDocument();\n });\n});\n```\n\n### Interaction Tests\n\nTest keyboard interactions and onChange 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 { Slider, FormField, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"Slider - Interactions\", () => {\n it(\"calls onChange with the updated value on keyboard interaction\", async () => {\n const user = userEvent.setup();\n const handleChange = vi.fn();\n render(\n <NimbusProvider>\n <Slider\n aria-label=\"Volume\"\n defaultValue={30}\n minValue={0}\n maxValue={100}\n onChange={handleChange}\n />\n </NimbusProvider>\n );\n\n const thumb = screen.getByRole(\"slider\");\n thumb.focus();\n await user.keyboard(\"{ArrowRight}\");\n\n expect(thumb).toHaveValue(\"31\");\n expect(handleChange).toHaveBeenCalledWith(31);\n });\n\n it(\"jumps to minValue/maxValue with Home/End\", async () => {\n const user = userEvent.setup();\n render(\n <NimbusProvider>\n <Slider\n aria-label=\"Volume\"\n defaultValue={30}\n minValue={0}\n maxValue={100}\n />\n </NimbusProvider>\n );\n\n const thumb = screen.getByRole(\"slider\");\n thumb.focus();\n\n await user.keyboard(\"{End}\");\n expect(thumb).toHaveValue(\"100\");\n\n await user.keyboard(\"{Home}\");\n expect(thumb).toHaveValue(\"0\");\n });\n});\n```\n\n### Testing States\n\nVerify disabled and invalid states render correctly\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 { Slider, FormField, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"Slider - States\", () => {\n it(\"handles disabled state\", () => {\n render(\n <NimbusProvider>\n <Slider\n aria-label=\"Volume\"\n defaultValue={30}\n minValue={0}\n maxValue={100}\n isDisabled\n />\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"slider\")).toBeDisabled();\n });\n\n it(\"surfaces the invalid state on the root element\", () => {\n const { container } = render(\n <NimbusProvider>\n <Slider\n aria-label=\"Volume\"\n defaultValue={30}\n minValue={0}\n maxValue={100}\n isInvalid\n />\n </NimbusProvider>\n );\n\n const root = container.querySelector('[data-slot=\"root\"]');\n expect(root).toHaveAttribute(\"data-invalid\", \"true\");\n });\n});\n```\n\n### FormField Integration Tests\n\nVerify the slider composes correctly inside FormField\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 { Slider, FormField, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"Slider - FormField integration\", () => {\n it(\"resolves an accessible name from FormField.Label\", () => {\n render(\n <NimbusProvider>\n <FormField.Root>\n <FormField.Label>Opacity</FormField.Label>\n <FormField.Input>\n <Slider defaultValue={50} minValue={0} maxValue={100} />\n </FormField.Input>\n <FormField.Description>Adjust layer opacity</FormField.Description>\n </FormField.Root>\n </NimbusProvider>\n );\n\n const thumb = screen.getByRole(\"slider\");\n // aria-labelledby is not transitive per WAI-ARIA, so React Aria composes\n // the thumb's name from the group's content-based fallback name, which\n // includes the thumb's own live value — match by substring rather than\n // an exact string.\n expect(thumb).toHaveAccessibleName(/Opacity/);\n });\n\n it(\"surfaces the invalid state from FormField.Root\", () => {\n const { container } = render(\n <NimbusProvider>\n <FormField.Root isInvalid>\n <FormField.Label>Opacity</FormField.Label>\n <FormField.Input>\n <Slider defaultValue={50} minValue={0} maxValue={100} />\n </FormField.Input>\n <FormField.Error>Value is out of range</FormField.Error>\n </FormField.Root>\n </NimbusProvider>\n );\n\n const root = container.querySelector('[data-slot=\"root\"]');\n expect(root).toHaveAttribute(\"data-invalid\", \"true\");\n });\n});\n```\n\n### Visual Variants Tests\n\nEach visual variant renders an operable slider.\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 { Slider, FormField, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"Slider - Visual variants\", () => {\n it.each([\"filled\", \"minimal\", \"enclosed\"] as const)(\n \"renders an operable %s variant slider\",\n (variant) => {\n render(\n <NimbusProvider>\n <Slider\n aria-label={`${variant} slider`}\n variant={variant}\n defaultValue={50}\n />\n </NimbusProvider>\n );\n\n expect(screen.getByRole(\"slider\")).toHaveValue(\"50\");\n }\n );\n});\n```\n\n\n## Resources\n\n- [Storybook: Slider](https://nimbus-storybook.vercel.app/?path=/docs/components-slider--docs)\n- [Range Slider](/components/inputs/range-slider) — the two-handle range counterpart\n- [React Aria Slider](https://react-spectrum.adobe.com/react-aria/Slider.html)\n- [W3C ARIA Authoring Practices Guide (APG): Slider pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/)\n",
290
+ "toc": [
291
+ {
292
+ "value": "Getting started",
293
+ "href": "#getting-started",
294
+ "depth": 2,
295
+ "numbering": [
296
+ 1,
297
+ 1
298
+ ],
299
+ "parent": "root"
300
+ },
301
+ {
302
+ "value": "Import",
303
+ "href": "#import",
304
+ "depth": 3,
305
+ "numbering": [
306
+ 1,
307
+ 1,
308
+ 1
309
+ ],
310
+ "parent": "root"
311
+ },
312
+ {
313
+ "value": "Basic usage",
314
+ "href": "#basic-usage",
315
+ "depth": 3,
316
+ "numbering": [
317
+ 1,
318
+ 1,
319
+ 2
320
+ ],
321
+ "parent": "root"
322
+ },
323
+ {
324
+ "value": "Usage examples",
325
+ "href": "#usage-examples",
326
+ "depth": 2,
327
+ "numbering": [
328
+ 1,
329
+ 2
330
+ ],
331
+ "parent": "root"
332
+ },
333
+ {
334
+ "value": "Size options",
335
+ "href": "#size-options",
336
+ "depth": 3,
337
+ "numbering": [
338
+ 1,
339
+ 2,
340
+ 1
341
+ ],
342
+ "parent": "root"
343
+ },
344
+ {
345
+ "value": "Visual variants",
346
+ "href": "#visual-variants",
347
+ "depth": 3,
348
+ "numbering": [
349
+ 1,
350
+ 2,
351
+ 2
352
+ ],
353
+ "parent": "root"
354
+ },
355
+ {
356
+ "value": "Orientation",
357
+ "href": "#orientation",
358
+ "depth": 3,
359
+ "numbering": [
360
+ 1,
361
+ 2,
362
+ 3
363
+ ],
364
+ "parent": "root"
365
+ },
366
+ {
367
+ "value": "Tick marks",
368
+ "href": "#tick-marks",
369
+ "depth": 3,
370
+ "numbering": [
371
+ 1,
372
+ 2,
373
+ 4
374
+ ],
375
+ "parent": "root"
376
+ },
377
+ {
378
+ "value": "Value formatting",
379
+ "href": "#value-formatting",
380
+ "depth": 3,
381
+ "numbering": [
382
+ 1,
383
+ 2,
384
+ 5
385
+ ],
386
+ "parent": "root"
387
+ },
388
+ {
389
+ "value": "Disabled state",
390
+ "href": "#disabled-state",
391
+ "depth": 3,
392
+ "numbering": [
393
+ 1,
394
+ 2,
395
+ 6
396
+ ],
397
+ "parent": "root"
398
+ },
399
+ {
400
+ "value": "Uncontrolled mode",
401
+ "href": "#uncontrolled-mode",
402
+ "depth": 3,
403
+ "numbering": [
404
+ 1,
405
+ 2,
406
+ 7
407
+ ],
408
+ "parent": "root"
409
+ },
410
+ {
411
+ "value": "Controlled mode",
412
+ "href": "#controlled-mode",
413
+ "depth": 3,
414
+ "numbering": [
415
+ 1,
416
+ 2,
417
+ 8
418
+ ],
419
+ "parent": "root"
420
+ },
421
+ {
422
+ "value": "Component requirements",
423
+ "href": "#component-requirements",
424
+ "depth": 2,
425
+ "numbering": [
426
+ 1,
427
+ 3
428
+ ],
429
+ "parent": "root"
430
+ },
431
+ {
432
+ "value": "Accessibility",
433
+ "href": "#accessibility",
434
+ "depth": 3,
435
+ "numbering": [
436
+ 1,
437
+ 3,
438
+ 1
439
+ ],
440
+ "parent": "root"
441
+ },
442
+ {
443
+ "value": "Keyboard navigation",
444
+ "href": "#keyboard-navigation",
445
+ "depth": 4,
446
+ "numbering": [
447
+ 1,
448
+ 3,
449
+ 1,
450
+ 1
451
+ ],
452
+ "parent": "root"
453
+ },
454
+ {
455
+ "value": "API reference",
456
+ "href": "#api-reference",
457
+ "depth": 2,
458
+ "numbering": [
459
+ 1,
460
+ 4
461
+ ],
462
+ "parent": "root"
463
+ },
464
+ {
465
+ "value": "Common patterns",
466
+ "href": "#common-patterns",
467
+ "depth": 2,
468
+ "numbering": [
469
+ 1,
470
+ 5
471
+ ],
472
+ "parent": "root"
473
+ },
474
+ {
475
+ "value": "Slider inside a form field with validation",
476
+ "href": "#slider-inside-a-form-field-with-validation",
477
+ "depth": 3,
478
+ "numbering": [
479
+ 1,
480
+ 5,
481
+ 1
482
+ ],
483
+ "parent": "root"
484
+ },
485
+ {
486
+ "value": "Testing your implementation",
487
+ "href": "#testing-your-implementation",
488
+ "depth": 2,
489
+ "numbering": [
490
+ 1,
491
+ 6
492
+ ],
493
+ "parent": "root"
494
+ },
495
+ {
496
+ "value": "Basic Rendering Tests",
497
+ "href": "#basic-rendering-tests",
498
+ "depth": 3,
499
+ "numbering": [
500
+ 1,
501
+ 6,
502
+ 1
503
+ ],
504
+ "parent": "root"
505
+ },
506
+ {
507
+ "value": "Interaction Tests",
508
+ "href": "#interaction-tests",
509
+ "depth": 3,
510
+ "numbering": [
511
+ 1,
512
+ 6,
513
+ 2
514
+ ],
515
+ "parent": "root"
516
+ },
517
+ {
518
+ "value": "Testing States",
519
+ "href": "#testing-states",
520
+ "depth": 3,
521
+ "numbering": [
522
+ 1,
523
+ 6,
524
+ 3
525
+ ],
526
+ "parent": "root"
527
+ },
528
+ {
529
+ "value": "FormField Integration Tests",
530
+ "href": "#formfield-integration-tests",
531
+ "depth": 3,
532
+ "numbering": [
533
+ 1,
534
+ 6,
535
+ 4
536
+ ],
537
+ "parent": "root"
538
+ },
539
+ {
540
+ "value": "Visual Variants Tests",
541
+ "href": "#visual-variants-tests",
542
+ "depth": 3,
543
+ "numbering": [
544
+ 1,
545
+ 6,
546
+ 5
547
+ ],
548
+ "parent": "root"
549
+ },
550
+ {
551
+ "value": "Resources",
552
+ "href": "#resources",
553
+ "depth": 2,
554
+ "numbering": [
555
+ 1,
556
+ 7
557
+ ],
558
+ "parent": "root"
559
+ }
560
+ ]
561
+ },
562
+ "guidelines": {
563
+ "mdx": "\n## Guidelines\n\nSlider guidelines focus on picking a scale users can reason about, keeping the\nvalue visible while it's being changed, and always giving the control an\naccessible name, even though it draws no visible label of its own.\n\n### Best practices\n\n- **Always provide an accessible name.** A slider renders no visible label —\n place it inside `FormField.Root` with `FormField.Label`, or pass an\n `aria-label` (or `aria-labelledby`) when there's no surrounding form field.\n- **Choose a scale people can reason about.** Sliders work best when the exact\n number matters less than its position relative to the whole range — pick\n `minValue`, `maxValue`, and `step` so most handle positions feel meaningful.\n- **Show ticks only when the steps matter.** Turn on `showTicks` for scales\n with a handful of meaningful stops (star ratings, quality levels); leave it\n off for continuous-feeling values like volume or opacity, where ticks would\n just add visual noise.\n- **Rely on the value tooltip at the track, not a duplicate readout.** The\n current value already appears above the handle on hover, focus, or drag —\n don't add a second number readout right next to the slider that just\n repeats it. A `FormField.Description` summarizing the selection elsewhere\n in the form (e.g. a range's bounds) is a separate, permanent piece of\n context and is fine to keep.\n- **Reach for the [Range Slider](/components/inputs/range-slider) for bounded\n ranges.** Its two handles can't cross, so it guarantees the lower value never\n exceeds the upper one — useful for filters like price or distance ranges.\n- **Disable, don't hide.** When a slider's value is temporarily not\n applicable, disable it with `isDisabled` rather than removing it from the\n layout, so surrounding controls don't shift.\n\n### Usage\n\nA slider lets users choose a value by dragging a handle along a track, best for\nvalues that are set by feel rather than typed precisely. To choose a range\ninstead, use the [Range Slider](/components/inputs/range-slider).\n\n> [!TIP]\\\n> When to use\n>\n> - Selecting a value from a continuous or stepped numeric scale by feel, such\n> as volume, zoom, opacity, or brightness.\n> - The exact number matters less than its position relative to the minimum\n> and maximum.\n\n> [!CAUTION]\\\n> When not to use\n>\n> - The value must be typed precisely, or falls outside a small, well-known\n> range — use `NumberInput` instead.\n> - The input isn't really a position on a scale (e.g. a multi-step wizard or\n> a list of unrelated options) — a slider implies a continuum, not a\n> sequence of unrelated choices.\n> - Users need to see the min/max bounds labeled directly on the track — that\n> isn't supported yet; consider pairing the slider with your own labels.\n\n### Keeping interactions simple\n\nSimple, predictable interactions matter because a slider is operated by feel —\nunexpected jumps or hidden values erode trust in the control.\n\n> [!TIP]\\\n> **Do**\n>\n> - Give the slider a clear accessible name via `FormField.Label` or\n> `aria-label`.\n> - Set `minValue`, `maxValue`, and a `step` that make sense for the data.\n> - Use `showTicks` when the discrete stops themselves are meaningful.\n> - Reach for the [Range Slider](/components/inputs/range-slider) when both a\n> lower and upper bound need to be set together.\n> - Let the disabled state show when the value can't currently be changed.\n\n```jsx live\nconst App = () => (\n <Stack gap=\"200\" alignItems=\"start\">\n <FormField.Root>\n <FormField.Label>Opacity</FormField.Label>\n <FormField.Input>\n <Slider defaultValue={80} minValue={0} maxValue={100} />\n </FormField.Input>\n <FormField.Description>\n Adjust how transparent the layer appears.\n </FormField.Description>\n </FormField.Root>\n </Stack>\n);\n```\n\n> [!CAUTION]\\\n> **Don't**\n>\n> - Leave the slider without any accessible name — a bare `<Slider />` with no\n> `aria-label` and no `FormField.Label` is unusable with a screen reader.\n> - Duplicate the tooltip's job by placing a bare numeric readout directly\n> beside the track — the tooltip already covers that on hover, focus, and\n> drag. A `FormField.Description` that summarizes the selection for context\n> (e.g. a price range below the control) is a different thing: it's a\n> permanent summary for users who aren't actively interacting with the\n> slider, not a redundant echo of the tooltip.\n> - Use a slider for values that require exact, typed precision.\n\n```tsx\n// Missing an accessible name — screen reader users have no way to know\n// what this control is for.\n<Slider defaultValue={30} minValue={0} maxValue={100} />\n```\n",
564
+ "toc": [
565
+ {
566
+ "value": "Guidelines",
567
+ "href": "#guidelines",
568
+ "depth": 2,
569
+ "numbering": [
570
+ 1,
571
+ 1
572
+ ],
573
+ "parent": "root"
574
+ },
575
+ {
576
+ "value": "Best practices",
577
+ "href": "#best-practices",
578
+ "depth": 3,
579
+ "numbering": [
580
+ 1,
581
+ 1,
582
+ 1
583
+ ],
584
+ "parent": "root"
585
+ },
586
+ {
587
+ "value": "Usage",
588
+ "href": "#usage",
589
+ "depth": 3,
590
+ "numbering": [
591
+ 1,
592
+ 1,
593
+ 2
594
+ ],
595
+ "parent": "root"
596
+ },
597
+ {
598
+ "value": "Keeping interactions simple",
599
+ "href": "#keeping-interactions-simple",
600
+ "depth": 3,
601
+ "numbering": [
602
+ 1,
603
+ 1,
604
+ 3
605
+ ],
606
+ "parent": "root"
607
+ }
608
+ ]
609
+ }
610
+ }
611
+ }