@charcuterie/ui 4.4.0 → 4.5.1

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 (212) hide show
  1. package/README.md +7 -2
  2. package/dist/ActionTiles/ActionTiles.d.ts +2 -1
  3. package/dist/ActionTiles/ActionTiles.d.ts.map +1 -1
  4. package/dist/ActionTiles/ActionTiles.js +4 -2
  5. package/dist/ActionTiles/ActionTiles.js.map +1 -1
  6. package/dist/Card/Card.d.ts +5 -2
  7. package/dist/Card/Card.d.ts.map +1 -1
  8. package/dist/Card/Card.js +23 -3
  9. package/dist/Card/Card.js.map +1 -1
  10. package/package.json +3 -2
  11. package/src/Accordion/Accordion.mdx +1 -1
  12. package/src/Accordion/Accordion.stories.tsx +3 -1
  13. package/src/Accordion/Accordion.test.tsx +4 -4
  14. package/src/ActionTiles/ActionTiles.mdx +7 -1
  15. package/src/ActionTiles/ActionTiles.stories.tsx +3 -1
  16. package/src/ActionTiles/ActionTiles.test.tsx +3 -3
  17. package/src/ActionTiles/ActionTiles.tsx +4 -2
  18. package/src/AdaptiveGrid/AdaptiveGrid.mdx +1 -1
  19. package/src/AdaptiveGrid/AdaptiveGrid.stories.tsx +3 -1
  20. package/src/AdaptiveGrid/AdaptiveGrid.test.tsx +5 -5
  21. package/src/Alert/Alert.mdx +1 -1
  22. package/src/Alert/Alert.stories.tsx +3 -1
  23. package/src/Alert/Alert.test.tsx +2 -2
  24. package/src/Avatar/Avatar.mdx +1 -1
  25. package/src/Avatar/Avatar.stories.tsx +4 -1
  26. package/src/Avatar/Avatar.test.tsx +2 -2
  27. package/src/Badge/Badge.mdx +1 -1
  28. package/src/Badge/Badge.stories.tsx +3 -1
  29. package/src/Badge/Badge.test.tsx +3 -3
  30. package/src/BadgeButton/BadgeButton.mdx +1 -1
  31. package/src/BadgeButton/BadgeButton.stories.tsx +3 -1
  32. package/src/BadgeButton/BadgeButton.test.tsx +2 -2
  33. package/src/Board/Board.mdx +1 -1
  34. package/src/Board/Board.stories.tsx +4 -1
  35. package/src/Board/Board.test.tsx +2 -2
  36. package/src/Button/Button.mdx +1 -1
  37. package/src/Button/Button.stories.tsx +3 -1
  38. package/src/Button/Button.test.tsx +2 -2
  39. package/src/ButtonLink/ButtonLink.mdx +1 -1
  40. package/src/ButtonLink/ButtonLink.stories.tsx +3 -1
  41. package/src/ButtonLink/ButtonLink.test.tsx +3 -3
  42. package/src/Card/Card.mdx +21 -1
  43. package/src/Card/Card.stories.tsx +91 -1
  44. package/src/Card/Card.test.tsx +60 -3
  45. package/src/Card/Card.tsx +24 -2
  46. package/src/Checkbox/Checkbox.mdx +1 -1
  47. package/src/Checkbox/Checkbox.stories.tsx +3 -1
  48. package/src/Checkbox/Checkbox.test.tsx +4 -4
  49. package/src/ColorSchemeSwitcher/ColorSchemeSwitcher.mdx +1 -1
  50. package/src/ColorSchemeSwitcher/ColorSchemeSwitcher.stories.tsx +3 -1
  51. package/src/ColorSchemeSwitcher/ColorSchemeSwitcher.test.tsx +5 -5
  52. package/src/ColorSchemeToggle/ColorSchemeToggle.mdx +1 -1
  53. package/src/ColorSchemeToggle/ColorSchemeToggle.stories.tsx +3 -1
  54. package/src/ColorSchemeToggle/ColorSchemeToggle.test.tsx +5 -5
  55. package/src/Combobox/Combobox.mdx +1 -1
  56. package/src/Combobox/Combobox.stories.tsx +3 -1
  57. package/src/Combobox/Combobox.test.tsx +2 -2
  58. package/src/CopyButton/CopyButton.mdx +1 -1
  59. package/src/CopyButton/CopyButton.stories.tsx +4 -1
  60. package/src/CopyButton/CopyButton.test.tsx +3 -3
  61. package/src/DataTable/DataTable.mdx +1 -1
  62. package/src/DataTable/DataTable.stories.tsx +3 -1
  63. package/src/DataTable/DataTable.test.tsx +3 -3
  64. package/src/DatePicker/DatePicker.mdx +1 -1
  65. package/src/DatePicker/DatePicker.stories.tsx +3 -1
  66. package/src/DatePicker/DatePicker.test.tsx +3 -3
  67. package/src/DatePicker/plainDate.test.ts +21 -3
  68. package/src/Dialog/Dialog.mdx +1 -1
  69. package/src/Dialog/Dialog.stories.tsx +3 -1
  70. package/src/Dialog/Dialog.test.tsx +2 -2
  71. package/src/DropRail/DropRail.mdx +1 -1
  72. package/src/DropRail/DropRail.stories.tsx +4 -1
  73. package/src/DropRail/DropRail.test.tsx +4 -4
  74. package/src/EmptyState/EmptyState.mdx +1 -1
  75. package/src/EmptyState/EmptyState.stories.tsx +3 -1
  76. package/src/EmptyState/EmptyState.test.tsx +2 -2
  77. package/src/Field/Field.mdx +1 -1
  78. package/src/Field/Field.stories.tsx +3 -1
  79. package/src/Field/Field.test.tsx +4 -4
  80. package/src/FileDropZone/FileDropZone.mdx +1 -1
  81. package/src/FileDropZone/FileDropZone.stories.tsx +3 -1
  82. package/src/FileDropZone/FileDropZone.test.tsx +3 -3
  83. package/src/Header/Header.mdx +1 -1
  84. package/src/Header/Header.stories.tsx +3 -1
  85. package/src/IconButton/IconButton.mdx +1 -1
  86. package/src/IconButton/IconButton.stories.tsx +3 -1
  87. package/src/IconButton/IconButton.test.tsx +2 -2
  88. package/src/Lightbox/Lightbox.mdx +1 -1
  89. package/src/Lightbox/Lightbox.stories.tsx +3 -1
  90. package/src/Lightbox/Lightbox.test.tsx +2 -2
  91. package/src/Listbox/Listbox.mdx +1 -1
  92. package/src/Listbox/Listbox.stories.tsx +3 -1
  93. package/src/Listbox/Listbox.test.tsx +5 -5
  94. package/src/LiveStatusIndicator/LiveStatusIndicator.mdx +1 -1
  95. package/src/LiveStatusIndicator/LiveStatusIndicator.stories.tsx +3 -1
  96. package/src/LiveStatusIndicator/LiveStatusIndicator.test.tsx +2 -2
  97. package/src/LogViewer/LogViewer.mdx +1 -1
  98. package/src/LogViewer/LogViewer.stories.tsx +3 -1
  99. package/src/LogViewer/LogViewer.test.tsx +2 -2
  100. package/src/Main/Main.mdx +1 -1
  101. package/src/Main/Main.stories.tsx +3 -1
  102. package/src/Main/Main.test.tsx +3 -3
  103. package/src/MarkdownEditor/MarkdownEditor.mdx +1 -1
  104. package/src/MarkdownEditor/MarkdownEditor.stories.tsx +3 -1
  105. package/src/MarkdownEditor/MarkdownEditor.test.tsx +4 -4
  106. package/src/MarkdownLine/MarkdownLine.mdx +1 -1
  107. package/src/MarkdownLine/MarkdownLine.stories.tsx +4 -1
  108. package/src/MarkdownLine/MarkdownLine.test.tsx +3 -3
  109. package/src/MediaTile/MediaTile.stories.tsx +3 -1
  110. package/src/MediaTile/MediaTile.test.tsx +2 -2
  111. package/src/Menu/Menu.mdx +1 -1
  112. package/src/Menu/Menu.stories.tsx +3 -1
  113. package/src/Modal/Modal.mdx +1 -1
  114. package/src/Modal/Modal.stories.tsx +3 -1
  115. package/src/Modal/Modal.test.tsx +3 -3
  116. package/src/Nav/Nav.mdx +1 -1
  117. package/src/Nav/Nav.stories.tsx +3 -1
  118. package/src/Nav/Nav.test.tsx +6 -6
  119. package/src/NavBar/NavBar.mdx +1 -1
  120. package/src/NavBar/NavBar.stories.tsx +3 -1
  121. package/src/NavBar/NavBar.test.tsx +3 -3
  122. package/src/Picker/Picker.mdx +1 -1
  123. package/src/Picker/Picker.stories.tsx +3 -1
  124. package/src/Picker/Picker.test.tsx +2 -2
  125. package/src/Popover/Popover.mdx +1 -1
  126. package/src/Popover/Popover.stories.tsx +3 -1
  127. package/src/Popover/Popover.test.tsx +2 -2
  128. package/src/PortraitTiles/PortraitTiles.mdx +1 -1
  129. package/src/PortraitTiles/PortraitTiles.stories.tsx +3 -1
  130. package/src/PortraitTiles/PortraitTiles.test.tsx +5 -5
  131. package/src/ProgressBar/ProgressBar.mdx +1 -1
  132. package/src/ProgressBar/ProgressBar.stories.tsx +3 -1
  133. package/src/ProgressBar/ProgressBar.test.tsx +2 -2
  134. package/src/QueryBuilder/QueryBuilder.mdx +1 -1
  135. package/src/QueryBuilder/QueryBuilder.stories.tsx +3 -1
  136. package/src/QueryBuilder/QueryBuilder.test.tsx +2 -2
  137. package/src/RadioGroup/RadioGroup.mdx +1 -1
  138. package/src/RadioGroup/RadioGroup.stories.tsx +3 -1
  139. package/src/RadioGroup/RadioGroup.test.tsx +2 -2
  140. package/src/Rail/Rail.mdx +1 -1
  141. package/src/Rail/Rail.stories.tsx +3 -1
  142. package/src/Rail/Rail.test.tsx +2 -2
  143. package/src/RangeSlider/RangeSlider.mdx +1 -1
  144. package/src/RangeSlider/RangeSlider.stories.tsx +3 -1
  145. package/src/RangeSlider/RangeSlider.test.tsx +7 -3
  146. package/src/ReorderList/ReorderList.mdx +1 -1
  147. package/src/ReorderList/ReorderList.stories.tsx +3 -1
  148. package/src/ReorderList/ReorderList.test.tsx +7 -7
  149. package/src/RouterLink/UnstyledLink.stories.tsx +4 -1
  150. package/src/RouterLink/UnstyledLink.test.tsx +2 -2
  151. package/src/SearchInput/SearchInput.mdx +1 -1
  152. package/src/SearchInput/SearchInput.stories.tsx +3 -1
  153. package/src/SegmentedControl/SegmentedControl.mdx +1 -1
  154. package/src/SegmentedControl/SegmentedControl.stories.tsx +3 -1
  155. package/src/SegmentedControl/SegmentedControl.test.tsx +2 -2
  156. package/src/Select/Select.mdx +1 -1
  157. package/src/Select/Select.stories.tsx +3 -1
  158. package/src/Select/Select.test.tsx +4 -4
  159. package/src/Shell/Shell.mdx +1 -1
  160. package/src/Shell/Shell.stories.tsx +3 -1
  161. package/src/Shell/Shell.test.tsx +2 -2
  162. package/src/Skeleton/Skeleton.mdx +1 -1
  163. package/src/Skeleton/Skeleton.stories.tsx +3 -1
  164. package/src/Skeleton/Skeleton.test.tsx +2 -2
  165. package/src/Slider/Slider.mdx +1 -1
  166. package/src/Slider/Slider.stories.tsx +3 -1
  167. package/src/Slider/Slider.test.tsx +2 -2
  168. package/src/SortableTableHeader/SortableTableHeader.mdx +1 -1
  169. package/src/SortableTableHeader/SortableTableHeader.stories.tsx +3 -1
  170. package/src/SortableTableHeader/SortableTableHeader.test.tsx +3 -3
  171. package/src/Spinner/Spinner.mdx +1 -1
  172. package/src/Spinner/Spinner.stories.tsx +3 -1
  173. package/src/Spinner/Spinner.test.tsx +2 -2
  174. package/src/Stepper/Stepper.mdx +1 -1
  175. package/src/Stepper/Stepper.stories.tsx +4 -1
  176. package/src/Stepper/Stepper.test.tsx +7 -7
  177. package/src/Swatch/Swatch.mdx +1 -1
  178. package/src/Swatch/Swatch.stories.tsx +4 -1
  179. package/src/Swatch/Swatch.test.tsx +3 -3
  180. package/src/Switch/Switch.mdx +1 -1
  181. package/src/Switch/Switch.stories.tsx +3 -1
  182. package/src/Switch/Switch.test.tsx +2 -2
  183. package/src/Tabs/Tabs.mdx +1 -1
  184. package/src/Tabs/Tabs.stories.tsx +3 -1
  185. package/src/Tabs/Tabs.test.tsx +3 -3
  186. package/src/TextLink/TextLink.mdx +1 -1
  187. package/src/TextLink/TextLink.stories.tsx +3 -1
  188. package/src/TextLink/TextLink.test.tsx +4 -4
  189. package/src/TimecodeInput/TimecodeInput.mdx +1 -1
  190. package/src/TimecodeInput/TimecodeInput.stories.tsx +3 -1
  191. package/src/Toast/Toast.mdx +1 -1
  192. package/src/Toast/Toast.stories.tsx +3 -1
  193. package/src/Toast/Toast.test.tsx +2 -2
  194. package/src/Toolbar/Toolbar.mdx +1 -1
  195. package/src/Toolbar/Toolbar.stories.tsx +3 -1
  196. package/src/Toolbar/Toolbar.test.tsx +5 -5
  197. package/src/Tooltip/Tooltip.mdx +1 -1
  198. package/src/Tooltip/Tooltip.stories.tsx +3 -1
  199. package/src/Tooltip/Tooltip.test.tsx +2 -2
  200. package/src/VirtualizedGrid/VirtualizedGrid.mdx +1 -1
  201. package/src/VirtualizedGrid/VirtualizedGrid.stories.tsx +4 -1
  202. package/src/VirtualizedGrid/VirtualizedGrid.test.tsx +5 -5
  203. package/src/VisuallyHidden/VisuallyHidden.mdx +1 -1
  204. package/src/VisuallyHidden/VisuallyHidden.stories.tsx +3 -1
  205. package/src/markdownEditorCodeMirror/MarkdownEditorCodeMirror.mdx +1 -1
  206. package/src/markdownEditorCodeMirror/MarkdownEditorCodeMirror.stories.tsx +3 -1
  207. package/src/markdownEditorCodeMirror/MarkdownEditorCodeMirror.test.tsx +3 -3
  208. package/src/markdownEditorCodeMirror/MarkdownView.mdx +1 -1
  209. package/src/markdownEditorCodeMirror/MarkdownView.stories.tsx +4 -1
  210. package/src/markdownEditorCodeMirror/MarkdownView.test.tsx +44 -20
  211. package/src/reactRouter/ReactRouterAdapter.stories.tsx +3 -1
  212. package/src/reactRouter/ReactRouterAdapter.test.tsx +2 -2
@@ -16,11 +16,11 @@ import { expectAgentDrivable } from "../testing/index.ts"
16
16
  import meta, * as stories from "./CopyButton.stories.tsx"
17
17
  import { copyText } from "./copyText.ts"
18
18
 
19
- const { Confirmed, Default, Refused } =
19
+ const { Confirmed, Playground, Refused } =
20
20
  composeStories(stories)
21
21
 
22
22
  test("is a button an agent can find by role and name", async () => {
23
- const { canvas } = await mountStory(Default)
23
+ const { canvas } = await mountStory(Playground)
24
24
 
25
25
  const button = expectAgentDrivable(canvas, {
26
26
  name: "Copy",
@@ -170,7 +170,7 @@ test("a prevented click copies nothing", async () => {
170
170
  })
171
171
 
172
172
  test("has no axe violations", async () => {
173
- const { canvasElement } = await mountStory(Default)
173
+ const { canvasElement } = await mountStory(Playground)
174
174
 
175
175
  await expectNoAxeViolations(canvasElement)
176
176
  })
@@ -10,7 +10,7 @@ import * as DataTableStories from "./DataTable.stories";
10
10
  optional selection column, and the sort *announcement* — the data itself stays the
11
11
  consumer's.
12
12
 
13
- <Canvas of={DataTableStories.Default} />
13
+ <Canvas of={DataTableStories.Playground} />
14
14
 
15
15
  ## Props
16
16
 
@@ -1,3 +1,4 @@
1
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
1
2
  import type { Meta, StoryObj } from "@storybook/react"
2
3
  import type { ReactNode } from "react"
3
4
  import { useState } from "react"
@@ -266,7 +267,8 @@ type Story = StoryObj<typeof meta>
266
267
  * of the split: the component says *which* column is sorted, the
267
268
  * consumer says what that means for a priority enum.
268
269
  */
269
- export const Default: Story = {
270
+ export const Playground: Story = {
271
+ parameters: playgroundParameters,
270
272
  render: () => (
271
273
  <TaskTable
272
274
  initialSort={{
@@ -11,7 +11,7 @@ import {
11
11
  } from "../viewport.testHelpers.ts"
12
12
  import * as stories from "./DataTable.stories.tsx"
13
13
 
14
- const { AllVariants, Default, Interactive, Responsive } =
14
+ const { AllVariants, Playground, Interactive, Responsive } =
15
15
  composeStories(stories)
16
16
 
17
17
  /**
@@ -23,7 +23,7 @@ const { AllVariants, Default, Interactive, Responsive } =
23
23
  */
24
24
  test("the table is drivable by role and name", async () => {
25
25
  const { canvas, canvasElement } =
26
- await mountStory(Default)
26
+ await mountStory(Playground)
27
27
 
28
28
  const table = expectAgentDrivable(canvas, {
29
29
  name: "Tasks",
@@ -43,7 +43,7 @@ test("the table is drivable by role and name", async () => {
43
43
  * cannot be sorted", where `"none"` would say the opposite.
44
44
  */
45
45
  test("sortable columns announce, unsortable ones stay silent", async () => {
46
- const { canvas } = await mountStory(Default)
46
+ const { canvas } = await mountStory(Playground)
47
47
 
48
48
  const updated = expectAgentDrivable(canvas, {
49
49
  name: "Updated",
@@ -11,7 +11,7 @@ it. The consumer that shaped it is **Docket** — due dates, scheduled dates, ph
11
11
  ranges, and a staleness threshold counted in days
12
12
  ([decision](../../../docs/decisions/2026-08-19-a-date-is-a-calendar-date-not-an-instant.md)).
13
13
 
14
- <Canvas of={DatePickerStories.Default} />
14
+ <Canvas of={DatePickerStories.Playground} />
15
15
 
16
16
  ## Props
17
17
 
@@ -1,3 +1,4 @@
1
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
1
2
  import type { Meta, StoryObj } from "@storybook/react"
2
3
  import type { ReactNode } from "react"
3
4
  import { useState } from "react"
@@ -99,7 +100,8 @@ const DatePickerHarness = ({
99
100
  * `19 aug`, `2026-08-19` and a bare `19` all resolve, and the line
100
101
  * underneath shows what they resolved to before anything commits.
101
102
  */
102
- export const Default: Story = {
103
+ export const Playground: Story = {
104
+ parameters: playgroundParameters,
103
105
  args: { label: "Due date" },
104
106
  render: () => <DatePickerHarness label="Due date" />,
105
107
  }
@@ -12,11 +12,11 @@ import {
12
12
  } from "../viewport.testHelpers.ts"
13
13
  import * as stories from "./DatePicker.stories.tsx"
14
14
 
15
- const { AllVariants, Default, Interactive } =
15
+ const { AllVariants, Playground, Interactive } =
16
16
  composeStories(stories)
17
17
 
18
18
  const openDefault = async () => {
19
- const mounted = await mountStory(Default)
19
+ const mounted = await mountStory(Playground)
20
20
 
21
21
  const input = expectAgentDrivable(mounted.canvas, {
22
22
  name: "Due date",
@@ -415,7 +415,7 @@ test("a container narrower than --cq-xs drops the weekday headers to one letter"
415
415
  // clamped to the space available and the calendar reads *that*.
416
416
  await setViewport({ height: 700, width: 260 })
417
417
 
418
- const { body, canvas } = await mountStory(Default)
418
+ const { body, canvas } = await mountStory(Playground)
419
419
 
420
420
  await userEvent.click(
421
421
  expectAgentDrivable(canvas, {
@@ -155,16 +155,34 @@ test("the day number round-trips across four centuries", () => {
155
155
  year: 2101,
156
156
  })
157
157
 
158
+ // ⚠️ ONE assertion, not 74 000 of them.
159
+ //
160
+ // This loop covers about 74 000 days, and it used to call `expect` on every
161
+ // one. Vitest builds an assertion object per call, so the assertion overhead
162
+ // WAS the whole cost of the test — it ran right up against the default 5 000
163
+ // ms timeout and started failing on 2026-09-14 when the hosted runners got
164
+ // slower. Collecting the mismatches and asserting once removes the overhead
165
+ // and keeps every day covered.
166
+ //
167
+ // It also reports better. The old shape stopped at the first bad day; this
168
+ // one names every day that failed, which is what you want from a round-trip
169
+ // over a century rule.
170
+ const mismatchedDayNumbers = []
171
+
158
172
  for (
159
173
  let dayNumber = from;
160
174
  dayNumber <= to;
161
175
  dayNumber += 1
162
176
  ) {
163
- expect(
164
- getDayNumber(getPlainDateFromDayNumber(dayNumber)),
165
- ).toBe(dayNumber)
177
+ if (
178
+ getDayNumber(getPlainDateFromDayNumber(dayNumber)) !==
179
+ dayNumber
180
+ )
181
+ mismatchedDayNumbers.push(dayNumber)
166
182
  }
167
183
 
184
+ expect(mismatchedDayNumbers).toEqual([])
185
+
168
186
  expect(
169
187
  getDayNumber({ day: 1, month: 1, year: 1970 }),
170
188
  ).toBe(0)
@@ -12,7 +12,7 @@ Close button, a scrolling body, an optional footer, and five sizes. This is what
12
12
  and hands the generic one back to the base layer
13
13
  ([decision](../../../docs/decisions/2026-08-03-modal-is-the-base-layer-and-dialog-is-the-component.md)).
14
14
 
15
- <Canvas of={DialogStories.Default} />
15
+ <Canvas of={DialogStories.Playground} />
16
16
 
17
17
  ## Props
18
18
 
@@ -1,4 +1,5 @@
1
1
  import { useVisibility } from "@charcuterie/logic"
2
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
2
3
  import type { Meta, StoryObj } from "@storybook/react"
3
4
  import type { ReactNode } from "react"
4
5
  import { useRef } from "react"
@@ -121,7 +122,8 @@ const InitialFocusDemo = (): ReactNode => {
121
122
  )
122
123
  }
123
124
 
124
- export const Default: Story = {
125
+ export const Playground: Story = {
126
+ parameters: playgroundParameters,
125
127
  args: {
126
128
  heading: "Bay 3",
127
129
  isVisible: false,
@@ -13,7 +13,7 @@ import * as stories from "./Dialog.stories.tsx"
13
13
  const {
14
14
  AllStates,
15
15
  AllVariants,
16
- Default,
16
+ Playground,
17
17
  InitialFocus,
18
18
  Interactive,
19
19
  NoBody,
@@ -49,7 +49,7 @@ test("a dialog with no body renders from heading and footer alone", async () =>
49
49
  })
50
50
 
51
51
  test("the dialog is reachable from a body-scoped query", async () => {
52
- const { body, canvas } = await mountStory(Default)
52
+ const { body, canvas } = await mountStory(Playground)
53
53
 
54
54
  await userEvent.click(
55
55
  expectAgentDrivable(canvas, {
@@ -9,7 +9,7 @@ import * as DropRailStories from "./DropRail.stories";
9
9
  Every destination at once, brought to the pointer instead of the pointer being carried to
10
10
  it.
11
11
 
12
- <Canvas of={DropRailStories.Default} />
12
+ <Canvas of={DropRailStories.Playground} />
13
13
 
14
14
  ## Props
15
15
 
@@ -1,3 +1,4 @@
1
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
1
2
  import type { Meta, StoryObj } from "@storybook/react"
2
3
  import { useState } from "react"
3
4
 
@@ -170,7 +171,9 @@ type Story = StoryObj<typeof meta>
170
171
  * group the card is already in — visible, unofferable, and saying so
171
172
  * to a screen reader rather than only by being dimmer.
172
173
  */
173
- export const Default: Story = {}
174
+ export const Playground: Story = {
175
+ parameters: playgroundParameters,
176
+ }
174
177
 
175
178
  /**
176
179
  * The case the component exists for. Thirty-four destinations do not
@@ -6,7 +6,7 @@ import { expectNoAxeViolations } from "../expectNoAxeViolations.testHelpers.ts"
6
6
  import { mountStory } from "../mountStory.testHelpers.ts"
7
7
  import * as stories from "./DropRail.stories.tsx"
8
8
 
9
- const { AllStates, Default, InAList, ManyTargets } =
9
+ const { AllStates, Playground, InAList, ManyTargets } =
10
10
  composeStories(stories)
11
11
 
12
12
  /**
@@ -25,7 +25,7 @@ const { AllStates, Default, InAList, ManyTargets } =
25
25
  */
26
26
 
27
27
  test("the rail is a listbox of destinations", async () => {
28
- const { canvas } = await mountStory(Default)
28
+ const { canvas } = await mountStory(Playground)
29
29
 
30
30
  const rail = canvas.getByRole("listbox", {
31
31
  name: "Move to which project",
@@ -51,7 +51,7 @@ test("a closed rail renders nothing at all", async () => {
51
51
  })
52
52
 
53
53
  test("the group a card is already in is shown but not offerable", async () => {
54
- const { canvas } = await mountStory(Default)
54
+ const { canvas } = await mountStory(Playground)
55
55
 
56
56
  const current = canvas.getByRole("option", {
57
57
  name: /Atlas Ingest/,
@@ -64,7 +64,7 @@ test("the group a card is already in is shown but not offerable", async () => {
64
64
  })
65
65
 
66
66
  test("an archived destination is refused", async () => {
67
- const { canvas } = await mountStory(Default)
67
+ const { canvas } = await mountStory(Playground)
68
68
 
69
69
  expect(
70
70
  canvas.getByRole("option", {
@@ -14,7 +14,7 @@ Designed fresh rather than ported: the two repos that had a real `EmptyState` wi
14
14
  variants were bambuddy and spoolbuddy, which are upstream projects rather than Kevin's
15
15
  code, so that evidence was withdrawn from the plan.
16
16
 
17
- <Canvas of={EmptyStateStories.Default} />
17
+ <Canvas of={EmptyStateStories.Playground} />
18
18
 
19
19
  ## Props
20
20
 
@@ -1,3 +1,4 @@
1
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
1
2
  import type { Meta, StoryObj } from "@storybook/react"
2
3
  import { Button } from "../Button/Button.tsx"
3
4
  import {
@@ -30,7 +31,8 @@ type Story = StoryObj<typeof meta>
30
31
  * The heading is the handle. Eleven copies of "Nothing here" in a
31
32
  * `<div>` are indistinguishable to an agent; a named heading is not.
32
33
  */
33
- export const Default: Story = {
34
+ export const Playground: Story = {
35
+ parameters: playgroundParameters,
34
36
  args: {
35
37
  description:
36
38
  "Insert a disc and rip-deck will pick it up automatically.",
@@ -6,11 +6,11 @@ import { mountStory } from "../mountStory.testHelpers.ts"
6
6
  import { expectAgentDrivable } from "../testing/index.ts"
7
7
  import * as stories from "./EmptyState.stories.tsx"
8
8
 
9
- const { Default, DeeplyNested, Interactive } =
9
+ const { Playground, DeeplyNested, Interactive } =
10
10
  composeStories(stories)
11
11
 
12
12
  test("the heading is the handle", async () => {
13
- const { canvas } = await mountStory(Default)
13
+ const { canvas } = await mountStory(Playground)
14
14
 
15
15
  expectAgentDrivable(canvas, {
16
16
  name: "No discs queued",
@@ -25,7 +25,7 @@ wrong in the *other* file. Half of them are broken and nothing says which half.
25
25
  the argument for a component rather than a convention — here the id is minted and consumed
26
26
  in one place and cannot be spelled twice.
27
27
 
28
- <Canvas of={FieldStories.Default} />
28
+ <Canvas of={FieldStories.Playground} />
29
29
 
30
30
  `Field` is also how a `Picker` (or `Button`, or an app's own control) sits next to
31
31
  its label **without butting against the last word**. Those controls are
@@ -1,3 +1,4 @@
1
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
1
2
  import type { Meta, StoryObj } from "@storybook/react"
2
3
 
3
4
  import {
@@ -26,7 +27,8 @@ export default meta
26
27
 
27
28
  type Story = StoryObj<typeof meta>
28
29
 
29
- export const Default: Story = {
30
+ export const Playground: Story = {
31
+ parameters: playgroundParameters,
30
32
  args: {
31
33
  children: (
32
34
  <input className={TEXT_INPUT_CLASS} type="text" />
@@ -12,7 +12,7 @@ const {
12
12
  AdoptsOverlayTriggerId,
13
13
  AllStates,
14
14
  AllVariants,
15
- Default,
15
+ Playground,
16
16
  ForwardsRestProps,
17
17
  Group,
18
18
  Nested,
@@ -79,7 +79,7 @@ test("an overlay trigger keeps the id the label points at", async () => {
79
79
 
80
80
  test("the label names the control it points at", async () => {
81
81
  const { canvas, canvasElement } =
82
- await mountStory(Default)
82
+ await mountStory(Playground)
83
83
 
84
84
  // The whole point of the component in one query: the control is
85
85
  // findable by the *label's* text, which is only true if `htmlFor`
@@ -112,7 +112,7 @@ test("the label names the control it points at", async () => {
112
112
  * the other component's suite.
113
113
  */
114
114
  test("the label carries a derivable id for non-labelable controls", async () => {
115
- const { canvas } = await mountStory(Default)
115
+ const { canvas } = await mountStory(Playground)
116
116
 
117
117
  const control = expectAgentDrivable(canvas, {
118
118
  name: "Output directory",
@@ -133,7 +133,7 @@ test("the label carries a derivable id for non-labelable controls", async () =>
133
133
  })
134
134
 
135
135
  test("a description is announced with the control", async () => {
136
- const { canvas } = await mountStory(Default)
136
+ const { canvas } = await mountStory(Playground)
137
137
 
138
138
  const control = expectAgentDrivable(canvas, {
139
139
  name: "Output directory",
@@ -9,7 +9,7 @@ import * as FileDropZoneStories from "./FileDropZone.stories";
9
9
  The one drag target in the fleet is gallery-downloader's, and it **gets the hard part
10
10
  right** — credit where it is due, and the fix is reproduced here.
11
11
 
12
- <Canvas of={FileDropZoneStories.Default} />
12
+ <Canvas of={FileDropZoneStories.Playground} />
13
13
 
14
14
  ## Props
15
15
 
@@ -1,3 +1,4 @@
1
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
1
2
  import type { Meta, StoryObj } from "@storybook/react"
2
3
  import { useState } from "react"
3
4
 
@@ -25,7 +26,8 @@ export default meta
25
26
 
26
27
  type Story = StoryObj<typeof meta>
27
28
 
28
- export const Default: Story = {
29
+ export const Playground: Story = {
30
+ parameters: playgroundParameters,
29
31
  args: {
30
32
  description: "ISO or MKV, up to 50 GB.",
31
33
  label: "Drop a disc image here",
@@ -6,7 +6,7 @@ import { expectNoAxeViolations } from "../expectNoAxeViolations.testHelpers.ts"
6
6
  import { mountStory } from "../mountStory.testHelpers.ts"
7
7
  import * as stories from "./FileDropZone.stories.tsx"
8
8
 
9
- const { AllStates, AllVariants, Default, Interactive } =
9
+ const { AllStates, AllVariants, Playground, Interactive } =
10
10
  composeStories(stories)
11
11
 
12
12
  /**
@@ -45,7 +45,7 @@ const { AllStates, AllVariants, Default, Interactive } =
45
45
  */
46
46
  test("the zone is a real file input, reachable and named", async () => {
47
47
  const { canvas, canvasElement } =
48
- await mountStory(Default)
48
+ await mountStory(Playground)
49
49
 
50
50
  const input = canvas.getByLabelText(
51
51
  "Drop a disc image here",
@@ -198,7 +198,7 @@ test("a dropped link reports as text", async () => {
198
198
  * the correct fix and is reproduced here.
199
199
  */
200
200
  test("the highlight survives crossing a child element", async () => {
201
- const { canvas } = await mountStory(Default)
201
+ const { canvas } = await mountStory(Playground)
202
202
 
203
203
  const zone = canvas
204
204
  .getByLabelText("Drop a disc image here")
@@ -9,7 +9,7 @@ import * as HeaderStories from "./Header.stories";
9
9
  The `<header>` landmark, the app's name, and the controls that belong to the frame rather
10
10
  than to the page. Ten repos hand-roll this row; two of them wrote the same string.
11
11
 
12
- <Canvas of={HeaderStories.Default} />
12
+ <Canvas of={HeaderStories.Playground} />
13
13
 
14
14
  ## Props
15
15
 
@@ -1,3 +1,4 @@
1
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
1
2
  import type { Meta, StoryObj } from "@storybook/react"
2
3
 
3
4
  import { Badge } from "../Badge/Badge.tsx"
@@ -41,7 +42,8 @@ type Story = StoryObj<typeof meta>
41
42
  * and a fill that is `surface-raised` rather than the page's own
42
43
  * colour.
43
44
  */
44
- export const Default: Story = {
45
+ export const Playground: Story = {
46
+ parameters: playgroundParameters,
45
47
  args: { heading: "Rip Deck" },
46
48
  render: (headerProps) => (
47
49
  <Shell>
@@ -15,7 +15,7 @@ A screen reader announces the last of those as "↶", and
15
15
  the fleet is not agent-drivable today, and the reason this component exists as something
16
16
  other than `<Button sizing="icon">`.
17
17
 
18
- <Canvas of={IconButtonStories.Default} />
18
+ <Canvas of={IconButtonStories.Playground} />
19
19
 
20
20
  ## Props
21
21
 
@@ -1,3 +1,4 @@
1
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
1
2
  import type { Meta, StoryObj } from "@storybook/react"
2
3
 
3
4
  import { controlSizeArgType } from "../argTypes.storyHelpers.ts"
@@ -48,7 +49,8 @@ type Story = StoryObj<typeof meta>
48
49
  * bare `<button>` today, so a screen reader announces "↶" and
49
50
  * `getByRole("button", { name: "Undo" })` finds nothing.
50
51
  */
51
- export const Default: Story = {
52
+ export const Playground: Story = {
53
+ parameters: playgroundParameters,
52
54
  args: { children: UNDO_ICON, label: "Undo" },
53
55
  }
54
56
 
@@ -10,7 +10,7 @@ import { mountStory } from "../mountStory.testHelpers.ts"
10
10
  import { expectAgentDrivable } from "../testing/index.ts"
11
11
  import meta, * as stories from "./IconButton.stories.tsx"
12
12
 
13
- const { Default, RawGlyph } = composeStories(stories)
13
+ const { Playground, RawGlyph } = composeStories(stories)
14
14
 
15
15
  /**
16
16
  * The assertion the fleet fails today: plex-channels renders `↶`
@@ -18,7 +18,7 @@ const { Default, RawGlyph } = composeStories(stories)
18
18
  * query finds nothing.
19
19
  */
20
20
  test("a glyph gets a name", async () => {
21
- const { canvas } = await mountStory(Default)
21
+ const { canvas } = await mountStory(Playground)
22
22
 
23
23
  expectAgentDrivable(canvas, {
24
24
  name: "Undo",
@@ -16,7 +16,7 @@ So a `Lightbox` is a **skin over `Dialog`**, not a second dialog. `Dialog` (thro
16
16
  `object-contain` image clamped to the viewport, so a 2:3 poster and a 16:9 still both land
17
17
  whole.
18
18
 
19
- <Canvas of={LightboxStories.Default} />
19
+ <Canvas of={LightboxStories.Playground} />
20
20
 
21
21
  ## Props
22
22
 
@@ -1,4 +1,5 @@
1
1
  import { useVisibility } from "@charcuterie/logic"
2
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
2
3
  import type { Meta, StoryObj } from "@storybook/react"
3
4
  import type { ReactNode } from "react"
4
5
 
@@ -51,7 +52,8 @@ type Story = StoryObj<typeof meta>
51
52
  * component owns its open state. This is what a rip card passes —
52
53
  * one `Lightbox` with the poster as its `thumbnail`.
53
54
  */
54
- export const Default: Story = {
55
+ export const Playground: Story = {
56
+ parameters: playgroundParameters,
55
57
  args: {
56
58
  thumbnail: <PosterThumb />,
57
59
  },
@@ -7,11 +7,11 @@ import { mountStory } from "../mountStory.testHelpers.ts"
7
7
  import { expectAgentDrivable } from "../testing/index.ts"
8
8
  import * as stories from "./Lightbox.stories.tsx"
9
9
 
10
- const { Controlled, Default, Interactive, WithCaption } =
10
+ const { Controlled, Playground, Interactive, WithCaption } =
11
11
  composeStories(stories)
12
12
 
13
13
  test("the thumbnail opens the enlarged image", async () => {
14
- const { body, canvas } = await mountStory(Default)
14
+ const { body, canvas } = await mountStory(Playground)
15
15
 
16
16
  await userEvent.click(
17
17
  expectAgentDrivable(canvas, {
@@ -12,7 +12,7 @@ type-ahead, Home/End, the mobile wheel picker, form submission, `:invalid` and a
12
12
  `Listbox` is for the cases `<option>` cannot render — a leading icon, two lines, a trailing
13
13
  badge ([decision](../../../docs/decisions/2026-08-03-listbox-and-combobox-are-siblings-of-select.md)).
14
14
 
15
- <Canvas of={ListboxStories.Default} />
15
+ <Canvas of={ListboxStories.Playground} />
16
16
 
17
17
  ## Props
18
18
 
@@ -1,4 +1,5 @@
1
1
  import { useVisibility } from "@charcuterie/logic"
2
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
2
3
  import type { ControlSize } from "@charcuterie/tokens"
3
4
  import type { Meta, StoryObj } from "@storybook/react"
4
5
  import type { ReactNode } from "react"
@@ -142,7 +143,8 @@ const ListboxHarness = ({
142
143
  )
143
144
  }
144
145
 
145
- export const Default: Story = {
146
+ export const Playground: Story = {
147
+ parameters: playgroundParameters,
146
148
  args: {
147
149
  isVisible: false,
148
150
  onDismiss: () => {},
@@ -7,11 +7,11 @@ import { mountStory } from "../mountStory.testHelpers.ts"
7
7
  import { expectAgentDrivable } from "../testing/index.ts"
8
8
  import * as stories from "./Listbox.stories.tsx"
9
9
 
10
- const { AllStates, AllVariants, Default, Interactive } =
10
+ const { AllStates, AllVariants, Playground, Interactive } =
11
11
  composeStories(stories)
12
12
 
13
13
  test("a button opens a listbox whose rows are options", async () => {
14
- const { body, canvas } = await mountStory(Default)
14
+ const { body, canvas } = await mountStory(Playground)
15
15
 
16
16
  const trigger = expectAgentDrivable(canvas, {
17
17
  name: "Choose a language",
@@ -74,7 +74,7 @@ test("opening focuses the seeded selection, which reads selected", async () => {
74
74
  })
75
75
 
76
76
  test("the arrow keys move focus and skip the disabled option", async () => {
77
- const { body, canvas } = await mountStory(Default)
77
+ const { body, canvas } = await mountStory(Playground)
78
78
 
79
79
  await userEvent.click(
80
80
  expectAgentDrivable(canvas, {
@@ -116,7 +116,7 @@ test("the arrow keys move focus and skip the disabled option", async () => {
116
116
  })
117
117
 
118
118
  test("type-ahead jumps to the first match", async () => {
119
- const { body, canvas } = await mountStory(Default)
119
+ const { body, canvas } = await mountStory(Playground)
120
120
 
121
121
  await userEvent.click(
122
122
  expectAgentDrivable(canvas, {
@@ -163,7 +163,7 @@ test("Enter selects the focused option and closes", async () => {
163
163
  })
164
164
 
165
165
  test("Escape dismisses without choosing, and there is one tab stop", async () => {
166
- const { body, canvas } = await mountStory(Default)
166
+ const { body, canvas } = await mountStory(Playground)
167
167
 
168
168
  await userEvent.click(
169
169
  expectAgentDrivable(canvas, {
@@ -9,7 +9,7 @@ import * as LiveStatusIndicatorStories from "./LiveStatusIndicator.stories";
9
9
  Four repos, four implementations, and **it is the thing users read most** — a wall-mounted
10
10
  panel showing stale data under a green dot is worse than one showing nothing.
11
11
 
12
- <Canvas of={LiveStatusIndicatorStories.Default} />
12
+ <Canvas of={LiveStatusIndicatorStories.Playground} />
13
13
 
14
14
  ## Props
15
15
 
@@ -2,6 +2,7 @@ import {
2
2
  connectionTransitions,
3
3
  useStatus,
4
4
  } from "@charcuterie/logic"
5
+ import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters"
5
6
  import type { Meta, StoryObj } from "@storybook/react"
6
7
 
7
8
  import { connectionStatusArgType } from "../argTypes.storyHelpers.ts"
@@ -40,7 +41,8 @@ type Story = StoryObj<typeof meta>
40
41
  * handle for a Playwright assertion, because it survives translation
41
42
  * where the visible wording does not.
42
43
  */
43
- export const Default: Story = {
44
+ export const Playground: Story = {
45
+ parameters: playgroundParameters,
44
46
  args: { status: "connected" },
45
47
  }
46
48
 
@@ -6,10 +6,10 @@ import { mountStory } from "../mountStory.testHelpers.ts"
6
6
  import { expectAgentDrivable } from "../testing/index.ts"
7
7
  import * as stories from "./LiveStatusIndicator.stories.tsx"
8
8
 
9
- const { Default, Interactive } = composeStories(stories)
9
+ const { Playground, Interactive } = composeStories(stories)
10
10
 
11
11
  test("it is a named live region with a stable status handle", async () => {
12
- const { canvas } = await mountStory(Default)
12
+ const { canvas } = await mountStory(Playground)
13
13
 
14
14
  const indicator = expectAgentDrivable(canvas, {
15
15
  name: "Connected",