@charcuterie/ui 3.32.0 → 3.34.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 (76) hide show
  1. package/README.md +30 -0
  2. package/dist/AdaptiveGrid/useAdaptiveColumns.d.ts +16 -0
  3. package/dist/AdaptiveGrid/useAdaptiveColumns.d.ts.map +1 -1
  4. package/dist/AdaptiveGrid/useAdaptiveColumns.js +1 -0
  5. package/dist/AdaptiveGrid/useAdaptiveColumns.js.map +1 -1
  6. package/dist/Board/Board.d.ts.map +1 -1
  7. package/dist/Board/Board.js +2 -2
  8. package/dist/Board/Board.js.map +1 -1
  9. package/dist/RangeSlider/RangeSlider.d.ts +117 -0
  10. package/dist/RangeSlider/RangeSlider.d.ts.map +1 -0
  11. package/dist/RangeSlider/RangeSlider.js +242 -0
  12. package/dist/RangeSlider/RangeSlider.js.map +1 -0
  13. package/dist/RangeSlider/rangeSliderValue.d.ts +102 -0
  14. package/dist/RangeSlider/rangeSliderValue.d.ts.map +1 -0
  15. package/dist/RangeSlider/rangeSliderValue.js +116 -0
  16. package/dist/RangeSlider/rangeSliderValue.js.map +1 -0
  17. package/dist/SegmentedControl/SegmentedControl.d.ts +12 -1
  18. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  19. package/dist/SegmentedControl/SegmentedControl.js +3 -3
  20. package/dist/SegmentedControl/SegmentedControl.js.map +1 -1
  21. package/dist/SegmentedControl/SegmentedOption.d.ts +2 -1
  22. package/dist/SegmentedControl/SegmentedOption.d.ts.map +1 -1
  23. package/dist/SegmentedControl/SegmentedOption.js +7 -2
  24. package/dist/SegmentedControl/SegmentedOption.js.map +1 -1
  25. package/dist/Slider/Slider.d.ts +6 -1
  26. package/dist/Slider/Slider.d.ts.map +1 -1
  27. package/dist/Slider/Slider.js +8 -22
  28. package/dist/Slider/Slider.js.map +1 -1
  29. package/dist/TimecodeInput/TimecodeInput.d.ts +88 -0
  30. package/dist/TimecodeInput/TimecodeInput.d.ts.map +1 -0
  31. package/dist/TimecodeInput/TimecodeInput.js +258 -0
  32. package/dist/TimecodeInput/TimecodeInput.js.map +1 -0
  33. package/dist/TimecodeInput/timecode.d.ts +132 -0
  34. package/dist/TimecodeInput/timecode.d.ts.map +1 -0
  35. package/dist/TimecodeInput/timecode.js +246 -0
  36. package/dist/TimecodeInput/timecode.js.map +1 -0
  37. package/dist/VirtualizedGrid/VirtualizedGrid.d.ts +35 -0
  38. package/dist/VirtualizedGrid/VirtualizedGrid.d.ts.map +1 -1
  39. package/dist/VirtualizedGrid/VirtualizedGrid.js +37 -1
  40. package/dist/VirtualizedGrid/VirtualizedGrid.js.map +1 -1
  41. package/dist/index.d.ts +7 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +3 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/sliderStyles.d.ts +39 -0
  46. package/dist/sliderStyles.d.ts.map +1 -0
  47. package/dist/sliderStyles.js +50 -0
  48. package/dist/sliderStyles.js.map +1 -0
  49. package/package.json +1 -1
  50. package/src/AdaptiveGrid/useAdaptiveColumns.ts +17 -0
  51. package/src/Board/Board.test.tsx +8 -0
  52. package/src/Board/Board.tsx +7 -1
  53. package/src/RangeSlider/RangeSlider.mdx +85 -0
  54. package/src/RangeSlider/RangeSlider.stories.tsx +346 -0
  55. package/src/RangeSlider/RangeSlider.test.tsx +452 -0
  56. package/src/RangeSlider/RangeSlider.tsx +595 -0
  57. package/src/RangeSlider/rangeSliderValue.test.ts +217 -0
  58. package/src/RangeSlider/rangeSliderValue.ts +185 -0
  59. package/src/SegmentedControl/SegmentedControl.stories.tsx +50 -0
  60. package/src/SegmentedControl/SegmentedControl.test.tsx +36 -1
  61. package/src/SegmentedControl/SegmentedControl.tsx +14 -0
  62. package/src/SegmentedControl/SegmentedOption.tsx +7 -0
  63. package/src/Slider/Slider.tsx +23 -29
  64. package/src/TimecodeInput/TimecodeInput.mdx +155 -0
  65. package/src/TimecodeInput/TimecodeInput.stories.tsx +304 -0
  66. package/src/TimecodeInput/TimecodeInput.test.tsx +279 -0
  67. package/src/TimecodeInput/TimecodeInput.tsx +493 -0
  68. package/src/TimecodeInput/timecode.test.ts +236 -0
  69. package/src/TimecodeInput/timecode.ts +391 -0
  70. package/src/VirtualizedGrid/VirtualizedGrid.mdx +21 -0
  71. package/src/VirtualizedGrid/VirtualizedGrid.stories.tsx +64 -0
  72. package/src/VirtualizedGrid/VirtualizedGrid.test.tsx +122 -3
  73. package/src/VirtualizedGrid/VirtualizedGrid.tsx +37 -1
  74. package/src/index.ts +18 -0
  75. package/src/sliderStyles.ts +69 -0
  76. package/src/sourceRules.test.ts +25 -1
package/README.md CHANGED
@@ -96,6 +96,36 @@ it — the class really was in the DOM, tsc never reads the CSS, and unstyled ma
96
96
  axe
97
97
  ([decision](../../docs/decisions/2026-09-01-a-tile-that-acts-is-its-own-component-and-shares-only-the-box.md)).
98
98
 
99
+ **`TimecodeInput` is the first field the fleet could not write down twice the same way.**
100
+ QueuePilot is adding "play only this section of a video", and the *printing* half of a
101
+ timecode already exists five times — queuepilot's `clock` and `toClock`, castkit's
102
+ `formatTime`, and mux-magic's two modal formatters — with three different answers to whether
103
+ the hour is shown and two to whether the minute is padded, so the same position renders
104
+ differently in two panels of one app. The *reading* half exists nowhere. It is a text field
105
+ rather than an `<input type="time">` for the reason `Select` is deprecated and `Slider` is a
106
+ `div`: the platform widget is OS-painted, and it cannot carry a millisecond anyway. The
107
+ grammar is ordered, anchored and total — `90` is ninety seconds, `90:00` is ninety minutes,
108
+ and `1:90` is refused by name rather than carried into `2:30`, which is the `1:60` trap
109
+ mux-magic wrote down in 2023. `isRange` edits a section whose **two ends are independently
110
+ optional**; an inverted section swaps, and a zero-length one is refused, because a section
111
+ with no length plays nothing
112
+ ([decision](../../docs/decisions/2026-09-01-a-timecode-is-milliseconds-and-a-section-is-a-mode.md)).
113
+ **`RangeSlider` is the two-thumb range**, and it exists because
114
+ [the Slider record](../../docs/decisions/2026-08-22-the-slider-is-a-div-with-role-slider-not-an-input-range.md)
115
+ said one would be a different widget: QueuePilot plays *only a section* of a video, so a
116
+ user drags two handles over a film's runtime and reads the result beside a `TimecodeInput`.
117
+ `Slider` puts `role="slider"`, the tab stop and the pointer target on the **track**, and two
118
+ values cannot live on one accessible object — so here the role moves to the thumbs, the
119
+ track becomes a `role="group"` carrying the label, and one tab stop becomes two. That is why
120
+ it is a component rather than an `isRange` mode: both halves of the test that made
121
+ `Combobox`'s `isMultiple` and `DatePicker`'s `isRange` modes — *the role does not change,
122
+ and the shared part is everything* — are false here. The thumbs **clamp** rather than swap,
123
+ so the handle under the pointer keeps its identity and each thumb reports the other as its
124
+ own `aria-valuemin`/`aria-valuemax`. What is genuinely shared is the arithmetic
125
+ (`Slider/sliderValue.ts`, called rather than copied) and the bar (`sliderStyles.ts`, the
126
+ same extraction `tileStyles.ts` is), compared as **computed** styles in the test
127
+ ([decision](../../docs/decisions/2026-09-01-a-two-thumb-range-is-its-own-component-and-shares-the-bar.md)).
128
+
99
129
  **The unified app shell adds four**: `Shell`, `Header`, `Rail`, `Main` — the fleet's largest
100
130
  single duplication, where ten of twelve UI repos hand-roll the page chrome and three of them
101
131
  have a file named `AppShell.tsx` (two of those headers are a *byte-identical* class string,
@@ -148,6 +148,22 @@ export declare const useAdaptiveColumns: <ContainerElement extends HTMLElement =
148
148
  * ⚠️ Never the element `contentMaxInlineSize` is applied to.
149
149
  */
150
150
  containerRef: RefObject<ContainerElement | null>;
151
+ /**
152
+ * Has the container been given a box yet?
153
+ *
154
+ * False in two situations that look identical from here and are
155
+ * both "no measurement has happened": the frame before
156
+ * `ResizeObserver` delivers its first record, and any time the
157
+ * container sits inside a `display: none` ancestor — which is
158
+ * what the `hidden` attribute is, and what a tab panel, a
159
+ * collapsed disclosure and a closed `<details>` all use.
160
+ *
161
+ * The distinction matters because a zero inline size is not a
162
+ * measurement of zero. It is the absence of one, and a consumer
163
+ * that treats it as a number lays out for a 0px container and
164
+ * then reads the correction as a change.
165
+ */
166
+ isLaidOut: boolean;
151
167
  /** What was picked, `"auto"` included. */
152
168
  choice: ColumnChoice;
153
169
  setChoice: (choice: ColumnChoice) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useAdaptiveColumns.d.ts","sourceRoot":"","sources":["../../src/AdaptiveGrid/useAdaptiveColumns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAStC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAStD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,MAAM,CAAA;IACjB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;CAChD,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAChC,iBAgBF,CAAA;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GACxC,KAAK,MAAM,KACV,iBAeD,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,8BAG9B;IACD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,iBAAiB,GAAG,SAAS,CAAA;CAC3C,KAAG,YAkBH,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC7B,gBAAgB,SAAS,WAAW,GAAG,cAAc,EACrD,yMAaC;IACD,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAA;IACrB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gDAAgD;IAChD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,KAAG;IACF,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,YAAY,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAChD,0CAA0C;IAC1C,MAAM,EAAE,YAAY,CAAA;IACpB,SAAS,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAA;CA8G1C,CAAA"}
1
+ {"version":3,"file":"useAdaptiveColumns.d.ts","sourceRoot":"","sources":["../../src/AdaptiveGrid/useAdaptiveColumns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAStC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAStD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,MAAM,CAAA;IACjB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;CAChD,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAChC,iBAgBF,CAAA;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GACxC,KAAK,MAAM,KACV,iBAeD,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,8BAG9B;IACD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,iBAAiB,GAAG,SAAS,CAAA;CAC3C,KAAG,YAkBH,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC7B,gBAAgB,SAAS,WAAW,GAAG,cAAc,EACrD,yMAaC;IACD,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAA;IACrB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gDAAgD;IAChD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,KAAG;IACF,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,YAAY,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAChD;;;;;;;;;;;;;;OAcG;IACH,SAAS,EAAE,OAAO,CAAA;IAClB,0CAA0C;IAC1C,MAAM,EAAE,YAAY,CAAA;IACpB,SAAS,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAA;CA+G1C,CAAA"}
@@ -147,6 +147,7 @@ export const useAdaptiveColumns = ({ blockSizeResolver, chromeBlockSize, columnI
147
147
  gutterInlineSize,
148
148
  singleInlineSize,
149
149
  }),
150
+ isLaidOut: availableInlineSize > 0,
150
151
  setChoice,
151
152
  };
152
153
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useAdaptiveColumns.js","sourceRoot":"","sources":["../../src/AdaptiveGrid/useAdaptiveColumns.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,SAAS,EACT,MAAM,EACN,QAAQ,EACR,oBAAoB,GACrB,MAAM,OAAO,CAAA;AAGd,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,0BAA0B,EAC1B,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,oBAAoB,CAAA;AAuE3B;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,GAAsB,EAAE,CAAC,CAAC;IACxB,GAAG,EAAE,GAAG,EAAE,CACR,OAAO,MAAM,KAAK,WAAW;QAC3B,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,MAAM,CAAC,WAAW;IACxB,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;QACtB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QAE3C,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QAChD,CAAC,CAAA;IACH,CAAC;CACF,CAAC,CAAA;AAEJ;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,GAAW,EACQ,EAAE,CAAC,CAAC;IACvB,IAAI,EAAE,GAAG,EAAE;QACT,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,kDAAkD;QACpD,CAAC;IACH,CAAC;CACF,CAAC,CAAA;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,UAAU,GAAG,0BAA0B,EACvC,WAAW,GAIZ,EAAgB,EAAE;IACjB,MAAM,MAAM,GAAG,WAAW,EAAE,IAAI,EAAE,IAAI,IAAI,CAAA;IAE1C,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACzC,OAAO,MAAM,CAAA;IACf,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAE7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;QACtC,OAAO,MAAM,CAAA;IACf,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAEhC,EACA,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,cAAc,GAAG,wBAAwB,EACzC,gBAAgB,GAAG,0BAA0B,EAC7C,mBAAmB,GAAG,iCAAiC,EACvD,WAAW,EACX,gBAAgB,EAChB,UAAU,GAqCX,EAmBC,EAAE;IACF,MAAM,YAAY,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAA;IAEnD,2DAA2D;IAC3D,gEAAgE;IAChE,+DAA+D;IAC/D,QAAQ;IACR,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9B,SAAS,EACP,iBAAiB,IAAI,yBAAyB,EAAE;QAClD,WAAW,EACT,WAAW;YACX,CAAC,UAAU,KAAK,SAAS;gBACvB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,6BAA6B,CAAC,UAAU,CAAC,CAAC;KACjD,CAAC,CAAC,CAAA;IAEH,MAAM,kBAAkB,GAAG,oBAAoB,CAC7C,KAAK,CAAC,SAAS,CAAC,SAAS,EACzB,KAAK,CAAC,SAAS,CAAC,GAAG;IACnB,8DAA8D;IAC9D,GAAG,EAAE,CAAC,CAAC,CACR,CAAA;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GACjD,QAAQ,CAAC,CAAC,CAAC,CAAA;IAEb,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAA;QAEtC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE;YAC9C,MAAM,IAAI,GACR,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,SAAS,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAA;YAEzC,yDAAyD;YACzD,yDAAyD;YACzD,0BAA0B;YAC1B,sBAAsB,CAAC,CAAC,OAAO,EAAE,EAAE,CACjC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAClC,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAE3B,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,UAAU,EAAE,CAAA;QACvB,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,QAAQ,CACxC,GAAG,EAAE,CACH,gBAAgB,CAAC;QACf,UAAU,EAAE,gBAAgB;QAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;KAC/B,CAAC,CACL,CAAA;IAED,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,IAAkB,EAAE,EAAE;QACrB,eAAe,CAAC,IAAI,CAAC,CAAA;QAErB,oDAAoD;QACpD,6DAA6D;QAC7D,OAAO;QACP,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IACxC,CAAC,EACD,CAAC,KAAK,CAAC,CACR,CAAA;IAED,MAAM,WAAW,GAAG,aAAa,CAAC;QAChC,kBAAkB;QAClB,mBAAmB;QACnB,eAAe;QACf,aAAa;QACb,SAAS;QACT,UAAU,EAAE,cAAc;QAC1B,mBAAmB;KACpB,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAA;IAExD,OAAO;QACL,WAAW;QACX,MAAM;QACN,OAAO;QACP,YAAY;QACZ,oBAAoB,EAAE,uBAAuB,CAAC;YAC5C,gBAAgB;YAChB,OAAO;YACP,gBAAgB;YAChB,gBAAgB;SACjB,CAAC;QACF,SAAS;KACV,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"useAdaptiveColumns.js","sourceRoot":"","sources":["../../src/AdaptiveGrid/useAdaptiveColumns.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Board.d.ts","sourceRoot":"","sources":["../../src/Board/Board.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AASpD,MAAM,MAAM,SAAS,GAAG;IACtB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IAC/B,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IAC3B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CACnC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH,eAAO,MAAM,KAAK,GAAI,yFASnB,UAAU,KAAG,SA6Nf,CAAA"}
1
+ {"version":3,"file":"Board.d.ts","sourceRoot":"","sources":["../../src/Board/Board.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AASpD,MAAM,MAAM,SAAS,GAAG;IACtB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IAC/B,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IAC3B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CACnC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH,eAAO,MAAM,KAAK,GAAI,yFASnB,UAAU,KAAG,SAmOf,CAAA"}
@@ -144,13 +144,13 @@ export const Board = ({ className, headingLevel = 3, label, laneLayout = "column
144
144
  */
145
145
  className: toClassName("@container/board", className), children: [_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(SegmentedControl, { className: toClassName("max-w-full flex-wrap", laneLayout === "rows"
146
146
  ? "hidden"
147
- : "cq-lg:hidden"), items: lanes.map((lane) => ({
147
+ : "cq-lg:hidden"), isFullWidth: true, items: lanes.map((lane) => ({
148
148
  // Stacked rather than `Todo (6)`, because the count is
149
149
  // the reason to look: a lane picker that reads
150
150
  // "In Progress (5)" on one line is a long label with a
151
151
  // number in it, and at 15rem three of them do not fit
152
152
  // on any line at all.
153
- label: (_jsxs("span", { className: "flex flex-col items-center leading-tight", children: [_jsx("span", { children: lane.label }), _jsx("span", { className: "font-normal text-content-muted text-xs", children: String(lane.itemCount ?? lane.items.length) })] })),
153
+ label: (_jsxs("span", { className: "flex flex-col items-center leading-tight", children: [_jsx("span", { className: "block whitespace-nowrap", children: lane.label }), _jsx("span", { className: "font-normal text-content-muted text-xs", children: String(lane.itemCount ?? lane.items.length) })] })),
154
154
  value: lane.key,
155
155
  })), label: `${label} lanes`, onChange: (value) => {
156
156
  setVisibleLaneKey(value ?? "");
@@ -1 +1 @@
1
- {"version":3,"file":"Board.js","sourceRoot":"","sources":["../../src/Board/Board.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Board.js","sourceRoot":"","sources":["../../src/Board/Board.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import type { IntentName } from "@charcuterie/tokens";
2
+ import type { ComponentPropsWithRef, ReactNode } from "react";
3
+ import type { SliderSize } from "../sliderStyles.ts";
4
+ import type { RangeSliderValue } from "./rangeSliderValue.ts";
5
+ /**
6
+ * A position along the range, drawn as a mark on the bar.
7
+ *
8
+ * Prop-driven and nothing more: a chapter list, a scene index, a set
9
+ * of preset prices. The component holds no model of what a tick
10
+ * means, and `label` is optional because a mark that needs no words
11
+ * is the common case.
12
+ */
13
+ export type RangeSliderTick = {
14
+ label?: string;
15
+ value: number;
16
+ };
17
+ export type RangeSliderProps = Omit<ComponentPropsWithRef<"div">, "children" | "defaultValue" | "onChange"> & {
18
+ intent?: IntentName;
19
+ isDisabled?: boolean;
20
+ isLabelVisible?: boolean;
21
+ /**
22
+ * Read-only in the `aria-readonly` sense: focusable, full contrast,
23
+ * announced as unchangeable — the same distinction `Slider` draws.
24
+ * A clip already sent to a renderer is this, not `isDisabled`: the
25
+ * span is still worth reading.
26
+ */
27
+ isReadOnly?: boolean;
28
+ isValueShown?: boolean;
29
+ /** Required. Each thumb's own name is built from it. */
30
+ label: string;
31
+ /** PageUp / PageDown. Defaults to a tenth of the range, as `Slider`'s does. */
32
+ largeStep?: number;
33
+ max?: number;
34
+ min?: number;
35
+ /**
36
+ * Fires on every movement — each arrow key, and each pointer sample
37
+ * while dragging. Use it to paint. See `onChangeEnd` for committing.
38
+ */
39
+ onChange?: (value: RangeSliderValue) => void;
40
+ /**
41
+ * Fires once, when the interaction ends: pointer release, or key up.
42
+ *
43
+ * The same split `Slider` settled, for the same reason. A clip
44
+ * preview that re-seeks a player from `onChange` issues one seek per
45
+ * pointer sample and arrives at the right frame **last**, behind a
46
+ * queue of stale ones.
47
+ */
48
+ onChangeEnd?: (value: RangeSliderValue) => void;
49
+ size?: SliderSize;
50
+ step?: number;
51
+ /**
52
+ * Marks along the bar. Positions in the same units as `value`, so a
53
+ * film's chapters are the offsets the app already has.
54
+ *
55
+ * A `label` is centred on its own mark and clamped inside the bar at
56
+ * both ends. Two marks closer together than a label box will overlap:
57
+ * the component draws what it is given, and a caller with dense marks
58
+ * passes the words only where there is room for them.
59
+ */
60
+ ticks?: readonly RangeSliderTick[];
61
+ /**
62
+ * Seeds the range; it does not control it. A drag paints from the
63
+ * component's own value, so a caller that commits on `onChangeEnd`
64
+ * alone still sees the thumbs follow the pointer.
65
+ */
66
+ value?: RangeSliderValue;
67
+ /**
68
+ * How each end reads aloud and, when `isValueShown`, on screen.
69
+ * This is what keeps timecodes out of the library: the component
70
+ * knows a number, the app knows it is 21:14.
71
+ */
72
+ valueFormat?: (value: number) => string;
73
+ };
74
+ /**
75
+ * A two-thumb range control: a span picked out along a bar, with an
76
+ * independently focusable handle at each end.
77
+ *
78
+ * It exists because QueuePilot lets a user play **only a section** of
79
+ * a video, and a clip's start and end are a shape `Slider` states it
80
+ * is not: *"a two-thumb range is a different widget with its own
81
+ * focus model"*
82
+ * ([decision](../../../../docs/decisions/2026-09-01-a-two-thumb-range-is-its-own-component-and-shares-the-bar.md)).
83
+ *
84
+ * ## Why this is a component and not `Slider isRange`
85
+ *
86
+ * `Combobox`'s `isMultiple` and `DatePicker`'s `isRange` are modes
87
+ * because neither changes the widget's role and both share nearly
88
+ * everything. Both halves of that test fail here.
89
+ *
90
+ * `Slider` puts `role="slider"`, the tab stop and the pointer target
91
+ * **on the track**, because one track reports one value. Two values
92
+ * cannot live on one accessible object, so here the role moves to the
93
+ * thumbs, the track becomes a `role="group"` carrying the label, and
94
+ * the tab stops go from one to two. A mode that rewrote its own role
95
+ * would break `getByRole("slider", { name })` in every consumer that
96
+ * had ever used the single-value one.
97
+ *
98
+ * What the two genuinely share is the arithmetic
99
+ * (`Slider/sliderValue.ts`, called rather than copied) and the bar
100
+ * (`../sliderStyles.ts`) — so a range slider snaps on the same grid
101
+ * and paints as the same control.
102
+ *
103
+ * ## The thumbs clamp, they do not swap
104
+ *
105
+ * A thumb dragged past its partner stops on it and the range collapses
106
+ * to zero width. The thumbs never trade identities mid-drag: the
107
+ * handle under the pointer is the one the user grabbed, and the
108
+ * focused handle is the one an arrow key moves. Each thumb reports the
109
+ * other as its own `aria-valuemin` / `aria-valuemax`, which is how a
110
+ * screen reader is told where this handle stops.
111
+ *
112
+ * A press on the bar moves the **nearer** thumb. When the two sit on
113
+ * the same value, the press's side decides — which is what lets a
114
+ * collapsed range be pulled open again in either direction.
115
+ */
116
+ export declare const RangeSlider: ({ className, intent, isDisabled, isLabelVisible, isReadOnly, isValueShown, label, largeStep, max, min, onChange, onChangeEnd, size, step, ticks, value, valueFormat, ...divProps }: RangeSliderProps) => ReactNode;
117
+ //# sourceMappingURL=RangeSlider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RangeSlider.d.ts","sourceRoot":"","sources":["../../src/RangeSlider/RangeSlider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,EACV,qBAAqB,EAGrB,SAAS,EACV,MAAM,OAAO,CAAA;AAWd,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAWpD,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAQ9B;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,qBAAqB,CAAC,KAAK,CAAC,EAC5B,UAAU,GAAG,cAAc,GAAG,UAAU,CACzC,GAAG;IACF,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAC5C;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAC/C,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;CACxC,CAAA;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,WAAW,GAAI,oLAmBzB,gBAAgB,KAAG,SA8ZrB,CAAA"}
@@ -0,0 +1,242 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useUniqueId } from "@charcuterie/logic";
3
+ import { useRef, useState } from "react";
4
+ import { FOCUS_RING_CLASS, INTENT_SOLID_FILL_CLASS, } from "../intentStyles.js";
5
+ import { fromFraction, toPercent, } from "../Slider/sliderValue.js";
6
+ import { SLIDER_ROW_CLASS, SLIDER_THUMB_CLASS, SLIDER_THUMB_OFFSET, SLIDER_THUMB_SIZE_CLASS, SLIDER_TRACK_CLASS, SLIDER_TRACK_SIZE_CLASS, } from "../sliderStyles.js";
7
+ import { toClassName } from "../toClassName.js";
8
+ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
9
+ import { getNearerThumb, getThumbBounds, moveThumb, snapRange, } from "./rangeSliderValue.js";
10
+ /** Half the tick-label box, which is what centres it on its mark. */
11
+ const TICK_LABEL_INLINE_SIZE = "4.5rem";
12
+ const TICK_LABEL_HALF = "2.25rem";
13
+ /**
14
+ * A two-thumb range control: a span picked out along a bar, with an
15
+ * independently focusable handle at each end.
16
+ *
17
+ * It exists because QueuePilot lets a user play **only a section** of
18
+ * a video, and a clip's start and end are a shape `Slider` states it
19
+ * is not: *"a two-thumb range is a different widget with its own
20
+ * focus model"*
21
+ * ([decision](../../../../docs/decisions/2026-09-01-a-two-thumb-range-is-its-own-component-and-shares-the-bar.md)).
22
+ *
23
+ * ## Why this is a component and not `Slider isRange`
24
+ *
25
+ * `Combobox`'s `isMultiple` and `DatePicker`'s `isRange` are modes
26
+ * because neither changes the widget's role and both share nearly
27
+ * everything. Both halves of that test fail here.
28
+ *
29
+ * `Slider` puts `role="slider"`, the tab stop and the pointer target
30
+ * **on the track**, because one track reports one value. Two values
31
+ * cannot live on one accessible object, so here the role moves to the
32
+ * thumbs, the track becomes a `role="group"` carrying the label, and
33
+ * the tab stops go from one to two. A mode that rewrote its own role
34
+ * would break `getByRole("slider", { name })` in every consumer that
35
+ * had ever used the single-value one.
36
+ *
37
+ * What the two genuinely share is the arithmetic
38
+ * (`Slider/sliderValue.ts`, called rather than copied) and the bar
39
+ * (`../sliderStyles.ts`) — so a range slider snaps on the same grid
40
+ * and paints as the same control.
41
+ *
42
+ * ## The thumbs clamp, they do not swap
43
+ *
44
+ * A thumb dragged past its partner stops on it and the range collapses
45
+ * to zero width. The thumbs never trade identities mid-drag: the
46
+ * handle under the pointer is the one the user grabbed, and the
47
+ * focused handle is the one an arrow key moves. Each thumb reports the
48
+ * other as its own `aria-valuemin` / `aria-valuemax`, which is how a
49
+ * screen reader is told where this handle stops.
50
+ *
51
+ * A press on the bar moves the **nearer** thumb. When the two sit on
52
+ * the same value, the press's side decides — which is what lets a
53
+ * collapsed range be pulled open again in either direction.
54
+ */
55
+ export const RangeSlider = ({ className, intent = "accent", isDisabled = false, isLabelVisible = false, isReadOnly = false, isValueShown = false, label, largeStep, max = 100, min = 0, onChange, onChangeEnd, size = "md", step = 1, ticks, value = { end: max, start: min }, valueFormat, ...divProps }) => {
56
+ const labelId = useUniqueId();
57
+ const trackRef = useRef(null);
58
+ const startThumbRef = useRef(null);
59
+ const endThumbRef = useRef(null);
60
+ // Null means "not dragging". The thumb rides along with the value
61
+ // because a drag has to keep moving the handle it picked up, even
62
+ // once the pointer has travelled past the other one and the "nearer"
63
+ // answer has changed.
64
+ const [drag, setDrag] = useState(null);
65
+ const isInert = isDisabled || isReadOnly;
66
+ const bounds = { max, min, step };
67
+ const committed = snapRange(value, bounds);
68
+ const shown = drag?.range ?? committed;
69
+ const bigStep = largeStep == null
70
+ ? (Math.max(min, max) - Math.min(min, max)) / 10
71
+ : largeStep;
72
+ const startPercent = toPercent(shown.start, min, max);
73
+ const endPercent = toPercent(shown.end, min, max);
74
+ const emit = (next, thumb, isEnd) => {
75
+ if (next.start !== shown.start ||
76
+ next.end !== shown.end) {
77
+ onChange?.(next);
78
+ }
79
+ if (isEnd) {
80
+ setDrag(null);
81
+ onChangeEnd?.(next);
82
+ return;
83
+ }
84
+ setDrag({ range: next, thumb });
85
+ };
86
+ /** The value the pointer at `clientX` is pointing at. */
87
+ const valueAt = (clientX) => {
88
+ const track = trackRef.current;
89
+ if (!track)
90
+ return shown.start;
91
+ const box = track.getBoundingClientRect();
92
+ if (box.width <= 0)
93
+ return shown.start;
94
+ // `left`/`width` are physical, from the layout box, and stay
95
+ // physical on purpose — `isRtl` is what turns them into a value.
96
+ // The logical-properties rule is about `className`, not geometry.
97
+ const fraction = (clientX - box.left) / box.width;
98
+ const isRtl = getComputedStyle(track).direction === "rtl";
99
+ return fromFraction(fraction, min, max, step, isRtl);
100
+ };
101
+ const onPointerDown = (event) => {
102
+ if (isInert || event.button !== 0)
103
+ return;
104
+ // The press is ours, and the default is what would undo it: a
105
+ // mousedown on a non-focusable element moves focus to the body,
106
+ // so the handle this handler just focused would lose it again a
107
+ // tick later. `Slider` never needed this because its pointer
108
+ // target IS its focusable element; here the bar is the target and
109
+ // the thumb is the tab stop.
110
+ event.preventDefault();
111
+ const at = valueAt(event.clientX);
112
+ const thumb = getNearerThumb({ at, range: shown });
113
+ // Capture on the GROUP rather than on the thumb, so a drag that
114
+ // leaves the bar vertically keeps reporting — and so a fast drag
115
+ // that outruns the thumb it is moving does not hand the pointer to
116
+ // the element underneath.
117
+ event.currentTarget.setPointerCapture(event.pointerId);
118
+ // Focus follows the grab. A pointer user who then reaches for the
119
+ // arrow keys is moving the handle they were just dragging, which
120
+ // is the only answer that does not need looking at.
121
+ //
122
+ // The handle wears its focus ring for the length of the drag,
123
+ // which is a script `focus()` matching `:focus-visible`. On a
124
+ // one-thumb control that would be the ring-after-a-click the house
125
+ // style rejects; here it is the answer to "which of the two am I
126
+ // holding", and it is the same mark the keyboard path leaves.
127
+ const thumbElement = thumb === "start"
128
+ ? startThumbRef.current
129
+ : endThumbRef.current;
130
+ thumbElement?.focus();
131
+ emit(moveThumb({ bounds, next: at, range: shown, thumb }), thumb, false);
132
+ };
133
+ const onPointerMove = (event) => {
134
+ if (isInert || drag == null)
135
+ return;
136
+ emit(moveThumb({
137
+ bounds,
138
+ next: valueAt(event.clientX),
139
+ range: shown,
140
+ thumb: drag.thumb,
141
+ }), drag.thumb, false);
142
+ };
143
+ const onPointerUp = (event) => {
144
+ if (isInert || drag == null)
145
+ return;
146
+ event.currentTarget.releasePointerCapture(event.pointerId);
147
+ emit(moveThumb({
148
+ bounds,
149
+ next: valueAt(event.clientX),
150
+ range: shown,
151
+ thumb: drag.thumb,
152
+ }), drag.thumb, true);
153
+ };
154
+ /**
155
+ * `Slider`'s key handling, per thumb. Home and End are absolute and
156
+ * are clamped at the other thumb like any other movement, so End on
157
+ * the start handle means "as far right as this handle goes".
158
+ */
159
+ const getKeyedValue = (event, current) => {
160
+ switch (event.key) {
161
+ case "ArrowDown":
162
+ case "ArrowLeft":
163
+ return current - step;
164
+ case "ArrowRight":
165
+ case "ArrowUp":
166
+ return current + step;
167
+ case "End":
168
+ return Math.max(min, max);
169
+ case "Home":
170
+ return Math.min(min, max);
171
+ case "PageDown":
172
+ return current - bigStep;
173
+ case "PageUp":
174
+ return current + bigStep;
175
+ default:
176
+ return null;
177
+ }
178
+ };
179
+ const onThumbKeyDown = (thumb) => (event) => {
180
+ if (isInert)
181
+ return;
182
+ const next = getKeyedValue(event, shown[thumb]);
183
+ if (next == null)
184
+ return;
185
+ event.preventDefault();
186
+ // Keys commit immediately, as `Slider`'s do: a key press is a
187
+ // discrete interaction with no release to wait for.
188
+ emit(moveThumb({ bounds, next, range: shown, thumb }), thumb, true);
189
+ };
190
+ const renderThumb = (thumb) => {
191
+ const thumbBounds = getThumbBounds({
192
+ bounds,
193
+ range: shown,
194
+ thumb,
195
+ });
196
+ const percent = thumb === "start" ? startPercent : endPercent;
197
+ return (_jsx("span", { "aria-disabled": isDisabled || undefined, "aria-label": `${label} ${thumb}`, "aria-orientation": "horizontal", "aria-readonly": isReadOnly || undefined, "aria-valuemax": thumbBounds.max, "aria-valuemin": thumbBounds.min, "aria-valuenow": shown[thumb], "aria-valuetext": valueFormat?.(shown[thumb]), className: toClassName(SLIDER_THUMB_CLASS, SLIDER_THUMB_SIZE_CLASS[size], INTENT_SOLID_FILL_CLASS[intent], FOCUS_RING_CLASS, isReadOnly ? "cursor-default" : ""), onKeyDown: onThumbKeyDown(thumb), ref: thumb === "start" ? startThumbRef : endThumbRef, role: "slider",
198
+ // Pulled back by half its own width so it sits ON the value
199
+ // rather than starting at it. `margin-inline-start`, not
200
+ // `translate: -50%`: `translate` is physical, so in RTL it
201
+ // would shift the thumb the wrong way and 0% would hang off
202
+ // the start edge.
203
+ style: {
204
+ insetInlineStart: `${percent}%`,
205
+ marginInlineStart: SLIDER_THUMB_OFFSET[size],
206
+ }, tabIndex: isDisabled ? -1 : 0 }, thumb));
207
+ };
208
+ const shownText = valueFormat == null
209
+ ? `${shown.start} to ${shown.end}`
210
+ : `${valueFormat(shown.start)} to ${valueFormat(shown.end)}`;
211
+ return (_jsxs("div", { ...divProps, className: toClassName("flex flex-col gap-1",
212
+ // A definite floor, for `Slider`'s reason: the root has no
213
+ // intrinsic width of its own, so in a shrink-to-fit parent it
214
+ // would collapse to the width of a thumb with every gate
215
+ // still green.
216
+ "min-w-40", className), children: [isLabelVisible || isValueShown ? (_jsxs("div", { className: "flex items-baseline justify-between gap-2 text-sm", children: [isLabelVisible ? (_jsx("span", { className: "text-content-secondary", id: labelId, children: label })) : (_jsx(VisuallyHidden, { id: labelId, children: label })), isValueShown ? (_jsx("span", { className: "text-content-muted tabular-nums", children: shownText })) : null] })) : (_jsx(VisuallyHidden, { id: labelId, children: label })), _jsxs("div", { "aria-labelledby": labelId, className: toClassName(SLIDER_ROW_CLASS,
217
+ // NOT `ARIA_DISABLED_CLASS`, for the reason `Slider` gives:
218
+ // that constant paints a box-shaped control, and this
219
+ // control's body is a 2px bar inside a 40px row.
220
+ //
221
+ // `pointer-events-none` is load-bearing rather than
222
+ // cosmetic — without a real `:disabled` the hover rules
223
+ // still match.
224
+ isDisabled
225
+ ? "pointer-events-none opacity-55"
226
+ : "", isReadOnly ? "cursor-default" : ""), onPointerCancel: onPointerUp, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, ref: trackRef, role: "group", children: [_jsx("span", { className: toClassName(SLIDER_TRACK_CLASS, SLIDER_TRACK_SIZE_CLASS[size]), children: _jsx("span", { className: toClassName("block h-full rounded-full", INTENT_SOLID_FILL_CLASS[intent]), style: {
227
+ inlineSize: `${endPercent - startPercent}%`,
228
+ marginInlineStart: `${startPercent}%`,
229
+ } }) }), ticks?.map((tick) => (_jsx("span", { "aria-hidden": "true", className: "absolute h-2 w-px bg-border-strong", style: {
230
+ insetInlineStart: `${toPercent(tick.value, min, max)}%`,
231
+ } }, tick.value))), renderThumb("start"), renderThumb("end")] }), ticks?.some((tick) => tick.label != null) ? (_jsx("div", { "aria-hidden": "true", className: "relative h-4 w-full text-content-muted text-xs", children: ticks.map((tick) => tick.label == null ? null : (_jsx("span", { className: "absolute text-center",
232
+ // Centred on its mark, and `clamp`ed so the first and
233
+ // last labels stay inside the bar instead of hanging
234
+ // off its ends. A fixed box is what makes the centring
235
+ // possible at all: the label's own width is not known
236
+ // here, and `translate: -50%` is physical.
237
+ style: {
238
+ inlineSize: TICK_LABEL_INLINE_SIZE,
239
+ insetInlineStart: `clamp(0rem, calc(${toPercent(tick.value, min, max)}% - ${TICK_LABEL_HALF}), calc(100% - ${TICK_LABEL_INLINE_SIZE}))`,
240
+ }, children: tick.label }, tick.value))) })) : null] }));
241
+ };
242
+ //# sourceMappingURL=RangeSlider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RangeSlider.js","sourceRoot":"","sources":["../../src/RangeSlider/RangeSlider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * The arithmetic behind `RangeSlider`: everything the second thumb
3
+ * adds to `Slider`'s, and nothing `Slider` already answers.
4
+ *
5
+ * The single-value functions are **called**, never re-derived —
6
+ * `snapToStep` and `clampToRange` come from `../Slider/sliderValue.ts`
7
+ * — so a range slider snaps on exactly the grid a plain slider snaps
8
+ * on. Anchoring on `min` rather than on zero, the re-clamp after a
9
+ * snap, and the float-step rounding are all already right there, and
10
+ * a second copy of them is a second set of edge cases to keep in
11
+ * agreement.
12
+ *
13
+ * Every function here is total. A caller may hand over a reversed
14
+ * range, a `NaN`, or a start past its end, and the answer is still a
15
+ * pair of numbers inside `[min, max]` with `start <= end`. A range
16
+ * that renders `inline-size: NaN%` paints nothing and the DOM says
17
+ * nothing about it.
18
+ */
19
+ /** Which end of the range a movement is about. */
20
+ export type RangeSliderThumb = "end" | "start";
21
+ export type RangeSliderValue = {
22
+ end: number;
23
+ start: number;
24
+ };
25
+ export type RangeSliderBounds = {
26
+ max: number;
27
+ min: number;
28
+ step: number;
29
+ };
30
+ /**
31
+ * Both ends snapped to the step grid, clamped into the range, and put
32
+ * in order.
33
+ *
34
+ * The ordering is not a nicety. `value` **seeds** rather than
35
+ * controls, exactly as `Slider`'s does, so the pair arrives from an
36
+ * app's state and an app can hold `{ end: 20, start: 80 }` for a
37
+ * frame — a text field committing a typed start before the end
38
+ * catches up is the ordinary way to reach it. A backwards pair paints
39
+ * a fill of negative width, which is invisible rather than wrong-
40
+ * looking, so it is corrected here instead.
41
+ */
42
+ export declare const snapRange: (range: RangeSliderValue, { max, min, step }: RangeSliderBounds) => RangeSliderValue;
43
+ /**
44
+ * The range with one thumb moved to `next`, clamped at the other one.
45
+ *
46
+ * **The thumbs clamp; they do not swap.** A thumb pushed past its
47
+ * partner stops on it, keeps its own identity, and the range collapses
48
+ * to zero width rather than turning inside out. Swapping is the other
49
+ * defensible answer and is the wrong one for the first consumer: the
50
+ * thumbs are a clip's start and its end, a QueuePilot user drags them
51
+ * against a `TimecodeInput` showing which is which, and a drag that
52
+ * silently renamed the handle under the pointer would move a number
53
+ * the user is reading somewhere else. Keyboard makes it plainer still
54
+ * — swapping means one ArrowRight moves the *other* thumb, and the
55
+ * focused element is no longer the value that changed.
56
+ *
57
+ * The snap happens on the **global** grid before the clamp, never on
58
+ * a grid anchored at the other thumb: the partner is already on the
59
+ * grid, so clamping to it lands on the grid too, while snapping
60
+ * against a moving anchor would put the two thumbs on different
61
+ * ladders.
62
+ */
63
+ export declare const moveThumb: ({ bounds, next, range, thumb, }: {
64
+ bounds: RangeSliderBounds;
65
+ next: number;
66
+ range: RangeSliderValue;
67
+ thumb: RangeSliderThumb;
68
+ }) => RangeSliderValue;
69
+ /**
70
+ * The thumb a press at `at` should pick up.
71
+ *
72
+ * The nearer one, and the tie is the interesting half: two thumbs
73
+ * sitting on the same value are the state the clamping rule makes
74
+ * reachable, and a rule that always picked the same one would leave a
75
+ * collapsed range stuck against whichever end it collapsed on. So a
76
+ * tie is broken by **which side of them the press landed on** —
77
+ * below picks the start, on or above picks the end — which is what
78
+ * lets a collapsed pair be pulled open in either direction.
79
+ */
80
+ export declare const getNearerThumb: ({ at, range, }: {
81
+ at: number;
82
+ range: RangeSliderValue;
83
+ }) => RangeSliderThumb;
84
+ /**
85
+ * What one thumb may report as its own `aria-valuemin` /
86
+ * `aria-valuemax`.
87
+ *
88
+ * The other thumb is the bound, which is how the clamping rule
89
+ * reaches assistive technology at all: a screen reader reading
90
+ * "12 of 0 to 30" on the start thumb is being told, in the only
91
+ * vocabulary a slider has, that 30 is where this handle stops. The
92
+ * APG's multi-thumb pattern asks for exactly this.
93
+ */
94
+ export declare const getThumbBounds: ({ bounds, range, thumb, }: {
95
+ bounds: RangeSliderBounds;
96
+ range: RangeSliderValue;
97
+ thumb: RangeSliderThumb;
98
+ }) => {
99
+ max: number;
100
+ min: number;
101
+ };
102
+ //# sourceMappingURL=rangeSliderValue.d.ts.map