@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/tree.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tree.js","sourceRoot":"","sources":["../src/tree.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getTreeArrowKeyIntent,\n getTreeArrowResult,\n getVisibleTreeNavigationTarget,\n getVisibleTreeTypeaheadMatch,\n reconcileTreeExpansion,\n resolveTreeDescriptor,\n treeRecipe,\n type ComposeTreeAccessibleName,\n type ResolvedTreeNodeDescriptor,\n type TreeAsyncState,\n type TreeNodeDescriptor,\n type TreeSelectionModel,\n} from \"@hjmds/design-contracts/components/tree\";\nimport type { CheckboxState, WebKeyboardKey } from \"@hjmds/design-contracts/behaviors\";\nimport {\n forwardRef,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { classNames, composeRefs, useControllableState } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\n\nexport type TreeProps<Id extends string = string> = Readonly<{\n label: string;\n nodes: readonly TreeNodeDescriptor<Id>[];\n composeAccessibleName: ComposeTreeAccessibleName;\n expandedKeys?: ReadonlySet<Id>;\n defaultExpandedKeys?: ReadonlySet<Id>;\n onExpandedKeysChange?: (keys: ReadonlySet<Id>) => void;\n selection?: TreeSelectionModel<Id>;\n /**\n * Tri-state check marks per node, as `resolveTreeCheckedStates` derives them.\n * Checkboxes are not nested controls in a tree: the state rides on the node\n * itself as `aria-checked`, keeping the contract's one-tab-stop-per-node rule.\n */\n checkedStates?: ReadonlyMap<Id, CheckboxState>;\n onCheckedToggle?: (id: Id) => void;\n asyncState?: TreeAsyncState;\n /** Product-owned glyph for the expand/collapse affordance; decorative by contract. */\n renderToggle?: (state: Readonly<{ expanded: boolean }>) => ReactNode;\n className?: string;\n}>;\n\nconst typeaheadResetMs = 500;\n\nfunction selectedIds<Id extends string>(selection: TreeSelectionModel<Id> | undefined): ReadonlySet<Id> {\n if (!selection || selection.mode === \"none\") return new Set<Id>();\n if (selection.mode === \"single\") {\n const key = selection.selectedKey ?? selection.defaultSelectedKey ?? null;\n return key === null ? new Set<Id>() : new Set<Id>([key]);\n }\n return selection.selectedKeys ?? selection.defaultSelectedKeys ?? new Set<Id>();\n}\n\nexport const Tree = forwardRef(function Tree<Id extends string = string>(\n {\n label,\n nodes,\n composeAccessibleName,\n expandedKeys: controlledExpanded,\n defaultExpandedKeys,\n onExpandedKeysChange,\n selection,\n checkedStates,\n onCheckedToggle,\n asyncState = { status: \"idle\" },\n renderToggle,\n className,\n }: TreeProps<Id>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n const [expandedKeys, setExpandedKeys] = useControllableState<ReadonlySet<Id>>({\n ...(controlledExpanded === undefined ? {} : { value: controlledExpanded }),\n defaultValue: defaultExpandedKeys ?? new Set<Id>(),\n ...(onExpandedKeysChange === undefined ? {} : { onChange: onExpandedKeysChange }),\n });\n const direction = useOptionalHjmTheme()?.environment.direction ?? \"ltr\";\n // Expansion keys survive a node list change only where the node still exists\n // and can still hold children; the contract owns that reconciliation.\n const liveExpanded = useMemo(() => reconcileTreeExpansion(nodes, expandedKeys), [nodes, expandedKeys]);\n const resolved = useMemo(\n () => resolveTreeDescriptor(nodes, liveExpanded, { composeAccessibleName }),\n [nodes, liveExpanded, composeAccessibleName],\n );\n const visible = useMemo(() => resolved.filter((node) => node.visible), [resolved]);\n const selected = selectedIds(selection);\n const [focusedId, setFocusedId] = useState<Id | null>(null);\n // Roving tab stop: one node is tabbable, and it must stay a real visible node\n // after a collapse removed the previously focused descendant.\n const activeId = visible.some((node) => node.id === focusedId) ? focusedId : visible[0]?.id ?? null;\n const rootRef = useRef<HTMLDivElement>(null);\n const typeahead = useRef<Readonly<{ query: string; at: number }>>({ query: \"\", at: 0 });\n\n const focusNode = (id: Id) => {\n setFocusedId(id);\n rootRef.current?.querySelector<HTMLElement>(`[data-hjm-tree-node=\"${CSS.escape(id)}\"]`)?.focus();\n };\n const setExpanded = (id: Id, expanded: boolean) => {\n const next = new Set(liveExpanded);\n if (expanded) next.add(id); else next.delete(id);\n setExpandedKeys(next);\n };\n const toggleSelection = (node: ResolvedTreeNodeDescriptor<Id>) => {\n if (node.disabled || !selection || selection.mode === \"none\") return;\n if (selection.mode === \"single\") {\n const current = selection.selectedKey ?? selection.defaultSelectedKey ?? null;\n const next = current === node.id && selection.disallowEmptySelection !== true ? null : node.id;\n selection.onSelectionChange?.(next);\n return;\n }\n const next = new Set(selection.selectedKeys ?? selection.defaultSelectedKeys ?? []);\n if (next.has(node.id)) next.delete(node.id); else next.add(node.id);\n selection.onSelectionChange?.(next);\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>, node: ResolvedTreeNodeDescriptor<Id>) => {\n const key = event.key as WebKeyboardKey;\n const arrow = getTreeArrowKeyIntent(key, direction);\n if (arrow) {\n const result = getTreeArrowResult(visible, node.id, arrow);\n if (result.action === \"none\") return;\n event.preventDefault();\n if (result.action === \"moveFocus\") focusNode(result.targetId);\n else setExpanded(node.id, result.action === \"expand\");\n return;\n }\n if (key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Home\" || key === \"End\") {\n const intent = key === \"ArrowDown\" ? \"next\" : key === \"ArrowUp\" ? \"previous\" : key === \"Home\" ? \"first\" : \"last\";\n const target = getVisibleTreeNavigationTarget(visible, node.id, intent);\n if (target === undefined) return;\n event.preventDefault();\n focusNode(target);\n return;\n }\n if (key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n if (checkedStates && onCheckedToggle) { if (!node.disabled) onCheckedToggle(node.id); }\n else toggleSelection(node);\n return;\n }\n if (event.key.length !== 1 || event.metaKey || event.ctrlKey || event.altKey) return;\n const now = Date.now();\n const query = now - typeahead.current.at > typeaheadResetMs ? event.key : typeahead.current.query + event.key;\n typeahead.current = { query, at: now };\n const match = getVisibleTreeTypeaheadMatch(visible, query, { startsAfterKey: node.id });\n if (match !== undefined) { event.preventDefault(); focusNode(match); }\n };\n\n return (\n <div\n ref={composeRefs(rootRef, forwardedRef)}\n role=\"tree\"\n aria-label={label}\n aria-busy={asyncState.status === \"loading\" || asyncState.status === \"loadingMore\" || undefined}\n aria-multiselectable={selection?.mode === \"multiple\" || undefined}\n className={classNames(\"hjm-tree\", className)}\n style={{ \"--hjm-tree-indent\": `${treeRecipe.indentPerLevel}px` } as CSSProperties}\n >\n {asyncState.status === \"empty\" || asyncState.status === \"error\" || asyncState.status === \"loading\" ? (\n <p className=\"hjm-tree__state\" role={asyncState.status === \"error\" ? \"alert\" : \"status\"}>{asyncState.message}</p>\n ) : null}\n {visible.map((node) => (\n <div\n key={node.id}\n role=\"treeitem\"\n data-hjm-tree-node={node.id}\n aria-level={node.depth}\n aria-posinset={node.position}\n aria-setsize={node.siblingCount}\n aria-expanded={node.hasChildren ? node.expanded : undefined}\n aria-selected={selection && selection.mode !== \"none\" ? selected.has(node.id) : undefined}\n aria-checked={checkedStates ? (checkedStates.get(node.id) === \"mixed\" ? \"mixed\" : String(checkedStates.get(node.id) === true)) as \"true\" | \"false\" | \"mixed\" : undefined}\n aria-disabled={node.disabled || undefined}\n aria-label={node.accessibleName}\n // One tab stop for the whole tree; the glyph is decorative, not a\n // nested control, so a node is the only focusable thing in a row.\n tabIndex={node.id === activeId ? 0 : -1}\n className=\"hjm-tree__node\"\n style={{ \"--hjm-tree-depth\": node.depth - 1 } as CSSProperties}\n onClick={(event) => {\n setFocusedId(node.id);\n // Pointer users had no way to expand: only arrow keys toggled (2026-09-30\n // audit WR-0930-2). The contract lets a row click change expansion; the\n // glyph toggles only, and in check mode the row click stays the check.\n const onGlyph = node.hasChildren &&\n (event.target as Element).closest?.(\".hjm-tree__toggle\") !== null;\n if (onGlyph) { setExpanded(node.id, !node.expanded); return; }\n if (checkedStates && onCheckedToggle) { if (!node.disabled) onCheckedToggle(node.id); return; }\n if (node.hasChildren) setExpanded(node.id, !node.expanded);\n toggleSelection(node);\n }}\n onFocus={() => setFocusedId(node.id)}\n onKeyDown={(event) => onKeyDown(event, node)}\n >\n <span aria-hidden=\"true\" className=\"hjm-tree__indent\" />\n {checkedStates ? (\n <span aria-hidden=\"true\" className=\"hjm-tree__check\" data-state={String(checkedStates.get(node.id) ?? false)}>\n {checkedStates.get(node.id) === true ? \"✓\" : checkedStates.get(node.id) === \"mixed\" ? \"–\" : \"\"}\n </span>\n ) : null}\n <span aria-hidden=\"true\" className=\"hjm-tree__toggle\" data-visible={node.hasChildren || undefined}>\n {node.hasChildren ? renderToggle?.({ expanded: node.expanded }) ?? (node.expanded ? \"▾\" : \"▸\") : null}\n </span>\n <span aria-hidden=\"true\" className=\"hjm-tree__label\">\n {node.label}\n {node.description ? <span className=\"hjm-tree__description\">{node.description}</span> : null}\n </span>\n </div>\n ))}\n {asyncState.status === \"loadingMore\" ? <p className=\"hjm-tree__state\" role=\"status\">{asyncState.message}</p> : null}\n </div>\n );\n}) as <Id extends string = string>(\n props: TreeProps<Id> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n"]}
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../src/tree.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getTreeArrowKeyIntent,\n getTreeArrowResult,\n getVisibleTreeNavigationTarget,\n getVisibleTreeTypeaheadMatch,\n reconcileTreeExpansion,\n resolveTreeDescriptor,\n treeRecipe,\n type ComposeTreeAccessibleName,\n type ResolvedTreeNodeDescriptor,\n type TreeAsyncState,\n type TreeNodeDescriptor,\n type TreeSelectionModel,\n} from \"@hjmds/design-contracts/components/tree\";\nimport type { CheckboxState, WebKeyboardKey } from \"@hjmds/design-contracts/behaviors\";\nimport {\n forwardRef,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { classNames, composeRefs, useControllableState } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type TreeProps<Id extends string = string> = Readonly<{\n label: string;\n nodes: readonly TreeNodeDescriptor<Id>[];\n composeAccessibleName: ComposeTreeAccessibleName;\n expandedKeys?: ReadonlySet<Id>;\n defaultExpandedKeys?: ReadonlySet<Id>;\n onExpandedKeysChange?: (keys: ReadonlySet<Id>) => void;\n selection?: TreeSelectionModel<Id>;\n /**\n * Tri-state check marks per node, as `resolveTreeCheckedStates` derives them.\n * Checkboxes are not nested controls in a tree: the state rides on the node\n * itself as `aria-checked`, keeping the contract's one-tab-stop-per-node rule.\n */\n checkedStates?: ReadonlyMap<Id, CheckboxState>;\n onCheckedToggle?: (id: Id) => void;\n asyncState?: TreeAsyncState;\n /** Product-owned glyph for the expand/collapse affordance; decorative by contract. */\n renderToggle?: (state: Readonly<{ expanded: boolean }>) => ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nconst typeaheadResetMs = 500;\n\nfunction selectedIds<Id extends string>(selection: TreeSelectionModel<Id> | undefined): ReadonlySet<Id> {\n if (!selection || selection.mode === \"none\") return new Set<Id>();\n if (selection.mode === \"single\") {\n const key = selection.selectedKey ?? selection.defaultSelectedKey ?? null;\n return key === null ? new Set<Id>() : new Set<Id>([key]);\n }\n return selection.selectedKeys ?? selection.defaultSelectedKeys ?? new Set<Id>();\n}\n\nexport const Tree = forwardRef(function Tree<Id extends string = string>(\n {\n label,\n nodes,\n composeAccessibleName,\n expandedKeys: controlledExpanded,\n defaultExpandedKeys,\n onExpandedKeysChange,\n selection,\n checkedStates,\n onCheckedToggle,\n asyncState = { status: \"idle\" },\n renderToggle,\n className,\n layoutStyle,\n }: TreeProps<Id>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n const [expandedKeys, setExpandedKeys] = useControllableState<ReadonlySet<Id>>({\n ...(controlledExpanded === undefined ? {} : { value: controlledExpanded }),\n defaultValue: defaultExpandedKeys ?? new Set<Id>(),\n ...(onExpandedKeysChange === undefined ? {} : { onChange: onExpandedKeysChange }),\n });\n const direction = useOptionalHjmTheme()?.environment.direction ?? \"ltr\";\n // Expansion keys survive a node list change only where the node still exists\n // and can still hold children; the contract owns that reconciliation.\n const liveExpanded = useMemo(() => reconcileTreeExpansion(nodes, expandedKeys), [nodes, expandedKeys]);\n const resolved = useMemo(\n () => resolveTreeDescriptor(nodes, liveExpanded, { composeAccessibleName }),\n [nodes, liveExpanded, composeAccessibleName],\n );\n const visible = useMemo(() => resolved.filter((node) => node.visible), [resolved]);\n // `defaultSelectedKey(s)` used to be re-read on every render, so an\n // uncontrolled tree reported the click to `onSelectionChange` but kept showing\n // the default. Keep the uncontrolled value in state like `useControllableState`\n // does for expansion; a controlled `selectedKey(s)` (including `null`) still wins.\n const selectionControlled = selection?.mode === \"single\"\n ? selection.selectedKey !== undefined\n : selection?.mode === \"multiple\" ? selection.selectedKeys !== undefined : true;\n const [uncontrolledSelected, setUncontrolledSelected] = useState<ReadonlySet<Id>>(() => selectedIds(selection));\n const selected = selectionControlled ? selectedIds(selection) : uncontrolledSelected;\n const [focusedId, setFocusedId] = useState<Id | null>(null);\n // Roving tab stop: one node is tabbable, and it must stay a real visible node\n // after a collapse removed the previously focused descendant.\n const activeId = visible.some((node) => node.id === focusedId) ? focusedId : visible[0]?.id ?? null;\n const rootRef = useRef<HTMLDivElement>(null);\n const typeahead = useRef<Readonly<{ query: string; at: number }>>({ query: \"\", at: 0 });\n\n const focusNode = (id: Id) => {\n setFocusedId(id);\n rootRef.current?.querySelector<HTMLElement>(`[data-hjm-tree-node=\"${CSS.escape(id)}\"]`)?.focus();\n };\n const setExpanded = (id: Id, expanded: boolean) => {\n const next = new Set(liveExpanded);\n if (expanded) next.add(id); else next.delete(id);\n setExpandedKeys(next);\n };\n const toggleSelection = (node: ResolvedTreeNodeDescriptor<Id>) => {\n if (node.disabled || !selection || selection.mode === \"none\") return;\n if (selection.mode === \"single\") {\n const current = selected.has(node.id) ? node.id : null;\n const next = current === node.id && selection.disallowEmptySelection !== true ? null : node.id;\n if (!selectionControlled) setUncontrolledSelected(next === null ? new Set<Id>() : new Set<Id>([next]));\n selection.onSelectionChange?.(next);\n return;\n }\n const next = new Set(selected);\n if (next.has(node.id)) next.delete(node.id); else next.add(node.id);\n if (!selectionControlled) setUncontrolledSelected(next);\n selection.onSelectionChange?.(next);\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>, node: ResolvedTreeNodeDescriptor<Id>) => {\n const key = event.key as WebKeyboardKey;\n const arrow = getTreeArrowKeyIntent(key, direction);\n if (arrow) {\n const result = getTreeArrowResult(visible, node.id, arrow);\n if (result.action === \"none\") return;\n event.preventDefault();\n if (result.action === \"moveFocus\") focusNode(result.targetId);\n else setExpanded(node.id, result.action === \"expand\");\n return;\n }\n if (key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Home\" || key === \"End\") {\n const intent = key === \"ArrowDown\" ? \"next\" : key === \"ArrowUp\" ? \"previous\" : key === \"Home\" ? \"first\" : \"last\";\n const target = getVisibleTreeNavigationTarget(visible, node.id, intent);\n if (target === undefined) return;\n event.preventDefault();\n focusNode(target);\n return;\n }\n if (key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n if (checkedStates && onCheckedToggle) { if (!node.disabled) onCheckedToggle(node.id); }\n else toggleSelection(node);\n return;\n }\n if (event.key.length !== 1 || event.metaKey || event.ctrlKey || event.altKey) return;\n const now = Date.now();\n const query = now - typeahead.current.at > typeaheadResetMs ? event.key : typeahead.current.query + event.key;\n typeahead.current = { query, at: now };\n const match = getVisibleTreeTypeaheadMatch(visible, query, { startsAfterKey: node.id });\n if (match !== undefined) { event.preventDefault(); focusNode(match); }\n };\n\n return (\n <div\n ref={composeRefs(rootRef, forwardedRef)}\n role=\"tree\"\n aria-label={label}\n aria-busy={asyncState.status === \"loading\" || asyncState.status === \"loadingMore\" || undefined}\n aria-multiselectable={selection?.mode === \"multiple\" || undefined}\n className={classNames(\"hjm-tree\", className)}\n style={{ ...layoutStyle, \"--hjm-tree-indent\": `${treeRecipe.indentPerLevel}px` } as CSSProperties}\n >\n {asyncState.status === \"empty\" || asyncState.status === \"error\" || asyncState.status === \"loading\" ? (\n <p className=\"hjm-tree__state\" role={asyncState.status === \"error\" ? \"alert\" : \"status\"}>{asyncState.message}</p>\n ) : null}\n {visible.map((node) => (\n <div\n key={node.id}\n role=\"treeitem\"\n data-hjm-tree-node={node.id}\n aria-level={node.depth}\n aria-posinset={node.position}\n aria-setsize={node.siblingCount}\n aria-expanded={node.hasChildren ? node.expanded : undefined}\n aria-selected={selection && selection.mode !== \"none\" ? selected.has(node.id) : undefined}\n aria-checked={checkedStates ? (checkedStates.get(node.id) === \"mixed\" ? \"mixed\" : String(checkedStates.get(node.id) === true)) as \"true\" | \"false\" | \"mixed\" : undefined}\n aria-disabled={node.disabled || undefined}\n aria-label={node.accessibleName}\n // One tab stop for the whole tree; the glyph is decorative, not a\n // nested control, so a node is the only focusable thing in a row.\n tabIndex={node.id === activeId ? 0 : -1}\n className=\"hjm-tree__node\"\n style={{ \"--hjm-tree-depth\": node.depth - 1 } as CSSProperties}\n onClick={(event) => {\n setFocusedId(node.id);\n // Pointer users had no way to expand: only arrow keys toggled (2026-09-30\n // audit WR-0930-2). The contract lets a row click change expansion; the\n // glyph toggles only, and in check mode the row click stays the check.\n const onGlyph = node.hasChildren &&\n (event.target as Element).closest?.(\".hjm-tree__toggle\") !== null;\n if (onGlyph) { setExpanded(node.id, !node.expanded); return; }\n if (checkedStates && onCheckedToggle) { if (!node.disabled) onCheckedToggle(node.id); return; }\n if (node.hasChildren) setExpanded(node.id, !node.expanded);\n toggleSelection(node);\n }}\n onFocus={() => setFocusedId(node.id)}\n onKeyDown={(event) => onKeyDown(event, node)}\n >\n <span aria-hidden=\"true\" className=\"hjm-tree__indent\" />\n {checkedStates ? (\n <span aria-hidden=\"true\" className=\"hjm-tree__check\" data-state={String(checkedStates.get(node.id) ?? false)}>\n {checkedStates.get(node.id) === true ? \"✓\" : checkedStates.get(node.id) === \"mixed\" ? \"–\" : \"\"}\n </span>\n ) : null}\n <span aria-hidden=\"true\" className=\"hjm-tree__toggle\" data-visible={node.hasChildren || undefined}>\n {node.hasChildren ? renderToggle?.({ expanded: node.expanded }) ?? (node.expanded ? \"▾\" : \"▸\") : null}\n </span>\n <span aria-hidden=\"true\" className=\"hjm-tree__label\">\n {node.label}\n {node.description ? <span className=\"hjm-tree__description\">{node.description}</span> : null}\n </span>\n </div>\n ))}\n {asyncState.status === \"loadingMore\" ? <p className=\"hjm-tree__state\" role=\"status\">{asyncState.message}</p> : null}\n </div>\n );\n}) as <Id extends string = string>(\n props: TreeProps<Id> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n"]}
@@ -1,11 +1,14 @@
1
1
  import { type UploadItemDescriptor, type UploadItemLabels } from "@hjmds/design-contracts/components/upload-item";
2
2
  import { type HTMLAttributes, type ReactNode } from "react";
3
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
3
4
  export type UploadItemProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & Readonly<{
4
5
  descriptor: UploadItemDescriptor;
5
6
  labels: UploadItemLabels;
6
7
  onCancel?: (id: string) => void;
7
8
  onRetry?: (id: string) => void;
8
9
  leading?: ReactNode;
10
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
11
+ layoutStyle?: HjmCompositionStyleProp;
9
12
  }>;
10
13
  /** One upload row whose available action is derived entirely from status. */
11
14
  export declare const UploadItem: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & Readonly<{
@@ -14,5 +17,7 @@ export declare const UploadItem: import("react").ForwardRefExoticComponent<Omit<
14
17
  onCancel?: (id: string) => void;
15
18
  onRetry?: (id: string) => void;
16
19
  leading?: ReactNode;
20
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
21
+ layoutStyle?: HjmCompositionStyleProp;
17
22
  }> & import("react").RefAttributes<HTMLDivElement>>;
18
23
  //# sourceMappingURL=upload-item.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload-item.d.ts","sourceRoot":"","sources":["../src/upload-item.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKxE,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC;IACxF,UAAU,EAAE,oBAAoB,CAAC;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB,CAAC,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,UAAU;gBART,oBAAoB;YACxB,gBAAgB;eACb,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI;cACrB,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI;cACpB,SAAS;mDA8DnB,CAAC"}
1
+ {"version":3,"file":"upload-item.d.ts","sourceRoot":"","sources":["../src/upload-item.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC;IACxF,UAAU,EAAE,oBAAoB,CAAC;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,UAAU;gBAVT,oBAAoB;YACxB,gBAAgB;eACb,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI;cACrB,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI;cACpB,SAAS;IACnB,gGAAgG;kBAClF,uBAAuB;mDA+DrC,CAAC"}
@@ -4,7 +4,7 @@ import { forwardRef } from "react";
4
4
  import { Progress } from "./feedback.js";
5
5
  import { classNames } from "./internal.js";
6
6
  /** One upload row whose available action is derived entirely from status. */
7
- export const UploadItem = forwardRef(function UploadItem({ descriptor, labels, onCancel, onRetry, leading, className, ...props }, ref) {
7
+ export const UploadItem = forwardRef(function UploadItem({ descriptor, labels, onCancel, onRetry, leading, className, layoutStyle, ...props }, ref) {
8
8
  const announcement = resolveUploadItemAnnouncement(descriptor, labels);
9
9
  const action = getUploadItemAvailableAction(descriptor.state);
10
10
  if (action === "cancel" && onCancel === undefined) {
@@ -18,6 +18,6 @@ export const UploadItem = forwardRef(function UploadItem({ descriptor, labels, o
18
18
  const progressValueText = isUploading && announcement.description !== labels.uploading
19
19
  ? announcement.description
20
20
  : undefined;
21
- return (_jsxs("div", { ...props, ref: ref, "aria-label": announcement.label, className: classNames("hjm-upload-item", className), "data-status": descriptor.state.status, role: "group", children: [leading === undefined ? null : _jsx("span", { "aria-hidden": "true", className: "hjm-upload-item__leading", children: leading }), _jsxs("div", { className: "hjm-upload-item__body", children: [_jsx("span", { className: "hjm-upload-item__name", children: descriptor.name }), descriptor.sizeLabel === undefined ? null : _jsx("span", { className: "hjm-upload-item__meta", children: descriptor.sizeLabel }), isUploading ? (_jsxs(_Fragment, { children: [_jsx("span", { "aria-atomic": "true", "aria-live": "polite", className: "hjm-upload-item__status hjm-visually-hidden", children: labels.uploading }), _jsx(Progress, { "aria-label": labels.uploading, label: labels.uploading, ...(progress === null || progress === undefined ? {} : { value: progress * 100 }), ...(progressValueText === undefined ? {} : { valueText: progressValueText }) })] })) : (_jsx("span", { className: "hjm-upload-item__status", "aria-live": "polite", children: announcement.description }))] }), action === "cancel" ? (_jsx("button", { className: "hjm-upload-item__action", "data-action": "cancel", onClick: () => onCancel?.(descriptor.id), type: "button", children: labels.cancel })) : action === "retry" ? (_jsx("button", { className: "hjm-upload-item__action", "data-action": "retry", onClick: () => onRetry?.(descriptor.id), type: "button", children: labels.retry })) : null] }));
21
+ return (_jsxs("div", { ...props, style: { ...props.style, ...layoutStyle }, ref: ref, "aria-label": announcement.label, className: classNames("hjm-upload-item", className), "data-status": descriptor.state.status, role: "group", children: [leading === undefined ? null : _jsx("span", { "aria-hidden": "true", className: "hjm-upload-item__leading", children: leading }), _jsxs("div", { className: "hjm-upload-item__body", children: [_jsx("span", { className: "hjm-upload-item__name", children: descriptor.name }), descriptor.sizeLabel === undefined ? null : _jsx("span", { className: "hjm-upload-item__meta", children: descriptor.sizeLabel }), isUploading ? (_jsxs(_Fragment, { children: [_jsx("span", { "aria-atomic": "true", "aria-live": "polite", className: "hjm-upload-item__status hjm-visually-hidden", children: labels.uploading }), _jsx(Progress, { "aria-label": labels.uploading, label: labels.uploading, ...(progress === null || progress === undefined ? {} : { value: progress * 100 }), ...(progressValueText === undefined ? {} : { valueText: progressValueText }) })] })) : (_jsx("span", { className: "hjm-upload-item__status", "aria-live": "polite", children: announcement.description }))] }), action === "cancel" ? (_jsx("button", { className: "hjm-upload-item__action", "data-action": "cancel", onClick: () => onCancel?.(descriptor.id), type: "button", children: labels.cancel })) : action === "retry" ? (_jsx("button", { className: "hjm-upload-item__action", "data-action": "retry", onClick: () => onRetry?.(descriptor.id), type: "button", children: labels.retry })) : null] }));
22
22
  });
23
23
  //# sourceMappingURL=upload-item.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload-item.js","sourceRoot":"","sources":["../src/upload-item.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getUploadItemAvailableAction,\n resolveUploadItemAnnouncement,\n type UploadItemDescriptor,\n type UploadItemLabels,\n} from \"@hjmds/design-contracts/components/upload-item\";\nimport { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { Progress } from \"./feedback.js\";\nimport { classNames } from \"./internal.js\";\n\nexport type UploadItemProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> & Readonly<{\n descriptor: UploadItemDescriptor;\n labels: UploadItemLabels;\n onCancel?: (id: string) => void;\n onRetry?: (id: string) => void;\n leading?: ReactNode;\n}>;\n\n/** One upload row whose available action is derived entirely from status. */\nexport const UploadItem = forwardRef<HTMLDivElement, UploadItemProps>(function UploadItem(\n { descriptor, labels, onCancel, onRetry, leading, className, ...props },\n ref,\n) {\n const announcement = resolveUploadItemAnnouncement(descriptor, labels);\n const action = getUploadItemAvailableAction(descriptor.state);\n if (action === \"cancel\" && onCancel === undefined) {\n throw new TypeError(\"UploadItem requires onCancel while status is uploading\");\n }\n if (action === \"retry\" && onRetry === undefined) {\n throw new TypeError(\"UploadItem requires onRetry while status is error\");\n }\n const isUploading = descriptor.state.status === \"uploading\";\n const progress = isUploading ? descriptor.state.progress : undefined;\n const progressValueText =\n isUploading && announcement.description !== labels.uploading\n ? announcement.description\n : undefined;\n return (\n <div\n {...props}\n ref={ref}\n aria-label={announcement.label}\n className={classNames(\"hjm-upload-item\", className)}\n data-status={descriptor.state.status}\n role=\"group\"\n >\n {leading === undefined ? null : <span aria-hidden=\"true\" className=\"hjm-upload-item__leading\">{leading}</span>}\n <div className=\"hjm-upload-item__body\">\n <span className=\"hjm-upload-item__name\">{descriptor.name}</span>\n {descriptor.sizeLabel === undefined ? null : <span className=\"hjm-upload-item__meta\">{descriptor.sizeLabel}</span>}\n {isUploading ? (\n <>\n <span\n aria-atomic=\"true\"\n aria-live=\"polite\"\n className=\"hjm-upload-item__status hjm-visually-hidden\"\n >\n {labels.uploading}\n </span>\n <Progress\n aria-label={labels.uploading}\n label={labels.uploading}\n {...(progress === null || progress === undefined ? {} : { value: progress * 100 })}\n {...(progressValueText === undefined ? {} : { valueText: progressValueText })}\n />\n </>\n ) : (\n <span className=\"hjm-upload-item__status\" aria-live=\"polite\">{announcement.description}</span>\n )}\n </div>\n {action === \"cancel\" ? (\n <button className=\"hjm-upload-item__action\" data-action=\"cancel\" onClick={() => onCancel?.(descriptor.id)} type=\"button\">{labels.cancel}</button>\n ) : action === \"retry\" ? (\n <button className=\"hjm-upload-item__action\" data-action=\"retry\" onClick={() => onRetry?.(descriptor.id)} type=\"button\">{labels.retry}</button>\n ) : null}\n </div>\n );\n});\n"]}
1
+ {"version":3,"file":"upload-item.js","sourceRoot":"","sources":["../src/upload-item.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getUploadItemAvailableAction,\n resolveUploadItemAnnouncement,\n type UploadItemDescriptor,\n type UploadItemLabels,\n} from \"@hjmds/design-contracts/components/upload-item\";\nimport { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { Progress } from \"./feedback.js\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type UploadItemProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> & Readonly<{\n descriptor: UploadItemDescriptor;\n labels: UploadItemLabels;\n onCancel?: (id: string) => void;\n onRetry?: (id: string) => void;\n leading?: ReactNode;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** One upload row whose available action is derived entirely from status. */\nexport const UploadItem = forwardRef<HTMLDivElement, UploadItemProps>(function UploadItem(\n { descriptor, labels, onCancel, onRetry, leading, className, layoutStyle, ...props },\n ref,\n) {\n const announcement = resolveUploadItemAnnouncement(descriptor, labels);\n const action = getUploadItemAvailableAction(descriptor.state);\n if (action === \"cancel\" && onCancel === undefined) {\n throw new TypeError(\"UploadItem requires onCancel while status is uploading\");\n }\n if (action === \"retry\" && onRetry === undefined) {\n throw new TypeError(\"UploadItem requires onRetry while status is error\");\n }\n const isUploading = descriptor.state.status === \"uploading\";\n const progress = isUploading ? descriptor.state.progress : undefined;\n const progressValueText =\n isUploading && announcement.description !== labels.uploading\n ? announcement.description\n : undefined;\n return (\n <div\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n aria-label={announcement.label}\n className={classNames(\"hjm-upload-item\", className)}\n data-status={descriptor.state.status}\n role=\"group\"\n >\n {leading === undefined ? null : <span aria-hidden=\"true\" className=\"hjm-upload-item__leading\">{leading}</span>}\n <div className=\"hjm-upload-item__body\">\n <span className=\"hjm-upload-item__name\">{descriptor.name}</span>\n {descriptor.sizeLabel === undefined ? null : <span className=\"hjm-upload-item__meta\">{descriptor.sizeLabel}</span>}\n {isUploading ? (\n <>\n <span\n aria-atomic=\"true\"\n aria-live=\"polite\"\n className=\"hjm-upload-item__status hjm-visually-hidden\"\n >\n {labels.uploading}\n </span>\n <Progress\n aria-label={labels.uploading}\n label={labels.uploading}\n {...(progress === null || progress === undefined ? {} : { value: progress * 100 })}\n {...(progressValueText === undefined ? {} : { valueText: progressValueText })}\n />\n </>\n ) : (\n <span className=\"hjm-upload-item__status\" aria-live=\"polite\">{announcement.description}</span>\n )}\n </div>\n {action === \"cancel\" ? (\n <button className=\"hjm-upload-item__action\" data-action=\"cancel\" onClick={() => onCancel?.(descriptor.id)} type=\"button\">{labels.cancel}</button>\n ) : action === \"retry\" ? (\n <button className=\"hjm-upload-item__action\" data-action=\"retry\" onClick={() => onRetry?.(descriptor.id)} type=\"button\">{labels.retry}</button>\n ) : null}\n </div>\n );\n});\n"]}
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
2
3
  export type VirtualListProps<T> = {
3
4
  items: readonly T[];
4
5
  keyExtractor: (item: T) => string;
@@ -8,7 +9,9 @@ export type VirtualListProps<T> = {
8
9
  label: string;
9
10
  empty?: ReactNode;
10
11
  overscan?: number;
12
+ /** Canonical layout-only placement on the scroll viewport. `height` stays the prop's: the window math reads it. */
13
+ layoutStyle?: HjmCompositionStyleProp;
11
14
  };
12
15
  /** Fixed-height rows are an explicit host contract; use List for unconstrained flowing copy. */
13
- export declare function VirtualList<T>({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan }: VirtualListProps<T>): import("react").JSX.Element;
16
+ export declare function VirtualList<T>({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan, layoutStyle }: VirtualListProps<T>): import("react").JSX.Element;
14
17
  //# sourceMappingURL=virtual-list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"virtual-list.d.ts","sourceRoot":"","sources":["../src/virtual-list.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1F,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAAC,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAAC,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACxO,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAY,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BA+BrI"}
1
+ {"version":3,"file":"virtual-list.d.ts","sourceRoot":"","sources":["../src/virtual-list.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAAC,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAAC,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IACpO,mHAAmH;IACnH,WAAW,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAAC;AAC1C,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAY,EAAE,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BA+BlJ"}
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useId, useLayoutEffect, useMemo, useRef, useState } from "react";
3
3
  import { resolveVirtualWindow, validateListKeys } from "@hjmds/design-contracts/components/virtual-list";
4
4
  /** Fixed-height rows are an explicit host contract; use List for unconstrained flowing copy. */
5
- export function VirtualList({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan = 3 }) {
5
+ export function VirtualList({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan = 3, layoutStyle }) {
6
6
  const keys = useMemo(() => items.map(keyExtractor), [items, keyExtractor]);
7
7
  validateListKeys(keys, label);
8
8
  const [scrollTop, setScrollTop] = useState(0);
@@ -21,7 +21,7 @@ export function VirtualList({ items, keyExtractor, renderItem, rowHeight, height
21
21
  } }, [selected, id]);
22
22
  // Keep keyboard/descendant focus mounted when wheel scrolling moves it outside the window.
23
23
  const indices = [...new Set([...Array.from({ length: range.end - range.start }, (_, i) => i + range.start), ...(items.length ? [selected] : []), ...(focused !== null && focused < items.length ? [focused] : [])])].sort((a, b) => a - b);
24
- return _jsx("div", { "data-hjm-virtual-list": true, className: "hjm-virtual-list", ref: host, role: "list", "aria-label": label, tabIndex: 0, style: { overflowY: "auto", height, position: "relative" }, onScroll: event => setScrollTop(event.currentTarget.scrollTop), onKeyDown: event => {
24
+ return _jsx("div", { "data-hjm-virtual-list": true, className: "hjm-virtual-list", ref: host, role: "list", "aria-label": label, tabIndex: 0, style: { ...layoutStyle, overflowY: "auto", height, position: "relative" }, onScroll: event => setScrollTop(event.currentTarget.scrollTop), onKeyDown: event => {
25
25
  if (!items.length || !(event.target instanceof HTMLElement) || (event.target !== event.currentTarget && !event.target.hasAttribute("data-virtual-row")))
26
26
  return;
27
27
  const next = event.key === "ArrowDown" ? Math.min(selected + 1, items.length - 1) : event.key === "ArrowUp" ? Math.max(0, selected - 1) : event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : null;
@@ -1 +1 @@
1
- {"version":3,"file":"virtual-list.js","sourceRoot":"","sources":["../src/virtual-list.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useId, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { resolveVirtualWindow, validateListKeys } from \"@hjmds/design-contracts/components/virtual-list\";\nexport type VirtualListProps<T> = { items: readonly T[]; keyExtractor: (item: T) => string; renderItem: (item: T, index: number) => ReactNode; rowHeight: number; height: number; label: string; empty?: ReactNode; overscan?: number };\n/** Fixed-height rows are an explicit host contract; use List for unconstrained flowing copy. */\nexport function VirtualList<T>({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan = 3 }: VirtualListProps<T>) {\n const keys = useMemo(() => items.map(keyExtractor), [items, keyExtractor]); validateListKeys(keys, label);\n const [scrollTop, setScrollTop] = useState(0);\n const [active, setActive] = useState(0);\n const [focused, setFocused] = useState<number | null>(null);\n const host = useRef<HTMLDivElement>(null); const moveFocus = useRef(false); const id = useId();\n const range = resolveVirtualWindow(items.length, rowHeight, height, scrollTop, overscan);\n const selected = Math.min(active, Math.max(0, items.length - 1));\n useLayoutEffect(() => { if (host.current && host.current.scrollTop !== range.offset) host.current.scrollTop = range.offset; }, [range.offset]);\n useLayoutEffect(() => { if (moveFocus.current) { document.getElementById(`${id}-${selected}`)?.focus({ preventScroll: true }); moveFocus.current = false; } }, [selected, id]);\n // Keep keyboard/descendant focus mounted when wheel scrolling moves it outside the window.\n const indices = [...new Set([...Array.from({ length: range.end - range.start }, (_, i) => i + range.start), ...(items.length ? [selected] : []), ...(focused !== null && focused < items.length ? [focused] : [])])].sort((a,b) => a-b);\n return <div data-hjm-virtual-list className=\"hjm-virtual-list\" ref={host} role=\"list\" aria-label={label} tabIndex={0}\n style={{ overflowY: \"auto\", height, position: \"relative\" }} onScroll={event => setScrollTop(event.currentTarget.scrollTop)}\n onKeyDown={event => {\n if (!items.length || !(event.target instanceof HTMLElement) || (event.target !== event.currentTarget && !event.target.hasAttribute(\"data-virtual-row\"))) return;\n const next = event.key === \"ArrowDown\" ? Math.min(selected + 1, items.length - 1) : event.key === \"ArrowUp\" ? Math.max(0, selected - 1) : event.key === \"Home\" ? 0 : event.key === \"End\" ? items.length - 1 : null;\n if (next === null) return; event.preventDefault(); moveFocus.current = true; setActive(next);\n const top = next * rowHeight; const viewport = event.currentTarget;\n if (top < viewport.scrollTop) viewport.scrollTop = top;\n else if (top + rowHeight > viewport.scrollTop + height) viewport.scrollTop = top + rowHeight - height;\n setScrollTop(viewport.scrollTop);\n const rendered = document.getElementById(`${id}-${next}`);\n if (rendered) { rendered.focus({ preventScroll: true }); moveFocus.current = false; }\n }}>\n {!items.length ? empty : <div style={{ position: \"relative\", height: range.totalHeight }}>\n {indices.map(index => <div key={keys[index]} id={`${id}-${index}`} role=\"listitem\" data-virtual-row className=\"hjm-virtual-list__row\" tabIndex={index === selected ? 0 : -1} aria-setsize={items.length} aria-posinset={index + 1}\n onFocusCapture={() => setFocused(index)} onBlurCapture={event => { if (!event.currentTarget.contains(event.relatedTarget)) setFocused(null); }}\n style={{ position: \"absolute\", top: index * rowHeight, height: rowHeight, width: \"100%\" }}>{renderItem(items[index]!, index)}</div>)}\n </div>}\n </div>;\n}\n"]}
1
+ {"version":3,"file":"virtual-list.js","sourceRoot":"","sources":["../src/virtual-list.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useId, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { resolveVirtualWindow, validateListKeys } from \"@hjmds/design-contracts/components/virtual-list\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nexport type VirtualListProps<T> = { items: readonly T[]; keyExtractor: (item: T) => string; renderItem: (item: T, index: number) => ReactNode; rowHeight: number; height: number; label: string; empty?: ReactNode; overscan?: number;\n /** Canonical layout-only placement on the scroll viewport. `height` stays the prop's: the window math reads it. */\n layoutStyle?: HjmCompositionStyleProp };\n/** Fixed-height rows are an explicit host contract; use List for unconstrained flowing copy. */\nexport function VirtualList<T>({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan = 3, layoutStyle }: VirtualListProps<T>) {\n const keys = useMemo(() => items.map(keyExtractor), [items, keyExtractor]); validateListKeys(keys, label);\n const [scrollTop, setScrollTop] = useState(0);\n const [active, setActive] = useState(0);\n const [focused, setFocused] = useState<number | null>(null);\n const host = useRef<HTMLDivElement>(null); const moveFocus = useRef(false); const id = useId();\n const range = resolveVirtualWindow(items.length, rowHeight, height, scrollTop, overscan);\n const selected = Math.min(active, Math.max(0, items.length - 1));\n useLayoutEffect(() => { if (host.current && host.current.scrollTop !== range.offset) host.current.scrollTop = range.offset; }, [range.offset]);\n useLayoutEffect(() => { if (moveFocus.current) { document.getElementById(`${id}-${selected}`)?.focus({ preventScroll: true }); moveFocus.current = false; } }, [selected, id]);\n // Keep keyboard/descendant focus mounted when wheel scrolling moves it outside the window.\n const indices = [...new Set([...Array.from({ length: range.end - range.start }, (_, i) => i + range.start), ...(items.length ? [selected] : []), ...(focused !== null && focused < items.length ? [focused] : [])])].sort((a,b) => a-b);\n return <div data-hjm-virtual-list className=\"hjm-virtual-list\" ref={host} role=\"list\" aria-label={label} tabIndex={0}\n style={{ ...layoutStyle, overflowY: \"auto\", height, position: \"relative\" }} onScroll={event => setScrollTop(event.currentTarget.scrollTop)}\n onKeyDown={event => {\n if (!items.length || !(event.target instanceof HTMLElement) || (event.target !== event.currentTarget && !event.target.hasAttribute(\"data-virtual-row\"))) return;\n const next = event.key === \"ArrowDown\" ? Math.min(selected + 1, items.length - 1) : event.key === \"ArrowUp\" ? Math.max(0, selected - 1) : event.key === \"Home\" ? 0 : event.key === \"End\" ? items.length - 1 : null;\n if (next === null) return; event.preventDefault(); moveFocus.current = true; setActive(next);\n const top = next * rowHeight; const viewport = event.currentTarget;\n if (top < viewport.scrollTop) viewport.scrollTop = top;\n else if (top + rowHeight > viewport.scrollTop + height) viewport.scrollTop = top + rowHeight - height;\n setScrollTop(viewport.scrollTop);\n const rendered = document.getElementById(`${id}-${next}`);\n if (rendered) { rendered.focus({ preventScroll: true }); moveFocus.current = false; }\n }}>\n {!items.length ? empty : <div style={{ position: \"relative\", height: range.totalHeight }}>\n {indices.map(index => <div key={keys[index]} id={`${id}-${index}`} role=\"listitem\" data-virtual-row className=\"hjm-virtual-list__row\" tabIndex={index === selected ? 0 : -1} aria-setsize={items.length} aria-posinset={index + 1}\n onFocusCapture={() => setFocused(index)} onBlurCapture={event => { if (!event.currentTarget.contains(event.relatedTarget)) setFocused(null); }}\n style={{ position: \"absolute\", top: index * rowHeight, height: rowHeight, width: \"100%\" }}>{renderItem(items[index]!, index)}</div>)}\n </div>}\n </div>;\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
2
  import { type VoiceNoteDescriptor } from "@hjmds/design-contracts/voice-note";
3
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
3
4
  export type VoiceNoteProps = Readonly<{
4
5
  descriptor: VoiceNoteDescriptor;
5
6
  labels: Readonly<{
@@ -18,7 +19,9 @@ export type VoiceNoteProps = Readonly<{
18
19
  onPlayingChange: (playing: boolean) => void;
19
20
  onSeek: (seconds: number) => void;
20
21
  onRetry?: () => void;
22
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
23
+ layoutStyle?: HjmCompositionStyleProp;
21
24
  }>;
22
25
  /** Audio engine, network, file permission and playback lifecycle remain host-owned. */
23
- export declare function VoiceNote({ descriptor, labels, formatTime, artwork, onPlayingChange, onSeek, onRetry }: VoiceNoteProps): import("react").JSX.Element;
26
+ export declare function VoiceNote({ descriptor, labels, formatTime, artwork, onPlayingChange, onSeek, onRetry, layoutStyle }: VoiceNoteProps): import("react").JSX.Element;
24
27
  //# sourceMappingURL=voice-note.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"voice-note.d.ts","sourceRoot":"","sources":["../src/voice-note.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAMhG,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,UAAU,EAAE,mBAAmB,CAAC;IAChC,MAAM,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClJ,mEAAmE;IACnE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC,CAAC;AAEH,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,+BAgBtH"}
1
+ {"version":3,"file":"voice-note.d.ts","sourceRoot":"","sources":["../src/voice-note.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAKhG,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,UAAU,EAAE,mBAAmB,CAAC;IAChC,MAAM,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClJ,mEAAmE;IACnE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,cAAc,+BAgBnI"}
@@ -5,9 +5,9 @@ import { Button } from "./actions.js";
5
5
  import { Slider } from "./slider.js";
6
6
  import { Stack, Surface, Text } from "./layout.js";
7
7
  /** Audio engine, network, file permission and playback lifecycle remain host-owned. */
8
- export function VoiceNote({ descriptor, labels, formatTime, artwork, onPlayingChange, onSeek, onRetry }) {
8
+ export function VoiceNote({ descriptor, labels, formatTime, artwork, onPlayingChange, onSeek, onRetry, layoutStyle }) {
9
9
  const media = resolveVoiceNote(descriptor);
10
10
  const error = media.state === "error";
11
- return _jsx(Surface, { padding: "lg", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { axis: "inline", gap: "md", children: [artwork ? _jsx(Asset, { descriptor: { kind: "image", decorative: true, shape: "circle" }, children: artwork }) : null, _jsx(Text, { emphasis: "strong", children: media.title })] }), _jsx(Slider, { label: labels.seek, min: 0, max: media.duration || 1, step: 0.1, value: media.position, disabled: !media.canSeek, onValueChange: onSeek, getValueText: formatTime }), _jsxs(Text, { tone: "muted", children: [formatTime(media.position), media.duration === null ? "" : ` / ${formatTime(media.duration)}`] }), error ? _jsx(Text, { role: "alert", children: labels.error }) : null, _jsxs(Stack, { axis: "inline", gap: "sm", children: [_jsx(Button, { disabled: !media.canPlay, loading: media.state === "loading", onClick: () => onPlayingChange(media.state !== "playing"), children: media.state === "loading" ? labels.loading : media.state === "playing" ? labels.pause : labels.play }), error && onRetry ? _jsx(Button, { disabled: media.disabled ?? false, onClick: onRetry, children: labels.retry }) : null] })] }) });
11
+ return _jsx(Surface, { padding: "lg", ...(layoutStyle === undefined ? {} : { layoutStyle }), children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { axis: "inline", gap: "md", children: [artwork ? _jsx(Asset, { descriptor: { kind: "image", decorative: true, shape: "circle" }, children: artwork }) : null, _jsx(Text, { emphasis: "strong", children: media.title })] }), _jsx(Slider, { label: labels.seek, min: 0, max: media.duration || 1, step: 0.1, value: media.position, disabled: !media.canSeek, onValueChange: onSeek, getValueText: formatTime }), _jsxs(Text, { tone: "muted", children: [formatTime(media.position), media.duration === null ? "" : ` / ${formatTime(media.duration)}`] }), error ? _jsx(Text, { role: "alert", children: labels.error }) : null, _jsxs(Stack, { axis: "inline", gap: "sm", children: [_jsx(Button, { disabled: !media.canPlay, loading: media.state === "loading", onClick: () => onPlayingChange(media.state !== "playing"), children: media.state === "loading" ? labels.loading : media.state === "playing" ? labels.pause : labels.play }), error && onRetry ? _jsx(Button, { disabled: media.disabled ?? false, onClick: onRetry, children: labels.retry }) : null] })] }) });
12
12
  }
13
13
  //# sourceMappingURL=voice-note.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"voice-note.js","sourceRoot":"","sources":["../src/voice-note.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAA4B,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAanD,uFAAuF;AACvF,MAAM,UAAU,SAAS,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAkB;IACrH,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC;IACtC,OAAO,KAAC,OAAO,IAAC,OAAO,EAAC,IAAI,YAAC,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aAC1C,MAAC,KAAK,IAAC,IAAI,EAAC,QAAQ,EAAC,GAAG,EAAC,IAAI,aAC1B,OAAO,CAAC,CAAC,CAAC,KAAC,KAAK,IAAC,UAAU,EAAE,EAAC,IAAI,EAAC,OAAO,EAAC,UAAU,EAAC,IAAI,EAAC,KAAK,EAAC,QAAQ,EAAC,YAAG,OAAO,GAAS,CAAC,CAAC,CAAC,IAAI,EACrG,KAAC,IAAI,IAAC,QAAQ,EAAC,QAAQ,YAAE,KAAK,CAAC,KAAK,GAAQ,IACtC,EACR,KAAC,MAAM,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,GAAK,EAC9K,MAAC,IAAI,IAAC,IAAI,EAAC,OAAO,aAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAQ,EACxH,KAAK,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,YAAE,MAAM,CAAC,KAAK,GAAQ,CAAC,CAAC,CAAC,IAAI,EACxD,MAAC,KAAK,IAAC,IAAI,EAAC,QAAQ,EAAC,GAAG,EAAC,IAAI,aAC3B,KAAC,MAAM,IAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,YAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAU,EAC9O,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,EAAE,OAAO,EAAE,OAAO,YAAG,MAAM,CAAC,KAAK,GAAU,CAAC,CAAC,CAAC,IAAI,IACzG,IACF,GAAU,CAAC;AACrB,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\nimport { resolveVoiceNote, type VoiceNoteDescriptor } from \"@hjmds/design-contracts/voice-note\";\nimport { Asset } from \"./asset.js\";\nimport { Button } from \"./actions.js\";\nimport { Slider } from \"./slider.js\";\nimport { Stack, Surface, Text } from \"./layout.js\";\n\nexport type VoiceNoteProps = Readonly<{\n descriptor: VoiceNoteDescriptor;\n labels: Readonly<{ play: string; pause: string; seek: string; loading: string; error: string; retry: string; backward: string; forward: string }>;\n /** Localized elapsed/duration text and slider accessible value. */\n formatTime: (seconds: number) => string;\n artwork?: ReactNode;\n onPlayingChange: (playing: boolean) => void;\n onSeek: (seconds: number) => void;\n onRetry?: () => void;\n}>;\n\n/** Audio engine, network, file permission and playback lifecycle remain host-owned. */\nexport function VoiceNote({ descriptor, labels, formatTime, artwork, onPlayingChange, onSeek, onRetry }: VoiceNoteProps) {\n const media = resolveVoiceNote(descriptor);\n const error = media.state === \"error\";\n return <Surface padding=\"lg\"><Stack gap=\"md\">\n <Stack axis=\"inline\" gap=\"md\">\n {artwork ? <Asset descriptor={{kind:\"image\",decorative:true,shape:\"circle\"}}>{artwork}</Asset> : null}\n <Text emphasis=\"strong\">{media.title}</Text>\n </Stack>\n <Slider label={labels.seek} min={0} max={media.duration || 1} step={0.1} value={media.position} disabled={!media.canSeek} onValueChange={onSeek} getValueText={formatTime} />\n <Text tone=\"muted\">{formatTime(media.position)}{media.duration === null ? \"\" : ` / ${formatTime(media.duration)}`}</Text>\n {error ? <Text role=\"alert\">{labels.error}</Text> : null}\n <Stack axis=\"inline\" gap=\"sm\">\n <Button disabled={!media.canPlay} loading={media.state === \"loading\"} onClick={() => onPlayingChange(media.state !== \"playing\")}>{media.state === \"loading\" ? labels.loading : media.state === \"playing\" ? labels.pause : labels.play}</Button>\n {error && onRetry ? <Button disabled={media.disabled ?? false} onClick={onRetry}>{labels.retry}</Button> : null}\n </Stack>\n </Stack></Surface>;\n}\n"]}
1
+ {"version":3,"file":"voice-note.js","sourceRoot":"","sources":["../src/voice-note.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAA4B,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAgBnD,uFAAuF;AACvF,MAAM,UAAU,SAAS,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAkB;IAClI,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC;IACtC,OAAO,KAAC,OAAO,IAAC,OAAO,EAAC,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,YAAE,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aAClG,MAAC,KAAK,IAAC,IAAI,EAAC,QAAQ,EAAC,GAAG,EAAC,IAAI,aAC1B,OAAO,CAAC,CAAC,CAAC,KAAC,KAAK,IAAC,UAAU,EAAE,EAAC,IAAI,EAAC,OAAO,EAAC,UAAU,EAAC,IAAI,EAAC,KAAK,EAAC,QAAQ,EAAC,YAAG,OAAO,GAAS,CAAC,CAAC,CAAC,IAAI,EACrG,KAAC,IAAI,IAAC,QAAQ,EAAC,QAAQ,YAAE,KAAK,CAAC,KAAK,GAAQ,IACtC,EACR,KAAC,MAAM,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,GAAK,EAC9K,MAAC,IAAI,IAAC,IAAI,EAAC,OAAO,aAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAQ,EACxH,KAAK,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,YAAE,MAAM,CAAC,KAAK,GAAQ,CAAC,CAAC,CAAC,IAAI,EACxD,MAAC,KAAK,IAAC,IAAI,EAAC,QAAQ,EAAC,GAAG,EAAC,IAAI,aAC3B,KAAC,MAAM,IAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,YAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAU,EAC9O,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,EAAE,OAAO,EAAE,OAAO,YAAG,MAAM,CAAC,KAAK,GAAU,CAAC,CAAC,CAAC,IAAI,IACzG,IACF,GAAU,CAAC;AACrB,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\nimport { resolveVoiceNote, type VoiceNoteDescriptor } from \"@hjmds/design-contracts/voice-note\";\nimport { Asset } from \"./asset.js\";\nimport { Button } from \"./actions.js\";\nimport { Slider } from \"./slider.js\";\nimport { Stack, Surface, Text } from \"./layout.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type VoiceNoteProps = Readonly<{\n descriptor: VoiceNoteDescriptor;\n labels: Readonly<{ play: string; pause: string; seek: string; loading: string; error: string; retry: string; backward: string; forward: string }>;\n /** Localized elapsed/duration text and slider accessible value. */\n formatTime: (seconds: number) => string;\n artwork?: ReactNode;\n onPlayingChange: (playing: boolean) => void;\n onSeek: (seconds: number) => void;\n onRetry?: () => void;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Audio engine, network, file permission and playback lifecycle remain host-owned. */\nexport function VoiceNote({ descriptor, labels, formatTime, artwork, onPlayingChange, onSeek, onRetry, layoutStyle }: VoiceNoteProps) {\n const media = resolveVoiceNote(descriptor);\n const error = media.state === \"error\";\n return <Surface padding=\"lg\" {...(layoutStyle === undefined ? {} : { layoutStyle })}><Stack gap=\"md\">\n <Stack axis=\"inline\" gap=\"md\">\n {artwork ? <Asset descriptor={{kind:\"image\",decorative:true,shape:\"circle\"}}>{artwork}</Asset> : null}\n <Text emphasis=\"strong\">{media.title}</Text>\n </Stack>\n <Slider label={labels.seek} min={0} max={media.duration || 1} step={0.1} value={media.position} disabled={!media.canSeek} onValueChange={onSeek} getValueText={formatTime} />\n <Text tone=\"muted\">{formatTime(media.position)}{media.duration === null ? \"\" : ` / ${formatTime(media.duration)}`}</Text>\n {error ? <Text role=\"alert\">{labels.error}</Text> : null}\n <Stack axis=\"inline\" gap=\"sm\">\n <Button disabled={!media.canPlay} loading={media.state === \"loading\"} onClick={() => onPlayingChange(media.state !== \"playing\")}>{media.state === \"loading\" ? labels.loading : media.state === \"playing\" ? labels.pause : labels.play}</Button>\n {error && onRetry ? <Button disabled={media.disabled ?? false} onClick={onRetry}>{labels.retry}</Button> : null}\n </Stack>\n </Stack></Surface>;\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
2
3
  export type WatermarkProps = Readonly<{
3
4
  text: string | readonly string[];
4
5
  children: ReactNode;
@@ -6,7 +7,9 @@ export type WatermarkProps = Readonly<{
6
7
  tileHeight?: number;
7
8
  rotate?: number;
8
9
  opacity?: number;
10
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
11
+ layoutStyle?: HjmCompositionStyleProp;
9
12
  }>;
10
13
  /** React escapes all text; an inline SVG pattern avoids canvas, external requests and markup interpolation. */
11
- export declare function Watermark({ text, children, tileWidth, tileHeight, rotate, opacity }: WatermarkProps): import("react").JSX.Element;
14
+ export declare function Watermark({ text, children, tileWidth, tileHeight, rotate, opacity, layoutStyle }: WatermarkProps): import("react").JSX.Element;
12
15
  //# sourceMappingURL=watermark.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"watermark.d.ts","sourceRoot":"","sources":["../src/watermark.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9C,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC7K,+GAA+G;AAC/G,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,+BAanG"}
1
+ {"version":3,"file":"watermark.d.ts","sourceRoot":"","sources":["../src/watermark.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IACxK,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAAC,CAAC;AAC3C,+GAA+G;AAC/G,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,cAAc,+BAahH"}
package/dist/watermark.js CHANGED
@@ -2,9 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useId } from "react";
3
3
  import { resolveWatermark } from "@hjmds/design-contracts/components/watermark";
4
4
  /** React escapes all text; an inline SVG pattern avoids canvas, external requests and markup interpolation. */
5
- export function Watermark({ text, children, tileWidth, tileHeight, rotate, opacity }) {
5
+ export function Watermark({ text, children, tileWidth, tileHeight, rotate, opacity, layoutStyle }) {
6
6
  const config = resolveWatermark(text, tileWidth, tileHeight, rotate, opacity);
7
7
  const id = `hjm-watermark-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
8
- return _jsxs("div", { className: "hjm-watermark", "data-hjm-watermark": true, children: [_jsx("div", { className: "hjm-watermark__content", children: children }), _jsxs("svg", { className: "hjm-watermark__overlay", "aria-hidden": "true", focusable: "false", width: "100%", height: "100%", children: [_jsx("defs", { children: _jsx("pattern", { id: id, width: config.width, height: config.height, patternUnits: "userSpaceOnUse", children: _jsx("g", { transform: `rotate(${config.rotate} ${config.width / 2} ${config.height / 2})`, opacity: config.opacity, fill: "currentColor", children: config.lines.map((line, index) => _jsx("text", { x: config.width / 2, y: config.height / 2, dy: `${(index - (config.lines.length - 1) / 2) * 1.2}em`, textAnchor: "middle", dominantBaseline: "middle", children: line }, index)) }) }) }), _jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })] })] });
8
+ return _jsxs("div", { className: "hjm-watermark", style: layoutStyle, "data-hjm-watermark": true, children: [_jsx("div", { className: "hjm-watermark__content", children: children }), _jsxs("svg", { className: "hjm-watermark__overlay", "aria-hidden": "true", focusable: "false", width: "100%", height: "100%", children: [_jsx("defs", { children: _jsx("pattern", { id: id, width: config.width, height: config.height, patternUnits: "userSpaceOnUse", children: _jsx("g", { transform: `rotate(${config.rotate} ${config.width / 2} ${config.height / 2})`, opacity: config.opacity, fill: "currentColor", children: config.lines.map((line, index) => _jsx("text", { x: config.width / 2, y: config.height / 2, dy: `${(index - (config.lines.length - 1) / 2) * 1.2}em`, textAnchor: "middle", dominantBaseline: "middle", children: line }, index)) }) }) }), _jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })] })] });
9
9
  }
10
10
  //# sourceMappingURL=watermark.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"watermark.js","sourceRoot":"","sources":["../src/watermark.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAEhF,+GAA+G;AAC/G,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAkB;IAClG,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9E,MAAM,EAAE,GAAG,iBAAiB,KAAK,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,EAAE,CAAC;IACrE,OAAO,eAAK,SAAS,EAAC,eAAe,yCACnC,cAAK,SAAS,EAAC,wBAAwB,YAAE,QAAQ,GAAO,EACxD,eAAK,SAAS,EAAC,wBAAwB,iBAAa,MAAM,EAAC,SAAS,EAAC,OAAO,EAAC,KAAK,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,aACrG,yBAAM,kBAAS,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAC,gBAAgB,YAC9F,YAAG,SAAS,EAAE,UAAU,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAC,cAAc,YAC5H,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,eAAkB,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,EAAE,UAAU,EAAC,QAAQ,EAAC,gBAAgB,EAAC,QAAQ,YAAE,IAAI,IAA/J,KAAK,CAAkK,CAAC,GACpN,GACI,GAAO,EAAA,eAAM,KAAK,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAI,IACrE,IACF,CAAC;AACT,CAAC","sourcesContent":["import { useId, type ReactNode } from \"react\";\nimport { resolveWatermark } from \"@hjmds/design-contracts/components/watermark\";\nexport type WatermarkProps = Readonly<{ text: string | readonly string[]; children: ReactNode; tileWidth?: number; tileHeight?: number; rotate?: number; opacity?: number }>;\n/** React escapes all text; an inline SVG pattern avoids canvas, external requests and markup interpolation. */\nexport function Watermark({ text, children, tileWidth, tileHeight, rotate, opacity }: WatermarkProps) {\n const config = resolveWatermark(text, tileWidth, tileHeight, rotate, opacity);\n const id = `hjm-watermark-${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n return <div className=\"hjm-watermark\" data-hjm-watermark>\n <div className=\"hjm-watermark__content\">{children}</div>\n <svg className=\"hjm-watermark__overlay\" aria-hidden=\"true\" focusable=\"false\" width=\"100%\" height=\"100%\">\n <defs><pattern id={id} width={config.width} height={config.height} patternUnits=\"userSpaceOnUse\">\n <g transform={`rotate(${config.rotate} ${config.width / 2} ${config.height / 2})`} opacity={config.opacity} fill=\"currentColor\">\n {config.lines.map((line, index) => <text key={index} x={config.width / 2} y={config.height / 2} dy={`${(index - (config.lines.length - 1) / 2) * 1.2}em`} textAnchor=\"middle\" dominantBaseline=\"middle\">{line}</text>)}\n </g>\n </pattern></defs><rect width=\"100%\" height=\"100%\" fill={`url(#${id})`} />\n </svg>\n </div>;\n}\n"]}
1
+ {"version":3,"file":"watermark.js","sourceRoot":"","sources":["../src/watermark.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAKhF,+GAA+G;AAC/G,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAkB;IAC/G,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9E,MAAM,EAAE,GAAG,iBAAiB,KAAK,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,EAAE,CAAC;IACrE,OAAO,eAAK,SAAS,EAAC,eAAe,EAAC,KAAK,EAAE,WAAW,yCACtD,cAAK,SAAS,EAAC,wBAAwB,YAAE,QAAQ,GAAO,EACxD,eAAK,SAAS,EAAC,wBAAwB,iBAAa,MAAM,EAAC,SAAS,EAAC,OAAO,EAAC,KAAK,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,aACrG,yBAAM,kBAAS,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAC,gBAAgB,YAC9F,YAAG,SAAS,EAAE,UAAU,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAC,cAAc,YAC5H,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,eAAkB,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,EAAE,UAAU,EAAC,QAAQ,EAAC,gBAAgB,EAAC,QAAQ,YAAE,IAAI,IAA/J,KAAK,CAAkK,CAAC,GACpN,GACI,GAAO,EAAA,eAAM,KAAK,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAI,IACrE,IACF,CAAC;AACT,CAAC","sourcesContent":["import { useId, type ReactNode } from \"react\";\nimport { resolveWatermark } from \"@hjmds/design-contracts/components/watermark\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nexport type WatermarkProps = Readonly<{ text: string | readonly string[]; children: ReactNode; tileWidth?: number; tileHeight?: number; rotate?: number; opacity?: number;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp }>;\n/** React escapes all text; an inline SVG pattern avoids canvas, external requests and markup interpolation. */\nexport function Watermark({ text, children, tileWidth, tileHeight, rotate, opacity, layoutStyle }: WatermarkProps) {\n const config = resolveWatermark(text, tileWidth, tileHeight, rotate, opacity);\n const id = `hjm-watermark-${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n return <div className=\"hjm-watermark\" style={layoutStyle} data-hjm-watermark>\n <div className=\"hjm-watermark__content\">{children}</div>\n <svg className=\"hjm-watermark__overlay\" aria-hidden=\"true\" focusable=\"false\" width=\"100%\" height=\"100%\">\n <defs><pattern id={id} width={config.width} height={config.height} patternUnits=\"userSpaceOnUse\">\n <g transform={`rotate(${config.rotate} ${config.width / 2} ${config.height / 2})`} opacity={config.opacity} fill=\"currentColor\">\n {config.lines.map((line, index) => <text key={index} x={config.width / 2} y={config.height / 2} dy={`${(index - (config.lines.length - 1) / 2) * 1.2}em`} textAnchor=\"middle\" dominantBaseline=\"middle\">{line}</text>)}\n </g>\n </pattern></defs><rect width=\"100%\" height=\"100%\" fill={`url(#${id})`} />\n </svg>\n </div>;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hjmds/react",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Accessible React 19 renderers for HJM design contracts.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -457,6 +457,21 @@
457
457
  "types": "./dist/navigation-bar.d.ts",
458
458
  "import": "./dist/navigation-bar.js",
459
459
  "default": "./dist/navigation-bar.js"
460
+ },
461
+ "./screens": {
462
+ "types": "./dist/screens.d.ts",
463
+ "import": "./dist/screens.js",
464
+ "default": "./dist/screens.js"
465
+ },
466
+ "./screen-flows": {
467
+ "types": "./dist/screen-flows.d.ts",
468
+ "import": "./dist/screen-flows.js",
469
+ "default": "./dist/screen-flows.js"
470
+ },
471
+ "./saved-items": {
472
+ "types": "./dist/saved-items.d.ts",
473
+ "import": "./dist/saved-items.js",
474
+ "default": "./dist/saved-items.js"
460
475
  }
461
476
  },
462
477
  "files": [
@@ -466,7 +481,7 @@
466
481
  "THIRD_PARTY_NOTICES.md"
467
482
  ],
468
483
  "peerDependencies": {
469
- "@hjmds/design-contracts": ">=1.12.0 <1.13.0",
484
+ "@hjmds/design-contracts": ">=1.13.0 <1.14.0",
470
485
  "react": ">=19.0.0",
471
486
  "react-dom": ">=19.0.0",
472
487
  "@number-flow/react": "0.6.2",
@@ -503,7 +518,7 @@
503
518
  "blobatar": "2.7.0",
504
519
  "@blobatar/react": "2.7.0",
505
520
  "lucide-react": "1.49.0",
506
- "@hjmds/design-contracts": "1.12.0"
521
+ "@hjmds/design-contracts": "1.13.0"
507
522
  },
508
523
  "peerDependenciesMeta": {
509
524
  "@number-flow/react": {