@hjmds/react 1.12.0 → 1.13.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 (356) hide show
  1. package/dist/actions.d.ts +4 -0
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +4 -1
  4. package/dist/actions.js.map +1 -1
  5. package/dist/activity-heatmap.d.ts +4 -1
  6. package/dist/activity-heatmap.d.ts.map +1 -1
  7. package/dist/activity-heatmap.js +1 -1
  8. package/dist/activity-heatmap.js.map +1 -1
  9. package/dist/advanced-display.d.ts +31 -3
  10. package/dist/advanced-display.d.ts.map +1 -1
  11. package/dist/advanced-display.js +26 -27
  12. package/dist/advanced-display.js.map +1 -1
  13. package/dist/advanced-forms.d.ts +27 -2
  14. package/dist/advanced-forms.d.ts.map +1 -1
  15. package/dist/advanced-forms.js +11 -7
  16. package/dist/advanced-forms.js.map +1 -1
  17. package/dist/affix.d.ts +4 -1
  18. package/dist/affix.d.ts.map +1 -1
  19. package/dist/affix.js +2 -2
  20. package/dist/affix.js.map +1 -1
  21. package/dist/agreement.d.ts +3 -0
  22. package/dist/agreement.d.ts.map +1 -1
  23. package/dist/agreement.js +14 -3
  24. package/dist/agreement.js.map +1 -1
  25. package/dist/anchor.d.ts +5 -0
  26. package/dist/anchor.d.ts.map +1 -1
  27. package/dist/anchor.js +2 -2
  28. package/dist/anchor.js.map +1 -1
  29. package/dist/asset.d.ts +8 -1
  30. package/dist/asset.d.ts.map +1 -1
  31. package/dist/asset.js +4 -4
  32. package/dist/asset.js.map +1 -1
  33. package/dist/auth-screen.d.ts +5 -0
  34. package/dist/auth-screen.d.ts.map +1 -1
  35. package/dist/auth-screen.js +2 -1
  36. package/dist/auth-screen.js.map +1 -1
  37. package/dist/bottom-cta.d.ts +5 -0
  38. package/dist/bottom-cta.d.ts.map +1 -1
  39. package/dist/bottom-cta.js +2 -2
  40. package/dist/bottom-cta.js.map +1 -1
  41. package/dist/bottom-info.d.ts +5 -0
  42. package/dist/bottom-info.d.ts.map +1 -1
  43. package/dist/bottom-info.js +2 -2
  44. package/dist/bottom-info.js.map +1 -1
  45. package/dist/bottom-navigation.d.ts +3 -0
  46. package/dist/bottom-navigation.d.ts.map +1 -1
  47. package/dist/bottom-navigation.js +2 -1
  48. package/dist/bottom-navigation.js.map +1 -1
  49. package/dist/breadcrumb.d.ts +3 -0
  50. package/dist/breadcrumb.d.ts.map +1 -1
  51. package/dist/breadcrumb.js +2 -2
  52. package/dist/breadcrumb.js.map +1 -1
  53. package/dist/calendar.d.ts +4 -1
  54. package/dist/calendar.d.ts.map +1 -1
  55. package/dist/calendar.js +2 -2
  56. package/dist/calendar.js.map +1 -1
  57. package/dist/carousel-motion.d.ts +3 -0
  58. package/dist/carousel-motion.d.ts.map +1 -1
  59. package/dist/carousel-motion.js +1 -1
  60. package/dist/carousel-motion.js.map +1 -1
  61. package/dist/carousel.d.ts +3 -0
  62. package/dist/carousel.d.ts.map +1 -1
  63. package/dist/carousel.js +2 -2
  64. package/dist/carousel.js.map +1 -1
  65. package/dist/celebration.d.ts.map +1 -1
  66. package/dist/celebration.js.map +1 -1
  67. package/dist/clipboard.d.ts.map +1 -1
  68. package/dist/clipboard.js +6 -2
  69. package/dist/clipboard.js.map +1 -1
  70. package/dist/code-block.d.ts +4 -1
  71. package/dist/code-block.d.ts.map +1 -1
  72. package/dist/code-block.js +1 -1
  73. package/dist/code-block.js.map +1 -1
  74. package/dist/collapsible.d.ts +3 -0
  75. package/dist/collapsible.d.ts.map +1 -1
  76. package/dist/collapsible.js +2 -2
  77. package/dist/collapsible.js.map +1 -1
  78. package/dist/color-picker.d.ts +4 -1
  79. package/dist/color-picker.d.ts.map +1 -1
  80. package/dist/color-picker.js +2 -2
  81. package/dist/color-picker.js.map +1 -1
  82. package/dist/command-palette.d.ts +6 -0
  83. package/dist/command-palette.d.ts.map +1 -1
  84. package/dist/command-palette.js +49 -15
  85. package/dist/command-palette.js.map +1 -1
  86. package/dist/composition-style.d.ts +14 -1
  87. package/dist/composition-style.d.ts.map +1 -1
  88. package/dist/composition-style.js.map +1 -1
  89. package/dist/content-transition.d.ts +6 -2
  90. package/dist/content-transition.d.ts.map +1 -1
  91. package/dist/content-transition.js +4 -4
  92. package/dist/content-transition.js.map +1 -1
  93. package/dist/context-menu.d.ts +4 -1
  94. package/dist/context-menu.d.ts.map +1 -1
  95. package/dist/context-menu.js +2 -2
  96. package/dist/context-menu.js.map +1 -1
  97. package/dist/data-table.d.ts +3 -0
  98. package/dist/data-table.d.ts.map +1 -1
  99. package/dist/data-table.js +31 -11
  100. package/dist/data-table.js.map +1 -1
  101. package/dist/date-picker.d.ts +4 -1
  102. package/dist/date-picker.d.ts.map +1 -1
  103. package/dist/date-picker.js +2 -2
  104. package/dist/date-picker.js.map +1 -1
  105. package/dist/date-range.d.ts +4 -1
  106. package/dist/date-range.d.ts.map +1 -1
  107. package/dist/date-range.js +2 -2
  108. package/dist/date-range.js.map +1 -1
  109. package/dist/display.d.ts +4 -0
  110. package/dist/display.d.ts.map +1 -1
  111. package/dist/display.js.map +1 -1
  112. package/dist/duration-field.d.ts +4 -2
  113. package/dist/duration-field.d.ts.map +1 -1
  114. package/dist/duration-field.js +2 -2
  115. package/dist/duration-field.js.map +1 -1
  116. package/dist/effect-surface.d.ts +4 -2
  117. package/dist/effect-surface.d.ts.map +1 -1
  118. package/dist/effect-surface.js +2 -2
  119. package/dist/effect-surface.js.map +1 -1
  120. package/dist/evidence.d.ts +1 -1
  121. package/dist/evidence.js +1 -1
  122. package/dist/evidence.js.map +1 -1
  123. package/dist/feedback.d.ts +24 -13
  124. package/dist/feedback.d.ts.map +1 -1
  125. package/dist/feedback.js +17 -15
  126. package/dist/feedback.js.map +1 -1
  127. package/dist/file-picker.d.ts +5 -0
  128. package/dist/file-picker.d.ts.map +1 -1
  129. package/dist/file-picker.js +2 -2
  130. package/dist/file-picker.js.map +1 -1
  131. package/dist/floating-action-button.d.ts.map +1 -1
  132. package/dist/floating-action-button.js.map +1 -1
  133. package/dist/folder-preview.d.ts +4 -1
  134. package/dist/folder-preview.d.ts.map +1 -1
  135. package/dist/folder-preview.js +2 -2
  136. package/dist/folder-preview.js.map +1 -1
  137. package/dist/forms.d.ts +35 -3
  138. package/dist/forms.d.ts.map +1 -1
  139. package/dist/forms.js +55 -36
  140. package/dist/forms.js.map +1 -1
  141. package/dist/gravity-letters.d.ts +4 -2
  142. package/dist/gravity-letters.d.ts.map +1 -1
  143. package/dist/gravity-letters.js +2 -2
  144. package/dist/gravity-letters.js.map +1 -1
  145. package/dist/grid-reveal.d.ts +4 -2
  146. package/dist/grid-reveal.d.ts.map +1 -1
  147. package/dist/grid-reveal.js +2 -2
  148. package/dist/grid-reveal.js.map +1 -1
  149. package/dist/heading.d.ts +5 -0
  150. package/dist/heading.d.ts.map +1 -1
  151. package/dist/heading.js +8 -1
  152. package/dist/heading.js.map +1 -1
  153. package/dist/inline-confirm.d.ts +3 -0
  154. package/dist/inline-confirm.d.ts.map +1 -1
  155. package/dist/inline-confirm.js +3 -3
  156. package/dist/inline-confirm.js.map +1 -1
  157. package/dist/internal/message-reactions.d.ts +16 -0
  158. package/dist/internal/message-reactions.d.ts.map +1 -0
  159. package/dist/internal/message-reactions.js +42 -0
  160. package/dist/internal/message-reactions.js.map +1 -0
  161. package/dist/internal/spinner.d.ts +18 -0
  162. package/dist/internal/spinner.d.ts.map +1 -0
  163. package/dist/internal/spinner.js +10 -0
  164. package/dist/internal/spinner.js.map +1 -0
  165. package/dist/layout.d.ts +12 -0
  166. package/dist/layout.d.ts.map +1 -1
  167. package/dist/layout.js +6 -6
  168. package/dist/layout.js.map +1 -1
  169. package/dist/masonry.d.ts +4 -1
  170. package/dist/masonry.d.ts.map +1 -1
  171. package/dist/masonry.js +5 -3
  172. package/dist/masonry.js.map +1 -1
  173. package/dist/mentions.d.ts.map +1 -1
  174. package/dist/mentions.js +12 -3
  175. package/dist/mentions.js.map +1 -1
  176. package/dist/menu-morph.d.ts +8 -1
  177. package/dist/menu-morph.d.ts.map +1 -1
  178. package/dist/menu-morph.js +3 -3
  179. package/dist/menu-morph.js.map +1 -1
  180. package/dist/menubar.d.ts +4 -1
  181. package/dist/menubar.d.ts.map +1 -1
  182. package/dist/menubar.js +4 -3
  183. package/dist/menubar.js.map +1 -1
  184. package/dist/modal.d.ts.map +1 -1
  185. package/dist/modal.js +4 -1
  186. package/dist/modal.js.map +1 -1
  187. package/dist/navigation-bar.d.ts +4 -1
  188. package/dist/navigation-bar.d.ts.map +1 -1
  189. package/dist/navigation-bar.js +2 -2
  190. package/dist/navigation-bar.js.map +1 -1
  191. package/dist/navigation.d.ts +5 -0
  192. package/dist/navigation.d.ts.map +1 -1
  193. package/dist/navigation.js +6 -6
  194. package/dist/navigation.js.map +1 -1
  195. package/dist/notification-bell.d.ts +4 -1
  196. package/dist/notification-bell.d.ts.map +1 -1
  197. package/dist/notification-bell.js +5 -3
  198. package/dist/notification-bell.js.map +1 -1
  199. package/dist/number-field.d.ts +11 -0
  200. package/dist/number-field.d.ts.map +1 -1
  201. package/dist/number-field.js +8 -3
  202. package/dist/number-field.js.map +1 -1
  203. package/dist/overlay-stack.d.ts.map +1 -1
  204. package/dist/overlay-stack.js.map +1 -1
  205. package/dist/overlays.d.ts +5 -0
  206. package/dist/overlays.d.ts.map +1 -1
  207. package/dist/overlays.js +35 -11
  208. package/dist/overlays.js.map +1 -1
  209. package/dist/pagination.d.ts +5 -0
  210. package/dist/pagination.d.ts.map +1 -1
  211. package/dist/pagination.js +2 -2
  212. package/dist/pagination.js.map +1 -1
  213. package/dist/popover.d.ts.map +1 -1
  214. package/dist/popover.js +5 -4
  215. package/dist/popover.js.map +1 -1
  216. package/dist/portal.d.ts.map +1 -1
  217. package/dist/portal.js +2 -1
  218. package/dist/portal.js.map +1 -1
  219. package/dist/provider-button.d.ts +5 -0
  220. package/dist/provider-button.d.ts.map +1 -1
  221. package/dist/provider-button.js +2 -2
  222. package/dist/provider-button.js.map +1 -1
  223. package/dist/provider.d.ts.map +1 -1
  224. package/dist/provider.js.map +1 -1
  225. package/dist/qr-code.d.ts +4 -1
  226. package/dist/qr-code.d.ts.map +1 -1
  227. package/dist/qr-code.js +2 -2
  228. package/dist/qr-code.js.map +1 -1
  229. package/dist/reaction-picker.d.ts +6 -2
  230. package/dist/reaction-picker.d.ts.map +1 -1
  231. package/dist/reaction-picker.js +20 -4
  232. package/dist/reaction-picker.js.map +1 -1
  233. package/dist/saved-items.d.ts +33 -0
  234. package/dist/saved-items.d.ts.map +1 -0
  235. package/dist/saved-items.js +19 -0
  236. package/dist/saved-items.js.map +1 -0
  237. package/dist/screen-flows.d.ts +323 -0
  238. package/dist/screen-flows.d.ts.map +1 -0
  239. package/dist/screen-flows.js +212 -0
  240. package/dist/screen-flows.js.map +1 -0
  241. package/dist/screens.d.ts +120 -0
  242. package/dist/screens.d.ts.map +1 -0
  243. package/dist/screens.js +66 -0
  244. package/dist/screens.js.map +1 -0
  245. package/dist/select.d.ts +6 -0
  246. package/dist/select.d.ts.map +1 -1
  247. package/dist/select.js +13 -3
  248. package/dist/select.js.map +1 -1
  249. package/dist/selection.d.ts +28 -1
  250. package/dist/selection.d.ts.map +1 -1
  251. package/dist/selection.js +12 -12
  252. package/dist/selection.js.map +1 -1
  253. package/dist/side-panel.d.ts.map +1 -1
  254. package/dist/side-panel.js.map +1 -1
  255. package/dist/sidebar.d.ts +3 -0
  256. package/dist/sidebar.d.ts.map +1 -1
  257. package/dist/sidebar.js +2 -2
  258. package/dist/sidebar.js.map +1 -1
  259. package/dist/skip-nav.d.ts.map +1 -1
  260. package/dist/skip-nav.js.map +1 -1
  261. package/dist/slider.d.ts +5 -0
  262. package/dist/slider.d.ts.map +1 -1
  263. package/dist/slider.js +2 -1
  264. package/dist/slider.js.map +1 -1
  265. package/dist/sortable.d.ts +3 -0
  266. package/dist/sortable.d.ts.map +1 -1
  267. package/dist/sortable.js +1 -1
  268. package/dist/sortable.js.map +1 -1
  269. package/dist/splitter.d.ts +5 -0
  270. package/dist/splitter.d.ts.map +1 -1
  271. package/dist/splitter.js +28 -3
  272. package/dist/splitter.js.map +1 -1
  273. package/dist/step-player.d.ts +4 -1
  274. package/dist/step-player.d.ts.map +1 -1
  275. package/dist/step-player.js +2 -2
  276. package/dist/step-player.js.map +1 -1
  277. package/dist/steps.d.ts +5 -0
  278. package/dist/steps.d.ts.map +1 -1
  279. package/dist/steps.js +2 -2
  280. package/dist/steps.js.map +1 -1
  281. package/dist/styles.css +245 -65
  282. package/dist/styles.layered.css +245 -65
  283. package/dist/supplemental-display.d.ts +4 -0
  284. package/dist/supplemental-display.d.ts.map +1 -1
  285. package/dist/supplemental-display.js +7 -4
  286. package/dist/supplemental-display.js.map +1 -1
  287. package/dist/supplemental-navigation.d.ts +5 -0
  288. package/dist/supplemental-navigation.d.ts.map +1 -1
  289. package/dist/supplemental-navigation.js +2 -2
  290. package/dist/supplemental-navigation.js.map +1 -1
  291. package/dist/swipe-actions.d.ts +4 -1
  292. package/dist/swipe-actions.d.ts.map +1 -1
  293. package/dist/swipe-actions.js +2 -2
  294. package/dist/swipe-actions.js.map +1 -1
  295. package/dist/tags-input.d.ts +5 -0
  296. package/dist/tags-input.d.ts.map +1 -1
  297. package/dist/tags-input.js +2 -2
  298. package/dist/tags-input.js.map +1 -1
  299. package/dist/task-list.d.ts +4 -1
  300. package/dist/task-list.d.ts.map +1 -1
  301. package/dist/task-list.js +3 -3
  302. package/dist/task-list.js.map +1 -1
  303. package/dist/text-formats.d.ts +5 -0
  304. package/dist/text-formats.d.ts.map +1 -1
  305. package/dist/text-formats.js +2 -1
  306. package/dist/text-formats.js.map +1 -1
  307. package/dist/theme.d.ts.map +1 -1
  308. package/dist/theme.js +22 -2
  309. package/dist/theme.js.map +1 -1
  310. package/dist/thinking-orb.d.ts +4 -1
  311. package/dist/thinking-orb.d.ts.map +1 -1
  312. package/dist/thinking-orb.js +2 -2
  313. package/dist/thinking-orb.js.map +1 -1
  314. package/dist/toast.d.ts.map +1 -1
  315. package/dist/toast.js +10 -4
  316. package/dist/toast.js.map +1 -1
  317. package/dist/toggle-group.d.ts +3 -0
  318. package/dist/toggle-group.d.ts.map +1 -1
  319. package/dist/toggle-group.js +2 -1
  320. package/dist/toggle-group.js.map +1 -1
  321. package/dist/top-bar.d.ts +5 -0
  322. package/dist/top-bar.d.ts.map +1 -1
  323. package/dist/top-bar.js +2 -2
  324. package/dist/top-bar.js.map +1 -1
  325. package/dist/top.d.ts +5 -0
  326. package/dist/top.d.ts.map +1 -1
  327. package/dist/top.js +2 -2
  328. package/dist/top.js.map +1 -1
  329. package/dist/tour.d.ts.map +1 -1
  330. package/dist/tour.js +3 -2
  331. package/dist/tour.js.map +1 -1
  332. package/dist/transfer-list.d.ts +3 -0
  333. package/dist/transfer-list.d.ts.map +1 -1
  334. package/dist/transfer-list.js +2 -2
  335. package/dist/transfer-list.js.map +1 -1
  336. package/dist/tree.d.ts +3 -0
  337. package/dist/tree.d.ts.map +1 -1
  338. package/dist/tree.js +17 -5
  339. package/dist/tree.js.map +1 -1
  340. package/dist/upload-item.d.ts +5 -0
  341. package/dist/upload-item.d.ts.map +1 -1
  342. package/dist/upload-item.js +2 -2
  343. package/dist/upload-item.js.map +1 -1
  344. package/dist/virtual-list.d.ts +4 -1
  345. package/dist/virtual-list.d.ts.map +1 -1
  346. package/dist/virtual-list.js +2 -2
  347. package/dist/virtual-list.js.map +1 -1
  348. package/dist/voice-note.d.ts +4 -1
  349. package/dist/voice-note.d.ts.map +1 -1
  350. package/dist/voice-note.js +2 -2
  351. package/dist/voice-note.js.map +1 -1
  352. package/dist/watermark.d.ts +4 -1
  353. package/dist/watermark.d.ts.map +1 -1
  354. package/dist/watermark.js +2 -2
  355. package/dist/watermark.js.map +1 -1
  356. package/package.json +18 -3
package/dist/slider.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type CSSProperties, type InputHTMLAttributes } from "react";
2
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
2
3
  type NativeSliderInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "aria-label" | "aria-orientation" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "className" | "defaultValue" | "max" | "min" | "onChange" | "readOnly" | "size" | "step" | "type" | "value">;
3
4
  export type SliderProps = NativeSliderInputProps & Readonly<{
4
5
  label: string;
@@ -14,6 +15,8 @@ export type SliderProps = NativeSliderInputProps & Readonly<{
14
15
  className?: string;
15
16
  inputClassName?: string;
16
17
  style?: CSSProperties;
18
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
19
+ layoutStyle?: HjmCompositionStyleProp;
17
20
  }>;
18
21
  /** Native range semantics with HJM visuals and explicit change-end behavior. */
19
22
  export declare const Slider: import("react").ForwardRefExoticComponent<NativeSliderInputProps & Readonly<{
@@ -30,6 +33,8 @@ export declare const Slider: import("react").ForwardRefExoticComponent<NativeSli
30
33
  className?: string;
31
34
  inputClassName?: string;
32
35
  style?: CSSProperties;
36
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
37
+ layoutStyle?: HjmCompositionStyleProp;
33
38
  }> & import("react").RefAttributes<HTMLInputElement>>;
34
39
  export {};
35
40
  //# sourceMappingURL=slider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slider.d.ts","sourceRoot":"","sources":["../src/slider.tsx"],"names":[],"mappings":"AAOA,OAAO,EAML,KAAK,aAAa,EAElB,KAAK,mBAAmB,EAGzB,MAAM,OAAO,CAAC;AAIf,KAAK,sBAAsB,GAAG,IAAI,CAChC,mBAAmB,CAAC,gBAAgB,CAAC,EACnC,YAAY,GACZ,kBAAkB,GAClB,eAAe,GACf,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,UAAU,GACV,WAAW,GACX,cAAc,GACd,KAAK,GACL,KAAK,GACL,UAAU,GACV,UAAU,GACV,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,CACV,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,sBAAsB,GAC9C,QAAQ,CAAC;IACP,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,6DAA6D;IAC7D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,CAAC,CAAC;AA2BL,gFAAgF;AAChF,eAAO,MAAM,MAAM;WAzCR,MAAM;SACR,MAAM;SACN,MAAM;WACJ,MAAM;YACL,MAAM;mBACC,MAAM;oBACL,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;uBACpB,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IAC1C,6DAA6D;mBAC9C,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;gBAC5B,MAAM;qBACD,MAAM;YACf,aAAa;qDA8NvB,CAAC"}
1
+ {"version":3,"file":"slider.d.ts","sourceRoot":"","sources":["../src/slider.tsx"],"names":[],"mappings":"AAOA,OAAO,EAML,KAAK,aAAa,EAElB,KAAK,mBAAmB,EAGzB,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,KAAK,sBAAsB,GAAG,IAAI,CAChC,mBAAmB,CAAC,gBAAgB,CAAC,EACnC,YAAY,GACZ,kBAAkB,GAClB,eAAe,GACf,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,UAAU,GACV,WAAW,GACX,cAAc,GACd,KAAK,GACL,KAAK,GACL,UAAU,GACV,UAAU,GACV,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,CACV,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,sBAAsB,GAC9C,QAAQ,CAAC;IACP,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,6DAA6D;IAC7D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AA2BL,gFAAgF;AAChF,eAAO,MAAM,MAAM;WA3CR,MAAM;SACR,MAAM;SACN,MAAM;WACJ,MAAM;YACL,MAAM;mBACC,MAAM;oBACL,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;uBACpB,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IAC1C,6DAA6D;mBAC9C,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;gBAC5B,MAAM;qBACD,MAAM;YACf,aAAa;IACrB,gGAAgG;kBAClF,uBAAuB;qDAgOvC,CAAC"}
package/dist/slider.js CHANGED
@@ -28,7 +28,7 @@ function intentForKey(key) {
28
28
  return undefined;
29
29
  }
30
30
  /** Native range semantics with HJM visuals and explicit change-end behavior. */
31
- export const Slider = forwardRef(function Slider({ id, label, min, max, step, value, defaultValue, onValueChange, onValueChangeEnd, getValueText, disabled = false, className, inputClassName, style, onBlur, onFocus, onKeyDown, onKeyUp, onLostPointerCapture, onPointerCancel, onPointerDown, onPointerUp, ...inputProps }, forwardedRef) {
31
+ export const Slider = forwardRef(function Slider({ id, label, min, max, step, value, defaultValue, onValueChange, onValueChangeEnd, getValueText, disabled = false, className, inputClassName, style, onBlur, onFocus, onKeyDown, onKeyUp, onLostPointerCapture, onPointerCancel, onPointerDown, onPointerUp, layoutStyle, ...inputProps }, forwardedRef) {
32
32
  const generatedId = useId();
33
33
  const controlId = id ?? `hjm-slider-${generatedId.replaceAll(":", "")}`;
34
34
  const labelId = `${controlId}-label`;
@@ -134,6 +134,7 @@ export const Slider = forwardRef(function Slider({ id, label, min, max, step, va
134
134
  const fill = resolveSliderFillFraction(descriptor);
135
135
  const rootStyle = {
136
136
  ...style,
137
+ ...layoutStyle,
137
138
  "--hjm-slider-fill": `${fill * 100}%`,
138
139
  };
139
140
  const visibleValue = valueText ?? String(currentValue);
@@ -1 +1 @@
1
- {"version":3,"file":"slider.js","sourceRoot":"","sources":["../src/slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getSliderStepTarget,\n resolveSliderDescriptor,\n resolveSliderFillFraction,\n resolveSliderValue,\n type SliderStepIntent,\n} from \"@hjmds/design-contracts/components/slider\";\nimport {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type PointerEvent,\n} from \"react\";\n\nimport { classNames, useControllableState } from \"./internal.js\";\n\ntype NativeSliderInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n | \"aria-label\"\n | \"aria-orientation\"\n | \"aria-valuemax\"\n | \"aria-valuemin\"\n | \"aria-valuenow\"\n | \"aria-valuetext\"\n | \"children\"\n | \"className\"\n | \"defaultValue\"\n | \"max\"\n | \"min\"\n | \"onChange\"\n | \"readOnly\"\n | \"size\"\n | \"step\"\n | \"type\"\n | \"value\"\n>;\n\nexport type SliderProps = NativeSliderInputProps &\n Readonly<{\n label: string;\n min: number;\n max: number;\n step?: number;\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n onValueChangeEnd?: (value: number) => void;\n /** Product-owned visible and accessible value formatting. */\n getValueText?: (value: number) => string;\n className?: string;\n inputClassName?: string;\n style?: CSSProperties;\n }>;\n\ntype SliderInteraction = \"keyboard\" | \"pointer\";\n\nconst sliderKeys = new Set([\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n]);\n\nfunction intentForKey(key: string): SliderStepIntent | undefined {\n if (key === \"ArrowRight\" || key === \"ArrowUp\") return \"increment\";\n if (key === \"ArrowLeft\" || key === \"ArrowDown\") return \"decrement\";\n if (key === \"Home\") return \"first\";\n if (key === \"End\") return \"last\";\n if (key === \"PageUp\") return \"increment-page\";\n if (key === \"PageDown\") return \"decrement-page\";\n return undefined;\n}\n\ntype SliderRootStyle = CSSProperties & Readonly<{ \"--hjm-slider-fill\": string }>;\n\n/** Native range semantics with HJM visuals and explicit change-end behavior. */\nexport const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(\n {\n id,\n label,\n min,\n max,\n step,\n value,\n defaultValue,\n onValueChange,\n onValueChangeEnd,\n getValueText,\n disabled = false,\n className,\n inputClassName,\n style,\n onBlur,\n onFocus,\n onKeyDown,\n onKeyUp,\n onLostPointerCapture,\n onPointerCancel,\n onPointerDown,\n onPointerUp,\n ...inputProps\n },\n forwardedRef,\n) {\n const generatedId = useId();\n const controlId = id ?? `hjm-slider-${generatedId.replaceAll(\":\", \"\")}`;\n const labelId = `${controlId}-label`;\n const valueId = `${controlId}-value`;\n const controlled = value !== undefined;\n const controlledAtMount = useRef(controlled);\n if (controlledAtMount.current !== controlled) {\n throw new Error(\"HJM components cannot switch between controlled and uncontrolled state\");\n }\n const [currentValue, setCurrentValue] = useControllableState<number>({\n ...(value === undefined ? {} : { value }),\n defaultValue: defaultValue ?? min,\n ...(onValueChange === undefined ? {} : { onChange: onValueChange }),\n });\n const valueText = getValueText?.(currentValue);\n const descriptor = resolveSliderDescriptor({\n label,\n value: currentValue,\n min,\n max,\n ...(step === undefined ? {} : { step }),\n ...(valueText === undefined ? {} : { valueText }),\n });\n const interactionRef = useRef<SliderInteraction | null>(null);\n const lastInteractionValueRef = useRef(currentValue);\n const [interaction, setInteraction] = useState<SliderInteraction | null>(null);\n const [focused, setFocused] = useState(false);\n\n useEffect(() => {\n if (interactionRef.current === null) lastInteractionValueRef.current = currentValue;\n }, [currentValue]);\n\n const beginInteraction = (kind: SliderInteraction) => {\n interactionRef.current = kind;\n lastInteractionValueRef.current = currentValue;\n setInteraction(kind);\n };\n const publish = (next: number) => {\n const previous = interactionRef.current === null\n ? currentValue\n : lastInteractionValueRef.current;\n lastInteractionValueRef.current = next;\n if (!Object.is(next, previous)) setCurrentValue(next);\n };\n const finishInteraction = () => {\n if (interactionRef.current === null) return;\n const finalValue = lastInteractionValueRef.current;\n interactionRef.current = null;\n setInteraction(null);\n onValueChangeEnd?.(finalValue);\n };\n\n useEffect(() => {\n if (disabled) finishInteraction();\n }, [disabled]);\n\n const handleFocus = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(true);\n onFocus?.(event);\n };\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(false);\n finishInteraction();\n onBlur?.(event);\n };\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || disabled) return;\n const intent = intentForKey(event.key);\n if (intent === undefined) return;\n event.preventDefault();\n if (interactionRef.current !== \"keyboard\") beginInteraction(\"keyboard\");\n publish(getSliderStepTarget(descriptor, intent));\n };\n const handleKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {\n onKeyUp?.(event);\n if (!sliderKeys.has(event.key)) return;\n finishInteraction();\n };\n const handlePointerDown = (event: PointerEvent<HTMLInputElement>) => {\n onPointerDown?.(event);\n if (event.defaultPrevented || disabled) return;\n beginInteraction(\"pointer\");\n event.currentTarget.setPointerCapture?.(event.pointerId);\n };\n const handlePointerUp = (event: PointerEvent<HTMLInputElement>) => {\n onPointerUp?.(event);\n finishInteraction();\n };\n const handlePointerCancel = (event: PointerEvent<HTMLInputElement>) => {\n onPointerCancel?.(event);\n finishInteraction();\n };\n const handleLostPointerCapture = (event: PointerEvent<HTMLInputElement>) => {\n onLostPointerCapture?.(event);\n finishInteraction();\n };\n\n const fill = resolveSliderFillFraction(descriptor);\n const rootStyle: SliderRootStyle = {\n ...style,\n \"--hjm-slider-fill\": `${fill * 100}%`,\n };\n const visibleValue = valueText ?? String(currentValue);\n\n return (\n <div\n className={classNames(\"hjm-slider\", className)}\n data-disabled={disabled ? \"true\" : \"false\"}\n data-focused={focused ? \"true\" : \"false\"}\n data-interaction={interaction ?? \"idle\"}\n style={rootStyle}\n >\n <div className=\"hjm-slider__header\">\n <label className=\"hjm-slider__label\" id={labelId} htmlFor={controlId}>{label}</label>\n <output className=\"hjm-slider__value\" id={valueId} htmlFor={controlId}>\n {visibleValue}\n </output>\n </div>\n <div className=\"hjm-slider__control\">\n <div className=\"hjm-slider__interactive\">\n <div aria-hidden=\"true\" className=\"hjm-slider__track\">\n <div className=\"hjm-slider__filled-track\" />\n </div>\n <div aria-hidden=\"true\" className=\"hjm-slider__thumb\" />\n <input\n {...inputProps}\n ref={forwardedRef}\n id={controlId}\n type=\"range\"\n className={classNames(\"hjm-slider__input\", inputClassName)}\n min={min}\n max={max}\n step=\"any\"\n value={currentValue}\n disabled={disabled}\n aria-labelledby={labelId}\n aria-orientation=\"horizontal\"\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={currentValue}\n {...(valueText === undefined ? {} : { \"aria-valuetext\": valueText })}\n onChange={(event) => {\n if (disabled) return;\n const next = resolveSliderValue(\n descriptor,\n event.currentTarget.valueAsNumber,\n );\n const atomic = interactionRef.current === null;\n publish(next);\n if (atomic) onValueChangeEnd?.(next);\n }}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerCancel}\n onLostPointerCapture={handleLostPointerCapture}\n />\n </div>\n </div>\n </div>\n );\n});\n"]}
1
+ {"version":3,"file":"slider.js","sourceRoot":"","sources":["../src/slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getSliderStepTarget,\n resolveSliderDescriptor,\n resolveSliderFillFraction,\n resolveSliderValue,\n type SliderStepIntent,\n} from \"@hjmds/design-contracts/components/slider\";\nimport {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type PointerEvent,\n} from \"react\";\n\nimport { classNames, useControllableState } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\ntype NativeSliderInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n | \"aria-label\"\n | \"aria-orientation\"\n | \"aria-valuemax\"\n | \"aria-valuemin\"\n | \"aria-valuenow\"\n | \"aria-valuetext\"\n | \"children\"\n | \"className\"\n | \"defaultValue\"\n | \"max\"\n | \"min\"\n | \"onChange\"\n | \"readOnly\"\n | \"size\"\n | \"step\"\n | \"type\"\n | \"value\"\n>;\n\nexport type SliderProps = NativeSliderInputProps &\n Readonly<{\n label: string;\n min: number;\n max: number;\n step?: number;\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n onValueChangeEnd?: (value: number) => void;\n /** Product-owned visible and accessible value formatting. */\n getValueText?: (value: number) => string;\n className?: string;\n inputClassName?: string;\n style?: CSSProperties;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\ntype SliderInteraction = \"keyboard\" | \"pointer\";\n\nconst sliderKeys = new Set([\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n]);\n\nfunction intentForKey(key: string): SliderStepIntent | undefined {\n if (key === \"ArrowRight\" || key === \"ArrowUp\") return \"increment\";\n if (key === \"ArrowLeft\" || key === \"ArrowDown\") return \"decrement\";\n if (key === \"Home\") return \"first\";\n if (key === \"End\") return \"last\";\n if (key === \"PageUp\") return \"increment-page\";\n if (key === \"PageDown\") return \"decrement-page\";\n return undefined;\n}\n\ntype SliderRootStyle = CSSProperties & Readonly<{ \"--hjm-slider-fill\": string }>;\n\n/** Native range semantics with HJM visuals and explicit change-end behavior. */\nexport const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(\n {\n id,\n label,\n min,\n max,\n step,\n value,\n defaultValue,\n onValueChange,\n onValueChangeEnd,\n getValueText,\n disabled = false,\n className,\n inputClassName,\n style,\n onBlur,\n onFocus,\n onKeyDown,\n onKeyUp,\n onLostPointerCapture,\n onPointerCancel,\n onPointerDown,\n onPointerUp,\n layoutStyle,\n ...inputProps\n },\n forwardedRef,\n) {\n const generatedId = useId();\n const controlId = id ?? `hjm-slider-${generatedId.replaceAll(\":\", \"\")}`;\n const labelId = `${controlId}-label`;\n const valueId = `${controlId}-value`;\n const controlled = value !== undefined;\n const controlledAtMount = useRef(controlled);\n if (controlledAtMount.current !== controlled) {\n throw new Error(\"HJM components cannot switch between controlled and uncontrolled state\");\n }\n const [currentValue, setCurrentValue] = useControllableState<number>({\n ...(value === undefined ? {} : { value }),\n defaultValue: defaultValue ?? min,\n ...(onValueChange === undefined ? {} : { onChange: onValueChange }),\n });\n const valueText = getValueText?.(currentValue);\n const descriptor = resolveSliderDescriptor({\n label,\n value: currentValue,\n min,\n max,\n ...(step === undefined ? {} : { step }),\n ...(valueText === undefined ? {} : { valueText }),\n });\n const interactionRef = useRef<SliderInteraction | null>(null);\n const lastInteractionValueRef = useRef(currentValue);\n const [interaction, setInteraction] = useState<SliderInteraction | null>(null);\n const [focused, setFocused] = useState(false);\n\n useEffect(() => {\n if (interactionRef.current === null) lastInteractionValueRef.current = currentValue;\n }, [currentValue]);\n\n const beginInteraction = (kind: SliderInteraction) => {\n interactionRef.current = kind;\n lastInteractionValueRef.current = currentValue;\n setInteraction(kind);\n };\n const publish = (next: number) => {\n const previous = interactionRef.current === null\n ? currentValue\n : lastInteractionValueRef.current;\n lastInteractionValueRef.current = next;\n if (!Object.is(next, previous)) setCurrentValue(next);\n };\n const finishInteraction = () => {\n if (interactionRef.current === null) return;\n const finalValue = lastInteractionValueRef.current;\n interactionRef.current = null;\n setInteraction(null);\n onValueChangeEnd?.(finalValue);\n };\n\n useEffect(() => {\n if (disabled) finishInteraction();\n }, [disabled]);\n\n const handleFocus = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(true);\n onFocus?.(event);\n };\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n setFocused(false);\n finishInteraction();\n onBlur?.(event);\n };\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || disabled) return;\n const intent = intentForKey(event.key);\n if (intent === undefined) return;\n event.preventDefault();\n if (interactionRef.current !== \"keyboard\") beginInteraction(\"keyboard\");\n publish(getSliderStepTarget(descriptor, intent));\n };\n const handleKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {\n onKeyUp?.(event);\n if (!sliderKeys.has(event.key)) return;\n finishInteraction();\n };\n const handlePointerDown = (event: PointerEvent<HTMLInputElement>) => {\n onPointerDown?.(event);\n if (event.defaultPrevented || disabled) return;\n beginInteraction(\"pointer\");\n event.currentTarget.setPointerCapture?.(event.pointerId);\n };\n const handlePointerUp = (event: PointerEvent<HTMLInputElement>) => {\n onPointerUp?.(event);\n finishInteraction();\n };\n const handlePointerCancel = (event: PointerEvent<HTMLInputElement>) => {\n onPointerCancel?.(event);\n finishInteraction();\n };\n const handleLostPointerCapture = (event: PointerEvent<HTMLInputElement>) => {\n onLostPointerCapture?.(event);\n finishInteraction();\n };\n\n const fill = resolveSliderFillFraction(descriptor);\n const rootStyle: SliderRootStyle = {\n ...style,\n ...layoutStyle,\n \"--hjm-slider-fill\": `${fill * 100}%`,\n };\n const visibleValue = valueText ?? String(currentValue);\n\n return (\n <div\n className={classNames(\"hjm-slider\", className)}\n data-disabled={disabled ? \"true\" : \"false\"}\n data-focused={focused ? \"true\" : \"false\"}\n data-interaction={interaction ?? \"idle\"}\n style={rootStyle}\n >\n <div className=\"hjm-slider__header\">\n <label className=\"hjm-slider__label\" id={labelId} htmlFor={controlId}>{label}</label>\n <output className=\"hjm-slider__value\" id={valueId} htmlFor={controlId}>\n {visibleValue}\n </output>\n </div>\n <div className=\"hjm-slider__control\">\n <div className=\"hjm-slider__interactive\">\n <div aria-hidden=\"true\" className=\"hjm-slider__track\">\n <div className=\"hjm-slider__filled-track\" />\n </div>\n <div aria-hidden=\"true\" className=\"hjm-slider__thumb\" />\n <input\n {...inputProps}\n ref={forwardedRef}\n id={controlId}\n type=\"range\"\n className={classNames(\"hjm-slider__input\", inputClassName)}\n min={min}\n max={max}\n step=\"any\"\n value={currentValue}\n disabled={disabled}\n aria-labelledby={labelId}\n aria-orientation=\"horizontal\"\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={currentValue}\n {...(valueText === undefined ? {} : { \"aria-valuetext\": valueText })}\n onChange={(event) => {\n if (disabled) return;\n const next = resolveSliderValue(\n descriptor,\n event.currentTarget.valueAsNumber,\n );\n const atomic = interactionRef.current === null;\n publish(next);\n if (atomic) onValueChangeEnd?.(next);\n }}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerCancel}\n onLostPointerCapture={handleLostPointerCapture}\n />\n </div>\n </div>\n </div>\n );\n});\n"]}
@@ -1,5 +1,6 @@
1
1
  import { type ReactNode } from "react";
2
2
  import { type SortableItem, type SortableLabels, type ReorderIntent } from "@hjmds/design-contracts/components/interaction-adapters";
3
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
3
4
  export type SortableCollectionProps = {
4
5
  items: readonly SortableItem[];
5
6
  label: string;
@@ -8,6 +9,8 @@ export type SortableCollectionProps = {
8
9
  onCommit(intent: ReorderIntent): void;
9
10
  onCancel?(): void;
10
11
  disabled?: boolean;
12
+ /** Canonical layout-only placement on the list (DragDropProvider has no box of its own). */
13
+ layoutStyle?: HjmCompositionStyleProp;
11
14
  };
12
15
  /** Small controlled collections only; persistence and rollback belong to the host. */
13
16
  export declare function SortableCollection(props: SortableCollectionProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"sortable.d.ts","sourceRoot":"","sources":["../src/sortable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIhG,OAAO,EAAgC,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAInK,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IACtE,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC9E,CAAC;AAkBF,sFAAsF;AACtF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,+BAiEhE"}
1
+ {"version":3,"file":"sortable.d.ts","sourceRoot":"","sources":["../src/sortable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIhG,OAAO,EAAgC,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAGnK,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IACtE,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC7E,4FAA4F;IAC5F,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC;AAkBF,sFAAsF;AACtF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,+BAiEhE"}
package/dist/sortable.js CHANGED
@@ -82,6 +82,6 @@ export function SortableCollection(props) {
82
82
  const source = event.operation.source;
83
83
  if (source && isSortable(source))
84
84
  commit(String(source.id), source.index, "drag");
85
- }, children: [_jsx("ul", { ref: list, "aria-label": props.label, style: { listStyle: "none", margin: 0, padding: 0 }, children: props.items.map((item, index) => _jsx(Row, { item: item, index: index, count: props.items.length, disabled: props.disabled ?? false, reduced: environment.reducedMotion, labels: props.labels, move: to => commit(item.id, to, "keyboard"), children: props.renderItem(item) }, item.id)) }), _jsx("span", { role: "status", style: { position: "absolute", width: 1, height: 1, overflow: "hidden", clipPath: "inset(50%)" }, children: announcement })] });
85
+ }, children: [_jsx("ul", { ref: list, "aria-label": props.label, style: { listStyle: "none", margin: 0, padding: 0, ...props.layoutStyle }, children: props.items.map((item, index) => _jsx(Row, { item: item, index: index, count: props.items.length, disabled: props.disabled ?? false, reduced: environment.reducedMotion, labels: props.labels, move: to => commit(item.id, to, "keyboard"), children: props.renderItem(item) }, item.id)) }), _jsx("span", { role: "status", style: { position: "absolute", width: 1, height: 1, overflow: "hidden", clipPath: "inset(50%)" }, children: announcement })] });
86
86
  }
87
87
  //# sourceMappingURL=sortable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sortable.js","sourceRoot":"","sources":["../src/sortable.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useLayoutEffect, useRef, useState, useMemo, type ReactNode } from \"react\";\nimport { Accessibility, type DragStartEvent, type DragEndEvent } from \"@dnd-kit/dom\";\nimport { DragDropProvider } from \"@dnd-kit/react\";\nimport { useSortable, isSortable } from \"@dnd-kit/react/sortable\";\nimport { reorderIntent, validateItems, type SortableItem, type SortableLabels, type ReorderIntent } from \"@hjmds/design-contracts/components/interaction-adapters\";\nimport { Button } from \"./actions.js\";\nimport { useHjmTheme } from \"./provider.js\";\n\nexport type SortableCollectionProps = {\n items: readonly SortableItem[]; label: string; labels: SortableLabels;\n renderItem(item: SortableItem): ReactNode;\n onCommit(intent: ReorderIntent): void; onCancel?(): void; disabled?: boolean;\n};\nfunction Row({ item, index, children, disabled, reduced, labels, move, count }: {\n item: SortableItem; index: number; children: ReactNode; disabled: boolean; reduced: boolean;\n labels: SortableLabels; move(to: number): void; count: number;\n}) {\n const { ref, handleRef } = useSortable({ id: item.id, index, disabled: disabled || item.disabled === true,\n ...(reduced ? { transition: null } : {}) });\n return <li ref={ref} data-item-id={item.id} style={{ display: \"grid\", gridTemplateColumns: \"auto minmax(0, 1fr)\", alignItems: \"center\", gap: \"var(--hjm-space-sm)\", paddingBlock: \"var(--hjm-space-xs)\" }}>\n <Button ref={handleRef} tone=\"ghost\" type=\"button\" disabled={disabled || item.disabled} aria-label={labels.handle(item)}\n style={{ minWidth: 44, minHeight: 44, touchAction: \"none\", cursor: \"grab\" }}>⠿</Button>\n <div style={{ minWidth: 0, overflowWrap: \"anywhere\" }}>{children}</div>\n {/* Separate action line preserves readable item labels at 200% text in narrow hosts. */}\n <div style={{ gridColumn: \"1 / -1\", display: \"flex\", flexWrap: \"wrap\", gap: \"var(--hjm-space-xs)\" }}>\n <Button tone=\"ghost\" disabled={disabled || item.disabled || index === 0} onClick={() => move(index - 1)}>{labels.previous(item)}</Button>\n <Button tone=\"ghost\" disabled={disabled || item.disabled || index === count - 1} onClick={() => move(index + 1)}>{labels.next(item)}</Button>\n </div>\n </li>;\n}\n/** Small controlled collections only; persistence and rollback belong to the host. */\nexport function SortableCollection(props: SortableCollectionProps) {\n validateItems(props.items);\n if (!props.label.trim()) throw new TypeError(\"SortableCollection needs a label\");\n const { environment } = useHjmTheme();\n const [announcement, setAnnouncement] = useState(\"\");\n const latest = useRef(props); latest.current = props;\n const accessibility = useMemo(() => Accessibility.configure({\n screenReaderInstructions: { draggable: props.labels.instructions },\n announcements: {\n dragstart: ({ operation }: DragStartEvent) => {\n const item = latest.current.items.find(i => i.id === operation.source?.id);\n return item ? latest.current.labels.dragStart(item) : undefined;\n },\n dragend: ({ canceled }: DragEndEvent) => canceled ? latest.current.labels.dragCancel : undefined,\n // HJM emits the accepted controlled position, never raw upstream IDs.\n dragover: () => undefined, dragmove: () => undefined,\n },\n }), [props.labels.instructions]);\n const plugins = useCallback((defaults: readonly unknown[]) => [...defaults.filter(plugin => plugin !== Accessibility), accessibility],\n // A fresh function every render made the provider reassign manager.plugins on each render (2026-09-30 review).\n [accessibility]) as unknown as NonNullable<Parameters<typeof DragDropProvider>[0][\"plugins\"]>;\n const list = useRef<HTMLUListElement>(null);\n // Moving a row re-parents its DOM node, and an edge move disables the pressed button: both dropped focus to\n // <body> after a keyboard reorder. Refocus the moved row once the host has accepted the new order.\n const refocus = useRef<{ id: string; direction: \"previous\" | \"next\" } | null>(null);\n const snapshot = useRef(\"\");\n const signature = JSON.stringify(props.items);\n useLayoutEffect(() => {\n const pending = refocus.current;\n if (!pending) return;\n const row = list.current?.querySelector<HTMLElement>(`[data-item-id=\"${CSS.escape(pending.id)}\"]`);\n if (!row) return;\n refocus.current = null;\n const [handle, previous, next] = [...row.querySelectorAll<HTMLButtonElement>(\"button\")];\n const preferred = pending.direction === \"previous\" ? previous : next;\n const fallback = pending.direction === \"previous\" ? next : previous;\n (preferred && !preferred.disabled ? preferred : fallback && !fallback.disabled ? fallback : handle)?.focus();\n // Announce only once the controlled order reflects the move, never a proposed position.\n const index = props.items.findIndex(item => item.id === pending.id);\n if (index >= 0) setAnnouncement(props.labels.position(props.items[index]!, index + 1, props.items.length));\n }, [signature]); // eslint-disable-line react-hooks/exhaustive-deps\n const commit = (id: string, to: number, source: ReorderIntent[\"source\"]) => {\n if (props.disabled) return;\n const intent = reorderIntent(props.items, id, to, source);\n if (!intent) {\n // A rejected drag (fixed row in range, same index) must still end the host's drag session.\n if (source === \"drag\") props.onCancel?.();\n return;\n }\n if (source === \"keyboard\") refocus.current = { id, direction: intent.toIndex < intent.fromIndex ? \"previous\" : \"next\" };\n else refocus.current = { id, direction: \"next\" };\n props.onCommit(intent);\n };\n return <DragDropProvider plugins={plugins} onDragStart={() => { snapshot.current = signature; }} onDragEnd={event => {\n if (event.canceled || snapshot.current !== signature) { props.onCancel?.(); return; }\n const source = event.operation.source;\n if (source && isSortable(source)) commit(String(source.id), source.index, \"drag\");\n }}>\n <ul ref={list} aria-label={props.label} style={{ listStyle: \"none\", margin: 0, padding: 0 }}>\n {props.items.map((item, index) => <Row key={item.id} item={item} index={index} count={props.items.length}\n disabled={props.disabled ?? false} reduced={environment.reducedMotion} labels={props.labels}\n move={to => commit(item.id, to, \"keyboard\")}>{props.renderItem(item)}</Row>)}\n </ul>\n <span role=\"status\" style={{ position: \"absolute\", width: 1, height: 1, overflow: \"hidden\", clipPath: \"inset(50%)\" }}>{announcement}</span>\n </DragDropProvider>;\n}\n"]}
1
+ {"version":3,"file":"sortable.js","sourceRoot":"","sources":["../src/sortable.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useLayoutEffect, useRef, useState, useMemo, type ReactNode } from \"react\";\nimport { Accessibility, type DragStartEvent, type DragEndEvent } from \"@dnd-kit/dom\";\nimport { DragDropProvider } from \"@dnd-kit/react\";\nimport { useSortable, isSortable } from \"@dnd-kit/react/sortable\";\nimport { reorderIntent, validateItems, type SortableItem, type SortableLabels, type ReorderIntent } from \"@hjmds/design-contracts/components/interaction-adapters\";\nimport { Button } from \"./actions.js\";\nimport { useHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type SortableCollectionProps = {\n items: readonly SortableItem[]; label: string; labels: SortableLabels;\n renderItem(item: SortableItem): ReactNode;\n onCommit(intent: ReorderIntent): void; onCancel?(): void; disabled?: boolean;\n /** Canonical layout-only placement on the list (DragDropProvider has no box of its own). */\n layoutStyle?: HjmCompositionStyleProp;\n};\nfunction Row({ item, index, children, disabled, reduced, labels, move, count }: {\n item: SortableItem; index: number; children: ReactNode; disabled: boolean; reduced: boolean;\n labels: SortableLabels; move(to: number): void; count: number;\n}) {\n const { ref, handleRef } = useSortable({ id: item.id, index, disabled: disabled || item.disabled === true,\n ...(reduced ? { transition: null } : {}) });\n return <li ref={ref} data-item-id={item.id} style={{ display: \"grid\", gridTemplateColumns: \"auto minmax(0, 1fr)\", alignItems: \"center\", gap: \"var(--hjm-space-sm)\", paddingBlock: \"var(--hjm-space-xs)\" }}>\n <Button ref={handleRef} tone=\"ghost\" type=\"button\" disabled={disabled || item.disabled} aria-label={labels.handle(item)}\n style={{ minWidth: 44, minHeight: 44, touchAction: \"none\", cursor: \"grab\" }}>⠿</Button>\n <div style={{ minWidth: 0, overflowWrap: \"anywhere\" }}>{children}</div>\n {/* Separate action line preserves readable item labels at 200% text in narrow hosts. */}\n <div style={{ gridColumn: \"1 / -1\", display: \"flex\", flexWrap: \"wrap\", gap: \"var(--hjm-space-xs)\" }}>\n <Button tone=\"ghost\" disabled={disabled || item.disabled || index === 0} onClick={() => move(index - 1)}>{labels.previous(item)}</Button>\n <Button tone=\"ghost\" disabled={disabled || item.disabled || index === count - 1} onClick={() => move(index + 1)}>{labels.next(item)}</Button>\n </div>\n </li>;\n}\n/** Small controlled collections only; persistence and rollback belong to the host. */\nexport function SortableCollection(props: SortableCollectionProps) {\n validateItems(props.items);\n if (!props.label.trim()) throw new TypeError(\"SortableCollection needs a label\");\n const { environment } = useHjmTheme();\n const [announcement, setAnnouncement] = useState(\"\");\n const latest = useRef(props); latest.current = props;\n const accessibility = useMemo(() => Accessibility.configure({\n screenReaderInstructions: { draggable: props.labels.instructions },\n announcements: {\n dragstart: ({ operation }: DragStartEvent) => {\n const item = latest.current.items.find(i => i.id === operation.source?.id);\n return item ? latest.current.labels.dragStart(item) : undefined;\n },\n dragend: ({ canceled }: DragEndEvent) => canceled ? latest.current.labels.dragCancel : undefined,\n // HJM emits the accepted controlled position, never raw upstream IDs.\n dragover: () => undefined, dragmove: () => undefined,\n },\n }), [props.labels.instructions]);\n const plugins = useCallback((defaults: readonly unknown[]) => [...defaults.filter(plugin => plugin !== Accessibility), accessibility],\n // A fresh function every render made the provider reassign manager.plugins on each render (2026-09-30 review).\n [accessibility]) as unknown as NonNullable<Parameters<typeof DragDropProvider>[0][\"plugins\"]>;\n const list = useRef<HTMLUListElement>(null);\n // Moving a row re-parents its DOM node, and an edge move disables the pressed button: both dropped focus to\n // <body> after a keyboard reorder. Refocus the moved row once the host has accepted the new order.\n const refocus = useRef<{ id: string; direction: \"previous\" | \"next\" } | null>(null);\n const snapshot = useRef(\"\");\n const signature = JSON.stringify(props.items);\n useLayoutEffect(() => {\n const pending = refocus.current;\n if (!pending) return;\n const row = list.current?.querySelector<HTMLElement>(`[data-item-id=\"${CSS.escape(pending.id)}\"]`);\n if (!row) return;\n refocus.current = null;\n const [handle, previous, next] = [...row.querySelectorAll<HTMLButtonElement>(\"button\")];\n const preferred = pending.direction === \"previous\" ? previous : next;\n const fallback = pending.direction === \"previous\" ? next : previous;\n (preferred && !preferred.disabled ? preferred : fallback && !fallback.disabled ? fallback : handle)?.focus();\n // Announce only once the controlled order reflects the move, never a proposed position.\n const index = props.items.findIndex(item => item.id === pending.id);\n if (index >= 0) setAnnouncement(props.labels.position(props.items[index]!, index + 1, props.items.length));\n }, [signature]); // eslint-disable-line react-hooks/exhaustive-deps\n const commit = (id: string, to: number, source: ReorderIntent[\"source\"]) => {\n if (props.disabled) return;\n const intent = reorderIntent(props.items, id, to, source);\n if (!intent) {\n // A rejected drag (fixed row in range, same index) must still end the host's drag session.\n if (source === \"drag\") props.onCancel?.();\n return;\n }\n if (source === \"keyboard\") refocus.current = { id, direction: intent.toIndex < intent.fromIndex ? \"previous\" : \"next\" };\n else refocus.current = { id, direction: \"next\" };\n props.onCommit(intent);\n };\n return <DragDropProvider plugins={plugins} onDragStart={() => { snapshot.current = signature; }} onDragEnd={event => {\n if (event.canceled || snapshot.current !== signature) { props.onCancel?.(); return; }\n const source = event.operation.source;\n if (source && isSortable(source)) commit(String(source.id), source.index, \"drag\");\n }}>\n <ul ref={list} aria-label={props.label} style={{ listStyle: \"none\", margin: 0, padding: 0, ...props.layoutStyle }}>\n {props.items.map((item, index) => <Row key={item.id} item={item} index={index} count={props.items.length}\n disabled={props.disabled ?? false} reduced={environment.reducedMotion} labels={props.labels}\n move={to => commit(item.id, to, \"keyboard\")}>{props.renderItem(item)}</Row>)}\n </ul>\n <span role=\"status\" style={{ position: \"absolute\", width: 1, height: 1, overflow: \"hidden\", clipPath: \"inset(50%)\" }}>{announcement}</span>\n </DragDropProvider>;\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { type SplitterAxis } from "@hjmds/design-contracts/components/splitter";
2
2
  import { type CSSProperties, type ReactNode } from "react";
3
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
3
4
  export type SplitterProps = Readonly<{
4
5
  /** Required accessible name for the separator. */
5
6
  label: string;
@@ -20,6 +21,8 @@ export type SplitterProps = Readonly<{
20
21
  secondaryPane: ReactNode;
21
22
  className?: string;
22
23
  style?: CSSProperties;
24
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
25
+ layoutStyle?: HjmCompositionStyleProp;
23
26
  }>;
24
27
  export declare const Splitter: import("react").ForwardRefExoticComponent<Readonly<{
25
28
  /** Required accessible name for the separator. */
@@ -41,5 +44,7 @@ export declare const Splitter: import("react").ForwardRefExoticComponent<Readonl
41
44
  secondaryPane: ReactNode;
42
45
  className?: string;
43
46
  style?: CSSProperties;
47
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
48
+ layoutStyle?: HjmCompositionStyleProp;
44
49
  }> & import("react").RefAttributes<HTMLDivElement>>;
45
50
  //# sourceMappingURL=splitter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"splitter.d.ts","sourceRoot":"","sources":["../src/splitter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,YAAY,EAClB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAIL,KAAK,aAAa,EAGlB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,WAAW,EAAE,SAAS,CAAC;IACvB,aAAa,EAAE,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,CAAC,CAAC;AAoBH,eAAO,MAAM,QAAQ;IAvCnB,kDAAkD;WAC3C,MAAM;SACR,MAAM;SACN,MAAM;WACJ,MAAM;WACN,YAAY;YACX,MAAM;mBACC,MAAM;oBACL,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IACvC,wEAAwE;uBACrD,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IAC1C,6EAA6E;mBAC9D,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;eAC7B,OAAO;IAClB,6EAA6E;iBAChE,SAAS;mBACP,SAAS;gBACZ,MAAM;YACV,aAAa;mDA8IrB,CAAC"}
1
+ {"version":3,"file":"splitter.d.ts","sourceRoot":"","sources":["../src/splitter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,YAAY,EAClB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAKL,KAAK,aAAa,EAGlB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,WAAW,EAAE,SAAS,CAAC;IACvB,aAAa,EAAE,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAyCH,eAAO,MAAM,QAAQ;IA9DnB,kDAAkD;WAC3C,MAAM;SACR,MAAM;SACN,MAAM;WACJ,MAAM;WACN,YAAY;YACX,MAAM;mBACC,MAAM;oBACL,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IACvC,wEAAwE;uBACrD,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IAC1C,6EAA6E;mBAC9D,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;eAC7B,OAAO;IAClB,6EAA6E;iBAChE,SAAS;mBACP,SAAS;gBACZ,MAAM;YACV,aAAa;IACrB,gGAAgG;kBAClF,uBAAuB;mDAsKrC,CAAC"}
package/dist/splitter.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { getNextSplitterValue, resolveSplitterBoundaryValue, resolveSplitterDragValue, resolveSplitterSeparatorOrientation, splitterDefaults, splitterRecipe, validateSplitterDescriptor, } from "@hjmds/design-contracts/components/splitter";
3
- import { forwardRef, useRef, useState, } from "react";
3
+ import { forwardRef, useEffect, useRef, useState, } from "react";
4
4
  import { classNames, composeRefs, useControllableState } from "./internal.js";
5
5
  /*
6
6
  The value is a percentage of the root box: `min`/`max`/`step` stay in the
@@ -20,7 +20,30 @@ function fractionFromPointer(root, axis, clientX, clientY) {
20
20
  const flipped = horizontal && getComputedStyle(root).direction === "rtl";
21
21
  return (flipped ? span - offset : offset) / span;
22
22
  }
23
- export const Splitter = forwardRef(function Splitter({ label, min, max, step, axis = splitterDefaults.axis, value: controlledValue, defaultValue, onValueChange, onValueChangeEnd, getValueText, disabled = false, primaryPane, secondaryPane, className, style, }, forwardedRef) {
23
+ // Scrolling panes need a keyboard stop (axe scrollable-region-focusable), but only while they
24
+ // overflow: always-on tabIndex added two dead stops. Pane labels would need a breaking prop.
25
+ function useScrollableTabStop() {
26
+ const [node, setNode] = useState(null);
27
+ const [scrollable, setScrollable] = useState(false);
28
+ useEffect(() => {
29
+ if (!node)
30
+ return;
31
+ const measure = () => setScrollable(node.scrollHeight > node.clientHeight || node.scrollWidth > node.clientWidth);
32
+ measure();
33
+ if (typeof ResizeObserver === "undefined")
34
+ return;
35
+ // Content can grow without resizing the pane: watch children and mutations too.
36
+ const resize = new ResizeObserver(measure);
37
+ const observe = () => { resize.disconnect(); resize.observe(node); for (const child of node.children)
38
+ resize.observe(child); };
39
+ observe();
40
+ const mutation = new MutationObserver(() => { observe(); measure(); });
41
+ mutation.observe(node, { childList: true, subtree: true, characterData: true });
42
+ return () => { resize.disconnect(); mutation.disconnect(); };
43
+ }, [node]);
44
+ return [scrollable, setNode];
45
+ }
46
+ export const Splitter = forwardRef(function Splitter({ label, min, max, step, axis = splitterDefaults.axis, value: controlledValue, defaultValue, onValueChange, onValueChangeEnd, getValueText, disabled = false, primaryPane, secondaryPane, className, layoutStyle, style, }, forwardedRef) {
24
47
  const [value, setValue] = useControllableState({
25
48
  ...(controlledValue === undefined ? {} : { value: controlledValue }),
26
49
  defaultValue: defaultValue ?? min,
@@ -92,8 +115,10 @@ export const Splitter = forwardRef(function Splitter({ label, min, max, step, ax
92
115
  setDragging(false);
93
116
  onValueChangeEnd?.(value);
94
117
  };
118
+ const [primaryScrollable, primaryPaneRef] = useScrollableTabStop();
119
+ const [secondaryScrollable, secondaryPaneRef] = useScrollableTabStop();
95
120
  const fraction = max === min ? 0 : (value - min) / (max - min);
96
- return (_jsxs("div", { ref: composeRefs(rootRef, forwardedRef), className: classNames("hjm-splitter", className), "data-axis": axis, "data-dragging": dragging || undefined, style: { ...style, "--hjm-splitter-primary": `${fraction * 100}%` }, children: [_jsx("div", { className: "hjm-splitter__pane", "data-pane": "primary", children: primaryPane }), _jsx("div", { role: "separator", "aria-orientation": resolveSplitterSeparatorOrientation(axis), "aria-label": label, "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-valuetext": descriptor.valueText, "aria-disabled": disabled || undefined, tabIndex: disabled ? -1 : 0, className: "hjm-splitter__separator", style: { "--hjm-splitter-hit-target": `${splitterRecipe.separator.hitTarget}px`, "--hjm-splitter-thickness": `${splitterRecipe.separator.thickness}px` }, onKeyDown: onKeyDown, onPointerDown: onPointerDown, onPointerMove: resize, onPointerUp: endDrag, onPointerCancel: endDrag, children: _jsx("span", { className: "hjm-splitter__handle", "aria-hidden": "true" }) }), _jsx("div", { className: "hjm-splitter__pane", "data-pane": "secondary", children: secondaryPane })] }));
121
+ return (_jsxs("div", { ref: composeRefs(rootRef, forwardedRef), className: classNames("hjm-splitter", className), "data-axis": axis, "data-dragging": dragging || undefined, style: { ...style, ...layoutStyle, "--hjm-splitter-primary": `${fraction * 100}%` }, children: [_jsx("div", { ref: primaryPaneRef, className: "hjm-splitter__pane", tabIndex: primaryScrollable ? 0 : undefined, "data-pane": "primary", children: primaryPane }), _jsx("div", { role: "separator", "aria-orientation": resolveSplitterSeparatorOrientation(axis), "aria-label": label, "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max, "aria-valuetext": descriptor.valueText, "aria-disabled": disabled || undefined, tabIndex: disabled ? -1 : 0, className: "hjm-splitter__separator", style: { "--hjm-splitter-hit-target": `${splitterRecipe.separator.hitTarget}px`, "--hjm-splitter-thickness": `${splitterRecipe.separator.thickness}px` }, onKeyDown: onKeyDown, onPointerDown: onPointerDown, onPointerMove: resize, onPointerUp: endDrag, onPointerCancel: endDrag, children: _jsx("span", { className: "hjm-splitter__handle", "aria-hidden": "true" }) }), _jsx("div", { ref: secondaryPaneRef, className: "hjm-splitter__pane", tabIndex: secondaryScrollable ? 0 : undefined, "data-pane": "secondary", children: secondaryPane })] }));
97
122
  });
98
123
  function arrowIntent(key, axis, flipped) {
99
124
  // Only the axis the panes are arranged along resizes; the other pair of arrow
@@ -1 +1 @@
1
- {"version":3,"file":"splitter.js","sourceRoot":"","sources":["../src/splitter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getNextSplitterValue,\n resolveSplitterBoundaryValue,\n resolveSplitterDragValue,\n resolveSplitterSeparatorOrientation,\n splitterDefaults,\n splitterRecipe,\n validateSplitterDescriptor,\n type SplitterAxis,\n} from \"@hjmds/design-contracts/components/splitter\";\nimport {\n forwardRef,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type PointerEvent,\n type ReactNode,\n} from \"react\";\nimport { classNames, composeRefs, useControllableState } from \"./internal.js\";\n\nexport type SplitterProps = Readonly<{\n /** Required accessible name for the separator. */\n label: string;\n min: number;\n max: number;\n step?: number;\n axis?: SplitterAxis;\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n /** Fires once when a drag settles, for owners that persist the size. */\n onValueChangeEnd?: (value: number) => void;\n /** Product-owned announcement of the current size, e.g. \"35%\" or \"320px\". */\n getValueText?: (value: number) => string;\n disabled?: boolean;\n /** The pane the value sizes, and the pane that takes the remaining space. */\n primaryPane: ReactNode;\n secondaryPane: ReactNode;\n className?: string;\n style?: CSSProperties;\n}>;\n\n/*\n The value is a percentage of the root box: `min`/`max`/`step` stay in the\n product's own unit as the contract requires, but the pointer has to be turned\n into that unit somehow, and only a fraction of the container is meaningful\n without knowing the product's unit. Products that size in px pass min/max in\n px and read the same fraction back through their own formatting.\n*/\nfunction fractionFromPointer(root: HTMLElement, axis: SplitterAxis, clientX: number, clientY: number): number {\n const box = root.getBoundingClientRect();\n const horizontal = axis === \"horizontal\";\n const span = horizontal ? box.width : box.height;\n if (span === 0) return 0;\n const offset = horizontal ? clientX - box.left : clientY - box.top;\n // Logical, not physical: in RTL the primary pane starts at the right edge.\n const flipped = horizontal && getComputedStyle(root).direction === \"rtl\";\n return (flipped ? span - offset : offset) / span;\n}\n\nexport const Splitter = forwardRef<HTMLDivElement, SplitterProps>(function Splitter(\n {\n label,\n min,\n max,\n step,\n axis = splitterDefaults.axis,\n value: controlledValue,\n defaultValue,\n onValueChange,\n onValueChangeEnd,\n getValueText,\n disabled = false,\n primaryPane,\n secondaryPane,\n className,\n style,\n },\n forwardedRef,\n) {\n const [value, setValue] = useControllableState<number>({\n ...(controlledValue === undefined ? {} : { value: controlledValue }),\n defaultValue: defaultValue ?? min,\n ...(onValueChange === undefined ? {} : { onChange: onValueChange }),\n });\n const descriptor = {\n value,\n min,\n max,\n ...(step === undefined ? {} : { step }),\n axis,\n label,\n ...(getValueText === undefined ? {} : { valueText: getValueText(value) }),\n };\n validateSplitterDescriptor(descriptor);\n const rootRef = useRef<HTMLDivElement>(null);\n const [dragging, setDragging] = useState(false);\n\n const commit = (next: number) => {\n if (next !== value) setValue(next);\n return next;\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n const root = rootRef.current;\n const flipped = axis === \"horizontal\" && root !== null && getComputedStyle(root).direction === \"rtl\";\n const intent = arrowIntent(event.key, axis, flipped);\n const next =\n event.key === \"Home\" || event.key === \"End\"\n ? resolveSplitterBoundaryValue(descriptor, event.key === \"Home\" ? \"min\" : \"max\")\n : intent === undefined\n ? undefined\n : getNextSplitterValue(descriptor, intent);\n if (next === undefined) return;\n event.preventDefault();\n // Keyboard resize settles immediately: there is no drag to release, but an\n // owner persisting the size still needs the same end signal a drag gives.\n if (next === value) return;\n // Commit before notifying, never as the argument of an optional call:\n // `onValueChangeEnd?.(commit(next))` skips the argument entirely when no\n // handler is passed, so keyboard resize would silently do nothing.\n commit(next);\n // A step already at the boundary changes nothing, so it is not a settlement\n // — an owner persisting on every end would otherwise write a no-op.\n onValueChangeEnd?.(next);\n };\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n if (disabled || event.button !== 0) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n };\n const resize = (event: PointerEvent<HTMLDivElement>) => {\n const root = rootRef.current;\n if (!dragging || !root) return;\n const fraction = fractionFromPointer(root, axis, event.clientX, event.clientY);\n commit(resolveSplitterDragValue(descriptor, min + fraction * (max - min)));\n };\n const endDrag = (event: PointerEvent<HTMLDivElement>) => {\n if (!dragging) return;\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n setDragging(false);\n onValueChangeEnd?.(value);\n };\n\n const fraction = max === min ? 0 : (value - min) / (max - min);\n return (\n <div\n ref={composeRefs(rootRef, forwardedRef)}\n className={classNames(\"hjm-splitter\", className)}\n data-axis={axis}\n data-dragging={dragging || undefined}\n style={{ ...style, \"--hjm-splitter-primary\": `${fraction * 100}%` } as CSSProperties}\n >\n <div className=\"hjm-splitter__pane\" data-pane=\"primary\">{primaryPane}</div>\n <div\n role=\"separator\"\n // Perpendicular by contract: side-by-side panes have a vertical bar.\n aria-orientation={resolveSplitterSeparatorOrientation(axis)}\n aria-label={label}\n aria-valuenow={value}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={descriptor.valueText}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : 0}\n className=\"hjm-splitter__separator\"\n style={{ \"--hjm-splitter-hit-target\": `${splitterRecipe.separator.hitTarget}px`, \"--hjm-splitter-thickness\": `${splitterRecipe.separator.thickness}px` } as CSSProperties}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={resize}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n >\n <span className=\"hjm-splitter__handle\" aria-hidden=\"true\" />\n </div>\n <div className=\"hjm-splitter__pane\" data-pane=\"secondary\">{secondaryPane}</div>\n </div>\n );\n});\n\nfunction arrowIntent(\n key: string,\n axis: SplitterAxis,\n flipped: boolean,\n): \"increment\" | \"decrement\" | undefined {\n // Only the axis the panes are arranged along resizes; the other pair of arrow\n // keys belongs to whatever the pane content does with them. `flipped` keeps the\n // keyboard on the same logical direction the drag uses: in RTL the primary pane\n // grows toward the left, so ArrowLeft is the increment.\n if (axis === \"horizontal\") {\n if (key === (flipped ? \"ArrowLeft\" : \"ArrowRight\")) return \"increment\";\n if (key === (flipped ? \"ArrowRight\" : \"ArrowLeft\")) return \"decrement\";\n return undefined;\n }\n if (key === \"ArrowDown\") return \"increment\";\n if (key === \"ArrowUp\") return \"decrement\";\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"splitter.js","sourceRoot":"","sources":["../src/splitter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getNextSplitterValue,\n resolveSplitterBoundaryValue,\n resolveSplitterDragValue,\n resolveSplitterSeparatorOrientation,\n splitterDefaults,\n splitterRecipe,\n validateSplitterDescriptor,\n type SplitterAxis,\n} from \"@hjmds/design-contracts/components/splitter\";\nimport {\n forwardRef,\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type PointerEvent,\n type ReactNode,\n} from \"react\";\nimport { classNames, composeRefs, useControllableState } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type SplitterProps = Readonly<{\n /** Required accessible name for the separator. */\n label: string;\n min: number;\n max: number;\n step?: number;\n axis?: SplitterAxis;\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n /** Fires once when a drag settles, for owners that persist the size. */\n onValueChangeEnd?: (value: number) => void;\n /** Product-owned announcement of the current size, e.g. \"35%\" or \"320px\". */\n getValueText?: (value: number) => string;\n disabled?: boolean;\n /** The pane the value sizes, and the pane that takes the remaining space. */\n primaryPane: ReactNode;\n secondaryPane: ReactNode;\n className?: string;\n style?: CSSProperties;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/*\n The value is a percentage of the root box: `min`/`max`/`step` stay in the\n product's own unit as the contract requires, but the pointer has to be turned\n into that unit somehow, and only a fraction of the container is meaningful\n without knowing the product's unit. Products that size in px pass min/max in\n px and read the same fraction back through their own formatting.\n*/\nfunction fractionFromPointer(root: HTMLElement, axis: SplitterAxis, clientX: number, clientY: number): number {\n const box = root.getBoundingClientRect();\n const horizontal = axis === \"horizontal\";\n const span = horizontal ? box.width : box.height;\n if (span === 0) return 0;\n const offset = horizontal ? clientX - box.left : clientY - box.top;\n // Logical, not physical: in RTL the primary pane starts at the right edge.\n const flipped = horizontal && getComputedStyle(root).direction === \"rtl\";\n return (flipped ? span - offset : offset) / span;\n}\n\n// Scrolling panes need a keyboard stop (axe scrollable-region-focusable), but only while they\n// overflow: always-on tabIndex added two dead stops. Pane labels would need a breaking prop.\nfunction useScrollableTabStop(): readonly [boolean, (node: HTMLDivElement | null) => void] {\n const [node, setNode] = useState<HTMLDivElement | null>(null);\n const [scrollable, setScrollable] = useState(false);\n useEffect(() => {\n if (!node) return;\n const measure = () => setScrollable(node.scrollHeight > node.clientHeight || node.scrollWidth > node.clientWidth);\n measure();\n if (typeof ResizeObserver === \"undefined\") return;\n // Content can grow without resizing the pane: watch children and mutations too.\n const resize = new ResizeObserver(measure);\n const observe = () => { resize.disconnect(); resize.observe(node); for (const child of node.children) resize.observe(child); };\n observe();\n const mutation = new MutationObserver(() => { observe(); measure(); });\n mutation.observe(node, { childList: true, subtree: true, characterData: true });\n return () => { resize.disconnect(); mutation.disconnect(); };\n }, [node]);\n return [scrollable, setNode] as const;\n}\n\nexport const Splitter = forwardRef<HTMLDivElement, SplitterProps>(function Splitter(\n {\n label,\n min,\n max,\n step,\n axis = splitterDefaults.axis,\n value: controlledValue,\n defaultValue,\n onValueChange,\n onValueChangeEnd,\n getValueText,\n disabled = false,\n primaryPane,\n secondaryPane,\n className,\n layoutStyle,\n style,\n },\n forwardedRef,\n) {\n const [value, setValue] = useControllableState<number>({\n ...(controlledValue === undefined ? {} : { value: controlledValue }),\n defaultValue: defaultValue ?? min,\n ...(onValueChange === undefined ? {} : { onChange: onValueChange }),\n });\n const descriptor = {\n value,\n min,\n max,\n ...(step === undefined ? {} : { step }),\n axis,\n label,\n ...(getValueText === undefined ? {} : { valueText: getValueText(value) }),\n };\n validateSplitterDescriptor(descriptor);\n const rootRef = useRef<HTMLDivElement>(null);\n const [dragging, setDragging] = useState(false);\n\n const commit = (next: number) => {\n if (next !== value) setValue(next);\n return next;\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n const root = rootRef.current;\n const flipped = axis === \"horizontal\" && root !== null && getComputedStyle(root).direction === \"rtl\";\n const intent = arrowIntent(event.key, axis, flipped);\n const next =\n event.key === \"Home\" || event.key === \"End\"\n ? resolveSplitterBoundaryValue(descriptor, event.key === \"Home\" ? \"min\" : \"max\")\n : intent === undefined\n ? undefined\n : getNextSplitterValue(descriptor, intent);\n if (next === undefined) return;\n event.preventDefault();\n // Keyboard resize settles immediately: there is no drag to release, but an\n // owner persisting the size still needs the same end signal a drag gives.\n if (next === value) return;\n // Commit before notifying, never as the argument of an optional call:\n // `onValueChangeEnd?.(commit(next))` skips the argument entirely when no\n // handler is passed, so keyboard resize would silently do nothing.\n commit(next);\n // A step already at the boundary changes nothing, so it is not a settlement\n // — an owner persisting on every end would otherwise write a no-op.\n onValueChangeEnd?.(next);\n };\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n if (disabled || event.button !== 0) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n };\n const resize = (event: PointerEvent<HTMLDivElement>) => {\n const root = rootRef.current;\n if (!dragging || !root) return;\n const fraction = fractionFromPointer(root, axis, event.clientX, event.clientY);\n commit(resolveSplitterDragValue(descriptor, min + fraction * (max - min)));\n };\n const endDrag = (event: PointerEvent<HTMLDivElement>) => {\n if (!dragging) return;\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n setDragging(false);\n onValueChangeEnd?.(value);\n };\n\n const [primaryScrollable, primaryPaneRef] = useScrollableTabStop();\n const [secondaryScrollable, secondaryPaneRef] = useScrollableTabStop();\n const fraction = max === min ? 0 : (value - min) / (max - min);\n return (\n <div\n ref={composeRefs(rootRef, forwardedRef)}\n className={classNames(\"hjm-splitter\", className)}\n data-axis={axis}\n data-dragging={dragging || undefined}\n style={{ ...style, ...layoutStyle, \"--hjm-splitter-primary\": `${fraction * 100}%` } as CSSProperties}\n >\n <div ref={primaryPaneRef} className=\"hjm-splitter__pane\" tabIndex={primaryScrollable ? 0 : undefined} data-pane=\"primary\">{primaryPane}</div>\n <div\n role=\"separator\"\n // Perpendicular by contract: side-by-side panes have a vertical bar.\n aria-orientation={resolveSplitterSeparatorOrientation(axis)}\n aria-label={label}\n aria-valuenow={value}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={descriptor.valueText}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : 0}\n className=\"hjm-splitter__separator\"\n style={{ \"--hjm-splitter-hit-target\": `${splitterRecipe.separator.hitTarget}px`, \"--hjm-splitter-thickness\": `${splitterRecipe.separator.thickness}px` } as CSSProperties}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={resize}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n >\n <span className=\"hjm-splitter__handle\" aria-hidden=\"true\" />\n </div>\n <div ref={secondaryPaneRef} className=\"hjm-splitter__pane\" tabIndex={secondaryScrollable ? 0 : undefined} data-pane=\"secondary\">{secondaryPane}</div>\n </div>\n );\n});\n\nfunction arrowIntent(\n key: string,\n axis: SplitterAxis,\n flipped: boolean,\n): \"increment\" | \"decrement\" | undefined {\n // Only the axis the panes are arranged along resizes; the other pair of arrow\n // keys belongs to whatever the pane content does with them. `flipped` keeps the\n // keyboard on the same logical direction the drag uses: in RTL the primary pane\n // grows toward the left, so ArrowLeft is the increment.\n if (axis === \"horizontal\") {\n if (key === (flipped ? \"ArrowLeft\" : \"ArrowRight\")) return \"increment\";\n if (key === (flipped ? \"ArrowRight\" : \"ArrowLeft\")) return \"decrement\";\n return undefined;\n }\n if (key === \"ArrowDown\") return \"increment\";\n if (key === \"ArrowUp\") return \"decrement\";\n return undefined;\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
2
  import { type StepsProps } from "./steps.js";
3
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
3
4
  export type StepPlayerProps = Readonly<{
4
5
  descriptor: StepsProps["descriptor"];
5
6
  statusLabels: StepsProps["statusLabels"];
@@ -18,7 +19,9 @@ export type StepPlayerProps = Readonly<{
18
19
  /** Host resets its cursor/progress and chooses whether replay starts immediately. */
19
20
  onReplay: () => void;
20
21
  children?: ReactNode;
22
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
23
+ layoutStyle?: HjmCompositionStyleProp;
21
24
  }>;
22
25
  /** Controlled playback chrome: Steps owns the cursor and Progress owns range semantics. */
23
- export declare function StepPlayer({ descriptor, statusLabels, composeAccessibleName, progress, playing, disabled, labels, onPlayingChange, onReplay, children }: StepPlayerProps): import("react").JSX.Element;
26
+ export declare function StepPlayer({ descriptor, statusLabels, composeAccessibleName, progress, playing, disabled, labels, onPlayingChange, onReplay, children, layoutStyle }: StepPlayerProps): import("react").JSX.Element;
24
27
  //# sourceMappingURL=step-player.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"step-player.d.ts","sourceRoot":"","sources":["../src/step-player.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAKpD,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,UAAU,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IACrC,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,qBAAqB,EAAE,UAAU,CAAC,uBAAuB,CAAC,CAAC;IAC3D,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpF,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,qFAAqF;IACrF,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC,CAAC;AAEH,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,qBAAqB,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAgB,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,eAAe,+BAahL"}
1
+ {"version":3,"file":"step-player.d.ts","sourceRoot":"","sources":["../src/step-player.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAIpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,UAAU,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IACrC,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,qBAAqB,EAAE,UAAU,CAAC,uBAAuB,CAAC,CAAC;IAC3D,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpF,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,qFAAqF;IACrF,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,qBAAqB,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAgB,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,eAAe,+BAa7L"}
@@ -4,13 +4,13 @@ import { Progress } from "./feedback.js";
4
4
  import { Button } from "./actions.js";
5
5
  import { Stack } from "./layout.js";
6
6
  /** Controlled playback chrome: Steps owns the cursor and Progress owns range semantics. */
7
- export function StepPlayer({ descriptor, statusLabels, composeAccessibleName, progress, playing, disabled = false, labels, onPlayingChange, onReplay, children }) {
7
+ export function StepPlayer({ descriptor, statusLabels, composeAccessibleName, progress, playing, disabled = false, labels, onPlayingChange, onReplay, children, layoutStyle }) {
8
8
  // No internal timer: walkthroughs, recordings and host processes have different clocks.
9
9
  if (!Number.isFinite(progress) || progress < 0 || progress > 1)
10
10
  throw new RangeError("StepPlayer progress must be between 0 and 1");
11
11
  for (const label of Object.values(labels))
12
12
  if (!label.trim())
13
13
  throw new TypeError("StepPlayer requires localized control labels");
14
- return _jsxs(Stack, { gap: "lg", children: [_jsx(Steps, { descriptor: descriptor, statusLabels: statusLabels, composeAccessibleName: composeAccessibleName }), children, _jsx(Progress, { label: labels.progress, value: progress, max: 1 }), _jsxs(Stack, { axis: "inline", gap: "sm", children: [_jsx(Button, { disabled: disabled, onClick: () => onPlayingChange(!playing), children: playing ? labels.pause : labels.play }), _jsx(Button, { disabled: disabled, tone: "ghost", onClick: onReplay, children: labels.replay })] })] });
14
+ return _jsxs(Stack, { gap: "lg", ...(layoutStyle === undefined ? {} : { layoutStyle }), children: [_jsx(Steps, { descriptor: descriptor, statusLabels: statusLabels, composeAccessibleName: composeAccessibleName }), children, _jsx(Progress, { label: labels.progress, value: progress, max: 1 }), _jsxs(Stack, { axis: "inline", gap: "sm", children: [_jsx(Button, { disabled: disabled, onClick: () => onPlayingChange(!playing), children: playing ? labels.pause : labels.play }), _jsx(Button, { disabled: disabled, tone: "ghost", onClick: onReplay, children: labels.replay })] })] });
15
15
  }
16
16
  //# sourceMappingURL=step-player.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"step-player.js","sourceRoot":"","sources":["../src/step-player.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAiBpC,2FAA2F;AAC3F,MAAM,UAAU,UAAU,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,qBAAqB,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,GAAG,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAmB;IAC/K,wFAAwF;IACxF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,6CAA6C,CAAC,CAAC;IACpI,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YAAE,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;IAClI,OAAO,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACpB,KAAC,KAAK,IAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,GAAI,EAC1G,QAAQ,EACT,KAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAI,EAC7D,MAAC,KAAK,IAAC,IAAI,EAAC,QAAQ,EAAC,GAAG,EAAC,IAAI,aAC3B,KAAC,MAAM,IAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,YAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAU,EACrH,KAAC,MAAM,IAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAC,OAAO,EAAC,OAAO,EAAE,QAAQ,YAAG,MAAM,CAAC,MAAM,GAAU,IAC9E,IACF,CAAC;AACX,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\nimport { Steps, type StepsProps } from \"./steps.js\";\nimport { Progress } from \"./feedback.js\";\nimport { Button } from \"./actions.js\";\nimport { Stack } from \"./layout.js\";\n\nexport type StepPlayerProps = Readonly<{\n descriptor: StepsProps[\"descriptor\"];\n statusLabels: StepsProps[\"statusLabels\"];\n composeAccessibleName: StepsProps[\"composeAccessibleName\"];\n /** Playback position is supplied by the host, never estimated from elapsed time. */\n progress: number;\n playing: boolean;\n disabled?: boolean;\n labels: Readonly<{ play: string; pause: string; replay: string; progress: string }>;\n onPlayingChange: (playing: boolean) => void;\n /** Host resets its cursor/progress and chooses whether replay starts immediately. */\n onReplay: () => void;\n children?: ReactNode;\n}>;\n\n/** Controlled playback chrome: Steps owns the cursor and Progress owns range semantics. */\nexport function StepPlayer({ descriptor, statusLabels, composeAccessibleName, progress, playing, disabled = false, labels, onPlayingChange, onReplay, children }: StepPlayerProps) {\n // No internal timer: walkthroughs, recordings and host processes have different clocks.\n if (!Number.isFinite(progress) || progress < 0 || progress > 1) throw new RangeError(\"StepPlayer progress must be between 0 and 1\");\n for (const label of Object.values(labels)) if (!label.trim()) throw new TypeError(\"StepPlayer requires localized control labels\");\n return <Stack gap=\"lg\">\n <Steps descriptor={descriptor} statusLabels={statusLabels} composeAccessibleName={composeAccessibleName} />\n {children}\n <Progress label={labels.progress} value={progress} max={1} />\n <Stack axis=\"inline\" gap=\"sm\">\n <Button disabled={disabled} onClick={() => onPlayingChange(!playing)}>{playing ? labels.pause : labels.play}</Button>\n <Button disabled={disabled} tone=\"ghost\" onClick={onReplay}>{labels.replay}</Button>\n </Stack>\n </Stack>;\n}\n"]}
1
+ {"version":3,"file":"step-player.js","sourceRoot":"","sources":["../src/step-player.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAoBpC,2FAA2F;AAC3F,MAAM,UAAU,UAAU,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,qBAAqB,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,GAAG,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAmB;IAC5L,wFAAwF;IACxF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,6CAA6C,CAAC,CAAC;IACpI,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YAAE,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;IAClI,OAAO,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,aAC3E,KAAC,KAAK,IAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,GAAI,EAC1G,QAAQ,EACT,KAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAI,EAC7D,MAAC,KAAK,IAAC,IAAI,EAAC,QAAQ,EAAC,GAAG,EAAC,IAAI,aAC3B,KAAC,MAAM,IAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,YAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAU,EACrH,KAAC,MAAM,IAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAC,OAAO,EAAC,OAAO,EAAE,QAAQ,YAAG,MAAM,CAAC,MAAM,GAAU,IAC9E,IACF,CAAC;AACX,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\nimport { Steps, type StepsProps } from \"./steps.js\";\nimport { Progress } from \"./feedback.js\";\nimport { Button } from \"./actions.js\";\nimport { Stack } from \"./layout.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type StepPlayerProps = Readonly<{\n descriptor: StepsProps[\"descriptor\"];\n statusLabels: StepsProps[\"statusLabels\"];\n composeAccessibleName: StepsProps[\"composeAccessibleName\"];\n /** Playback position is supplied by the host, never estimated from elapsed time. */\n progress: number;\n playing: boolean;\n disabled?: boolean;\n labels: Readonly<{ play: string; pause: string; replay: string; progress: string }>;\n onPlayingChange: (playing: boolean) => void;\n /** Host resets its cursor/progress and chooses whether replay starts immediately. */\n onReplay: () => void;\n children?: ReactNode;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Controlled playback chrome: Steps owns the cursor and Progress owns range semantics. */\nexport function StepPlayer({ descriptor, statusLabels, composeAccessibleName, progress, playing, disabled = false, labels, onPlayingChange, onReplay, children, layoutStyle }: StepPlayerProps) {\n // No internal timer: walkthroughs, recordings and host processes have different clocks.\n if (!Number.isFinite(progress) || progress < 0 || progress > 1) throw new RangeError(\"StepPlayer progress must be between 0 and 1\");\n for (const label of Object.values(labels)) if (!label.trim()) throw new TypeError(\"StepPlayer requires localized control labels\");\n return <Stack gap=\"lg\" {...(layoutStyle === undefined ? {} : { layoutStyle })}>\n <Steps descriptor={descriptor} statusLabels={statusLabels} composeAccessibleName={composeAccessibleName} />\n {children}\n <Progress label={labels.progress} value={progress} max={1} />\n <Stack axis=\"inline\" gap=\"sm\">\n <Button disabled={disabled} onClick={() => onPlayingChange(!playing)}>{playing ? labels.pause : labels.play}</Button>\n <Button disabled={disabled} tone=\"ghost\" onClick={onReplay}>{labels.replay}</Button>\n </Stack>\n </Stack>;\n}\n"]}
package/dist/steps.d.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import { type ComposeStepsAccessibleName, type StepStatus, type StepsDescriptor, type StepsStatusLabels } from "@hjmds/design-contracts/components/steps";
2
2
  import { type HTMLAttributes, type ReactNode } from "react";
3
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
3
4
  export type StepsProps<Id extends string = string> = Omit<HTMLAttributes<HTMLOListElement>, "children"> & Readonly<{
4
5
  descriptor: StepsDescriptor<Id>;
5
6
  statusLabels: StepsStatusLabels;
6
7
  composeAccessibleName: ComposeStepsAccessibleName;
7
8
  renderMark?: (status: StepStatus, position: number) => ReactNode;
9
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
10
+ layoutStyle?: HjmCompositionStyleProp;
8
11
  }>;
9
12
  /** Linear, read-only progress steps with one canonical cursor. */
10
13
  export declare const Steps: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLOListElement>, "children"> & Readonly<{
@@ -25,5 +28,7 @@ export declare const Steps: import("react").ForwardRefExoticComponent<Omit<HTMLA
25
28
  }>;
26
29
  composeAccessibleName: ComposeStepsAccessibleName;
27
30
  renderMark?: (status: StepStatus, position: number) => ReactNode;
31
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
32
+ layoutStyle?: HjmCompositionStyleProp;
28
33
  }> & import("react").RefAttributes<HTMLOListElement>>;
29
34
  //# sourceMappingURL=steps.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../src/steps.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIxE,MAAM,MAAM,UAAU,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CACvD,cAAc,CAAC,gBAAgB,CAAC,EAChC,UAAU,CACX,GAAG,QAAQ,CAAC;IACX,UAAU,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;IAChC,YAAY,EAAE,iBAAiB,CAAC;IAChC,qBAAqB,EAAE,0BAA0B,CAAC;IAClD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;CAClE,CAAC,CAAC;AAEH,kEAAkE;AAClE,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;2BALO,0BAA0B;iBACpC,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS;qDAsChE,CAAC"}
1
+ {"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../src/steps.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,UAAU,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CACvD,cAAc,CAAC,gBAAgB,CAAC,EAChC,UAAU,CACX,GAAG,QAAQ,CAAC;IACX,UAAU,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;IAChC,YAAY,EAAE,iBAAiB,CAAC;IAChC,qBAAqB,EAAE,0BAA0B,CAAC;IAClD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;IACjE,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,kEAAkE;AAClE,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;2BAPO,0BAA0B;iBACpC,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS;IAChE,gGAAgG;kBAClF,uBAAuB;qDAsCrC,CAAC"}
package/dist/steps.js CHANGED
@@ -3,8 +3,8 @@ import { resolveStepsDescriptor, } from "@hjmds/design-contracts/components/step
3
3
  import { forwardRef } from "react";
4
4
  import { classNames } from "./internal.js";
5
5
  /** Linear, read-only progress steps with one canonical cursor. */
6
- export const Steps = forwardRef(function Steps({ descriptor, statusLabels, composeAccessibleName, renderMark, className, ...props }, ref) {
6
+ export const Steps = forwardRef(function Steps({ descriptor, statusLabels, composeAccessibleName, renderMark, className, layoutStyle, ...props }, ref) {
7
7
  const steps = resolveStepsDescriptor(descriptor, { statusLabels, composeAccessibleName });
8
- return (_jsx("ol", { ...props, ref: ref, className: classNames("hjm-steps", className), children: steps.map((step, index) => (_jsxs("li", { "aria-label": step.accessibleName, "aria-current": step.status === "current" || step.status === "error" ? "step" : undefined, className: "hjm-steps__step", "data-status": step.status, children: [_jsxs("div", { className: "hjm-steps__rail", "aria-hidden": "true", children: [_jsx("span", { className: "hjm-steps__indicator", children: renderMark?.(step.status, step.position) ?? (step.status === "complete" ? "✓" : step.status === "error" ? "!" : step.position) }), index === steps.length - 1 ? null : _jsx("span", { className: "hjm-steps__connector" })] }), _jsxs("div", { className: "hjm-steps__copy", children: [_jsx("span", { className: "hjm-steps__label", children: step.label }), step.description === undefined ? null : (_jsx("span", { className: "hjm-steps__description", children: step.description })), _jsx("span", { className: "hjm-visually-hidden", children: step.statusLabel })] })] }, step.id))) }));
8
+ return (_jsx("ol", { ...props, style: { ...props.style, ...layoutStyle }, ref: ref, className: classNames("hjm-steps", className), children: steps.map((step, index) => (_jsxs("li", { "aria-label": step.accessibleName, "aria-current": step.status === "current" || step.status === "error" ? "step" : undefined, className: "hjm-steps__step", "data-status": step.status, children: [_jsxs("div", { className: "hjm-steps__rail", "aria-hidden": "true", children: [_jsx("span", { className: "hjm-steps__indicator", children: renderMark?.(step.status, step.position) ?? (step.status === "complete" ? "✓" : step.status === "error" ? "!" : step.position) }), index === steps.length - 1 ? null : _jsx("span", { className: "hjm-steps__connector" })] }), _jsxs("div", { className: "hjm-steps__copy", children: [_jsx("span", { className: "hjm-steps__label", children: step.label }), step.description === undefined ? null : (_jsx("span", { className: "hjm-steps__description", children: step.description })), _jsx("span", { className: "hjm-visually-hidden", children: step.statusLabel })] })] }, step.id))) }));
9
9
  });
10
10
  //# sourceMappingURL=steps.js.map
package/dist/steps.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"steps.js","sourceRoot":"","sources":["../src/steps.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,sBAAsB,GAKvB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,UAAU,EAAuC,MAAM,OAAO,CAAC;AAExE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAY3C,kEAAkE;AAClE,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAA+B,SAAS,KAAK,CAC1E,EAAE,UAAU,EAAE,YAAY,EAAE,qBAAqB,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EACpF,GAAG;IAEH,MAAM,KAAK,GAAG,sBAAsB,CAAC,UAAU,EAAE,EAAE,YAAY,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAC1F,OAAO,CACL,gBAAQ,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,YACnE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,4BACc,IAAI,CAAC,cAAc,kBACjB,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACvF,SAAS,EAAC,iBAAiB,iBACd,IAAI,CAAC,MAAM,aAGxB,eAAK,SAAS,EAAC,iBAAiB,iBAAa,MAAM,aACjD,eAAM,SAAS,EAAC,sBAAsB,YACnC,UAAU,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAC3C,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CACjF,GACI,EACN,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,sBAAsB,GAAG,IAC1E,EACN,eAAK,SAAS,EAAC,iBAAiB,aAC9B,eAAM,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,KAAK,GAAQ,EACrD,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACvC,eAAM,SAAS,EAAC,wBAAwB,YAAE,IAAI,CAAC,WAAW,GAAQ,CACnE,EACD,eAAM,SAAS,EAAC,qBAAqB,YAAE,IAAI,CAAC,WAAW,GAAQ,IAC3D,KAhBD,IAAI,CAAC,EAAE,CAiBT,CACN,CAAC,GACC,CACN,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import {\n resolveStepsDescriptor,\n type ComposeStepsAccessibleName,\n type StepStatus,\n type StepsDescriptor,\n type StepsStatusLabels,\n} from \"@hjmds/design-contracts/components/steps\";\nimport { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { classNames } from \"./internal.js\";\n\nexport type StepsProps<Id extends string = string> = Omit<\n HTMLAttributes<HTMLOListElement>,\n \"children\"\n> & Readonly<{\n descriptor: StepsDescriptor<Id>;\n statusLabels: StepsStatusLabels;\n composeAccessibleName: ComposeStepsAccessibleName;\n renderMark?: (status: StepStatus, position: number) => ReactNode;\n}>;\n\n/** Linear, read-only progress steps with one canonical cursor. */\nexport const Steps = forwardRef<HTMLOListElement, StepsProps>(function Steps(\n { descriptor, statusLabels, composeAccessibleName, renderMark, className, ...props },\n ref,\n) {\n const steps = resolveStepsDescriptor(descriptor, { statusLabels, composeAccessibleName });\n return (\n <ol {...props} ref={ref} className={classNames(\"hjm-steps\", className)}>\n {steps.map((step, index) => (\n <li\n aria-label={step.accessibleName}\n aria-current={step.status === \"current\" || step.status === \"error\" ? \"step\" : undefined}\n className=\"hjm-steps__step\"\n data-status={step.status}\n key={step.id}\n >\n <div className=\"hjm-steps__rail\" aria-hidden=\"true\">\n <span className=\"hjm-steps__indicator\">\n {renderMark?.(step.status, step.position) ?? (\n step.status === \"complete\" ? \"✓\" : step.status === \"error\" ? \"!\" : step.position\n )}\n </span>\n {index === steps.length - 1 ? null : <span className=\"hjm-steps__connector\" />}\n </div>\n <div className=\"hjm-steps__copy\">\n <span className=\"hjm-steps__label\">{step.label}</span>\n {step.description === undefined ? null : (\n <span className=\"hjm-steps__description\">{step.description}</span>\n )}\n <span className=\"hjm-visually-hidden\">{step.statusLabel}</span>\n </div>\n </li>\n ))}\n </ol>\n );\n});\n"]}
1
+ {"version":3,"file":"steps.js","sourceRoot":"","sources":["../src/steps.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,sBAAsB,GAKvB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,UAAU,EAAuC,MAAM,OAAO,CAAC;AAExE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,kEAAkE;AAClE,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAA+B,SAAS,KAAK,CAC1E,EAAE,UAAU,EAAE,YAAY,EAAE,qBAAqB,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EACjG,GAAG;IAEH,MAAM,KAAK,GAAG,sBAAsB,CAAC,UAAU,EAAE,EAAE,YAAY,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAC1F,OAAO,CACL,gBAAQ,KAAK,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,YAC9G,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,4BACc,IAAI,CAAC,cAAc,kBACjB,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACvF,SAAS,EAAC,iBAAiB,iBACd,IAAI,CAAC,MAAM,aAGxB,eAAK,SAAS,EAAC,iBAAiB,iBAAa,MAAM,aACjD,eAAM,SAAS,EAAC,sBAAsB,YACnC,UAAU,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAC3C,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CACjF,GACI,EACN,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,sBAAsB,GAAG,IAC1E,EACN,eAAK,SAAS,EAAC,iBAAiB,aAC9B,eAAM,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,KAAK,GAAQ,EACrD,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACvC,eAAM,SAAS,EAAC,wBAAwB,YAAE,IAAI,CAAC,WAAW,GAAQ,CACnE,EACD,eAAM,SAAS,EAAC,qBAAqB,YAAE,IAAI,CAAC,WAAW,GAAQ,IAC3D,KAhBD,IAAI,CAAC,EAAE,CAiBT,CACN,CAAC,GACC,CACN,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import {\n resolveStepsDescriptor,\n type ComposeStepsAccessibleName,\n type StepStatus,\n type StepsDescriptor,\n type StepsStatusLabels,\n} from \"@hjmds/design-contracts/components/steps\";\nimport { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type StepsProps<Id extends string = string> = Omit<\n HTMLAttributes<HTMLOListElement>,\n \"children\"\n> & Readonly<{\n descriptor: StepsDescriptor<Id>;\n statusLabels: StepsStatusLabels;\n composeAccessibleName: ComposeStepsAccessibleName;\n renderMark?: (status: StepStatus, position: number) => ReactNode;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Linear, read-only progress steps with one canonical cursor. */\nexport const Steps = forwardRef<HTMLOListElement, StepsProps>(function Steps(\n { descriptor, statusLabels, composeAccessibleName, renderMark, className, layoutStyle, ...props },\n ref,\n) {\n const steps = resolveStepsDescriptor(descriptor, { statusLabels, composeAccessibleName });\n return (\n <ol {...props} style={{ ...props.style, ...layoutStyle }} ref={ref} className={classNames(\"hjm-steps\", className)}>\n {steps.map((step, index) => (\n <li\n aria-label={step.accessibleName}\n aria-current={step.status === \"current\" || step.status === \"error\" ? \"step\" : undefined}\n className=\"hjm-steps__step\"\n data-status={step.status}\n key={step.id}\n >\n <div className=\"hjm-steps__rail\" aria-hidden=\"true\">\n <span className=\"hjm-steps__indicator\">\n {renderMark?.(step.status, step.position) ?? (\n step.status === \"complete\" ? \"✓\" : step.status === \"error\" ? \"!\" : step.position\n )}\n </span>\n {index === steps.length - 1 ? null : <span className=\"hjm-steps__connector\" />}\n </div>\n <div className=\"hjm-steps__copy\">\n <span className=\"hjm-steps__label\">{step.label}</span>\n {step.description === undefined ? null : (\n <span className=\"hjm-steps__description\">{step.description}</span>\n )}\n <span className=\"hjm-visually-hidden\">{step.statusLabel}</span>\n </div>\n </li>\n ))}\n </ol>\n );\n});\n"]}