@hjmds/react 1.12.1 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +326 -0
  238. package/dist/screen-flows.d.ts.map +1 -0
  239. package/dist/screen-flows.js +222 -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 +256 -70
  282. package/dist/styles.layered.css +256 -70
  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
@@ -1,12 +1,15 @@
1
- import { emptyStateRecipe, skeletonRecipe, type NoticeTone, type ProgressShape, type ProgressSize, type ProgressTone, type SpinnerSize, type SpinnerTone } from "@hjmds/design-contracts/recipes";
1
+ import { emptyStateRecipe, skeletonRecipe, type NoticeTone, type ProgressShape, type ProgressSize, type ProgressTone } from "@hjmds/design-contracts/recipes";
2
2
  import { type ResultDescriptor } from "@hjmds/design-contracts/components/result";
3
3
  import { type HTMLAttributes, type ProgressHTMLAttributes, type ReactNode } from "react";
4
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
4
5
  export type NoticeProps = Omit<HTMLAttributes<HTMLElement>, "title"> & Readonly<{
5
6
  title: ReactNode;
6
7
  description?: ReactNode;
7
8
  action?: ReactNode;
8
9
  icon?: ReactNode;
9
10
  tone?: NoticeTone;
11
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
12
+ layoutStyle?: HjmCompositionStyleProp;
10
13
  }>;
11
14
  export declare const Notice: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLElement>, "title"> & Readonly<{
12
15
  title: ReactNode;
@@ -14,6 +17,8 @@ export declare const Notice: import("react").ForwardRefExoticComponent<Omit<HTML
14
17
  action?: ReactNode;
15
18
  icon?: ReactNode;
16
19
  tone?: NoticeTone;
20
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
21
+ layoutStyle?: HjmCompositionStyleProp;
17
22
  }> & import("react").RefAttributes<HTMLElement>>;
18
23
  type EmptyStateDensity = keyof typeof emptyStateRecipe.density;
19
24
  export type EmptyStateProps = Omit<HTMLAttributes<HTMLDivElement>, "title"> & Readonly<{
@@ -22,6 +27,8 @@ export type EmptyStateProps = Omit<HTMLAttributes<HTMLDivElement>, "title"> & Re
22
27
  action?: ReactNode;
23
28
  icon?: ReactNode;
24
29
  density?: EmptyStateDensity;
30
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
31
+ layoutStyle?: HjmCompositionStyleProp;
25
32
  }>;
26
33
  export declare const EmptyState: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "title"> & Readonly<{
27
34
  title: ReactNode;
@@ -29,11 +36,15 @@ export declare const EmptyState: import("react").ForwardRefExoticComponent<Omit<
29
36
  action?: ReactNode;
30
37
  icon?: ReactNode;
31
38
  density?: EmptyStateDensity;
39
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
40
+ layoutStyle?: HjmCompositionStyleProp;
32
41
  }> & import("react").RefAttributes<HTMLDivElement>>;
33
42
  export type ResultProps = Omit<HTMLAttributes<HTMLDivElement>, "children" | "title"> & ResultDescriptor & Readonly<{
34
43
  headingLevel?: 1 | 2;
35
44
  /** Optional product glyph; its meaning is already carried by title/status. */
36
45
  icon?: ReactNode;
46
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
47
+ layoutStyle?: HjmCompositionStyleProp;
37
48
  }>;
38
49
  /** A terminal flow outcome. EmptyState remains reserved for fillable content. */
39
50
  export declare const Result: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "title" | "children"> & Readonly<{
@@ -45,6 +56,8 @@ export declare const Result: import("react").ForwardRefExoticComponent<Omit<HTML
45
56
  headingLevel?: 1 | 2;
46
57
  /** Optional product glyph; its meaning is already carried by title/status. */
47
58
  icon?: ReactNode;
59
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
60
+ layoutStyle?: HjmCompositionStyleProp;
48
61
  }> & import("react").RefAttributes<HTMLDivElement>>;
49
62
  export type ProgressProps = Omit<ProgressHTMLAttributes<HTMLProgressElement>, "children" | "max" | "size" | "value"> & Readonly<{
50
63
  label: ReactNode;
@@ -61,8 +74,10 @@ export type ProgressProps = Omit<ProgressHTMLAttributes<HTMLProgressElement>, "c
61
74
  shape?: ProgressShape;
62
75
  /** Content inside the ring — a percentage, a count, an icon. Ignored when linear. */
63
76
  children?: ReactNode;
77
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
78
+ layoutStyle?: HjmCompositionStyleProp;
64
79
  }>;
65
- export declare const Progress: import("react").ForwardRefExoticComponent<Omit<ProgressHTMLAttributes<HTMLProgressElement>, "value" | "children" | "size" | "max"> & Readonly<{
80
+ export declare const Progress: import("react").ForwardRefExoticComponent<Omit<ProgressHTMLAttributes<HTMLProgressElement>, "value" | "size" | "children" | "max"> & Readonly<{
66
81
  label: ReactNode;
67
82
  value?: number;
68
83
  max?: number;
@@ -77,29 +92,25 @@ export declare const Progress: import("react").ForwardRefExoticComponent<Omit<Pr
77
92
  shape?: ProgressShape;
78
93
  /** Content inside the ring — a percentage, a count, an icon. Ignored when linear. */
79
94
  children?: ReactNode;
95
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
96
+ layoutStyle?: HjmCompositionStyleProp;
80
97
  }> & import("react").RefAttributes<HTMLProgressElement>>;
81
- export type SpinnerProps = HTMLAttributes<HTMLSpanElement> & Readonly<{
82
- label: string;
83
- size?: SpinnerSize;
84
- tone?: SpinnerTone;
85
- }>;
86
- export declare const Spinner: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLSpanElement> & Readonly<{
87
- label: string;
88
- size?: SpinnerSize;
89
- tone?: SpinnerTone;
90
- }> & import("react").RefAttributes<HTMLSpanElement>>;
98
+ export { Spinner, type SpinnerProps } from "./internal/spinner.js";
91
99
  type SkeletonShape = keyof typeof skeletonRecipe.shapes;
92
100
  export type SkeletonProps = Omit<HTMLAttributes<HTMLSpanElement>, "children"> & Readonly<{
93
101
  shape?: SkeletonShape;
94
102
  animated?: boolean;
95
103
  width?: string | number;
96
104
  height?: string | number;
105
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
106
+ layoutStyle?: HjmCompositionStyleProp;
97
107
  }>;
98
108
  export declare const Skeleton: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLSpanElement>, "children"> & Readonly<{
99
109
  shape?: SkeletonShape;
100
110
  animated?: boolean;
101
111
  width?: string | number;
102
112
  height?: string | number;
113
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
114
+ layoutStyle?: HjmCompositionStyleProp;
103
115
  }> & import("react").RefAttributes<HTMLSpanElement>>;
104
- export {};
105
116
  //# sourceMappingURL=feedback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.tsx"],"names":[],"mappings":"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"}
package/dist/feedback.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { emptyStateRecipe, noticeRecipe, progressRecipe, skeletonRecipe, spinnerRecipe, } from "@hjmds/design-contracts/recipes";
2
+ import { emptyStateRecipe, noticeRecipe, progressRecipe, skeletonRecipe, } from "@hjmds/design-contracts/recipes";
3
3
  import { resolveResultDescriptor, } from "@hjmds/design-contracts/components/result";
4
4
  import { forwardRef, } from "react";
5
5
  import { classNames } from "./internal.js";
6
6
  import { Button } from "./actions.js";
7
- export const Notice = forwardRef(function Notice({ title, description, action, icon, tone = noticeRecipe.defaults.tone, className, ...props }, ref) {
7
+ export const Notice = forwardRef(function Notice({ title, description, action, icon, tone = noticeRecipe.defaults.tone, className, layoutStyle, ...props }, ref) {
8
8
  const urgent = tone === "danger";
9
- return (_jsxs("section", { ...props, ref: ref, className: classNames("hjm-notice", className), "data-tone": tone, role: urgent ? "alert" : "status", "aria-live": urgent ? "assertive" : "polite", children: [icon ? _jsx("div", { className: "hjm-notice__icon", "aria-hidden": "true", children: icon }) : null, _jsxs("div", { className: "hjm-notice__content", children: [_jsx("strong", { className: "hjm-notice__title", children: title }), description ? _jsx("div", { className: "hjm-notice__description", children: description }) : null] }), action ? _jsx("div", { className: "hjm-notice__action", children: action }) : null] }));
9
+ return (_jsxs("section", { ...props, style: { ...props.style, ...layoutStyle }, ref: ref, className: classNames("hjm-notice", className), "data-tone": tone, role: urgent ? "alert" : "status", "aria-live": urgent ? "assertive" : "polite", children: [icon ? _jsx("div", { className: "hjm-notice__icon", "aria-hidden": "true", children: icon }) : null, _jsxs("div", { className: "hjm-notice__content", children: [_jsx("strong", { className: "hjm-notice__title", children: title }), description ? _jsx("div", { className: "hjm-notice__description", children: description }) : null] }), action ? _jsx("div", { className: "hjm-notice__action", children: action }) : null] }));
10
10
  });
11
- export const EmptyState = forwardRef(function EmptyState({ title, description, action, icon, density = emptyStateRecipe.defaults.density, className, ...props }, ref) {
12
- return (_jsxs("div", { ...props, ref: ref, className: classNames("hjm-empty-state", className), "data-density": density, role: "status", children: [icon ? _jsx("div", { className: "hjm-empty-state__icon", "aria-hidden": "true", children: icon }) : null, _jsx("strong", { className: "hjm-empty-state__title", children: title }), description ? _jsx("div", { className: "hjm-empty-state__description", children: description }) : null, action ? _jsx("div", { className: "hjm-empty-state__action", children: action }) : null] }));
11
+ export const EmptyState = forwardRef(function EmptyState({ title, description, action, icon, density = emptyStateRecipe.defaults.density, className, layoutStyle, ...props }, ref) {
12
+ return (_jsxs("div", { ...props, style: { ...props.style, ...layoutStyle }, ref: ref, className: classNames("hjm-empty-state", className), "data-density": density, role: "status", children: [icon ? _jsx("div", { className: "hjm-empty-state__icon", "aria-hidden": "true", children: icon }) : null, _jsx("strong", { className: "hjm-empty-state__title", children: title }), description ? _jsx("div", { className: "hjm-empty-state__description", children: description }) : null, action ? _jsx("div", { className: "hjm-empty-state__action", children: action }) : null] }));
13
13
  });
14
14
  /** A terminal flow outcome. EmptyState remains reserved for fillable content. */
15
- export const Result = forwardRef(function Result({ status, title, description, actions, headingLevel = 2, icon, className, role, ...props }, ref) {
15
+ export const Result = forwardRef(function Result({ status, title, description, actions, headingLevel = 2, icon, className, role, layoutStyle, ...props }, ref) {
16
16
  const result = resolveResultDescriptor({
17
17
  status,
18
18
  title,
@@ -20,9 +20,9 @@ export const Result = forwardRef(function Result({ status, title, description, a
20
20
  ...(actions === undefined ? {} : { actions }),
21
21
  });
22
22
  const Heading = headingLevel === 1 ? "h1" : "h2";
23
- return (_jsxs("div", { ...props, ref: ref, className: classNames("hjm-result", className), "data-status": result.status, role: role ?? (result.status === "failure" ? "alert" : "status"), children: [_jsx("span", { className: "hjm-result__icon", "aria-hidden": "true", children: icon }), _jsx(Heading, { className: "hjm-result__title", children: result.title }), result.description ? (_jsx("p", { className: "hjm-result__description", children: result.description })) : null, result.primaryAction || result.secondaryAction ? (_jsxs("div", { className: "hjm-result__actions", children: [result.primaryAction ? (_jsx(Button, { "aria-label": result.primaryAction.accessibilityLabel, onClick: result.primaryAction.onAction, children: result.primaryAction.label })) : null, result.secondaryAction ? (_jsx(Button, { "aria-label": result.secondaryAction.accessibilityLabel, onClick: result.secondaryAction.onAction, tone: "secondary", children: result.secondaryAction.label })) : null] })) : null] }));
23
+ return (_jsxs("div", { ...props, style: { ...props.style, ...layoutStyle }, ref: ref, className: classNames("hjm-result", className), "data-status": result.status, role: role ?? (result.status === "failure" ? "alert" : "status"), children: [_jsx("span", { className: "hjm-result__icon", "aria-hidden": "true", children: icon }), _jsx(Heading, { className: "hjm-result__title", children: result.title }), result.description ? (_jsx("p", { className: "hjm-result__description", children: result.description })) : null, result.primaryAction || result.secondaryAction ? (_jsxs("div", { className: "hjm-result__actions", children: [result.secondaryAction ? (_jsx(Button, { "aria-label": result.secondaryAction.accessibilityLabel, onClick: result.secondaryAction.onAction, tone: "secondary", children: result.secondaryAction.label })) : null, result.primaryAction ? (_jsx(Button, { "aria-label": result.primaryAction.accessibilityLabel, onClick: result.primaryAction.onAction, children: result.primaryAction.label })) : null] })) : null] }));
24
24
  });
25
- export const Progress = forwardRef(function Progress({ label, value, valueText, max = progressRecipe.defaults.max, size = progressRecipe.defaults.size, tone = progressRecipe.defaults.tone, shape = progressRecipe.defaults.shape, children, className, ...props }, ref) {
25
+ export const Progress = forwardRef(function Progress({ label, value, valueText, max = progressRecipe.defaults.max, size = progressRecipe.defaults.size, tone = progressRecipe.defaults.tone, shape = progressRecipe.defaults.shape, children, className, layoutStyle, ...props }, ref) {
26
26
  if (typeof max !== "number" || !Number.isFinite(max) || max <= 0) {
27
27
  throw new RangeError("Progress max must be a positive finite number");
28
28
  }
@@ -32,18 +32,20 @@ export const Progress = forwardRef(function Progress({ label, value, valueText,
32
32
  }
33
33
  const diameter = progressRecipe.circular.sizes[size];
34
34
  const strokeWidth = progressRecipe.circular.strokeWidth[size];
35
- return (_jsxs("div", { className: classNames("hjm-progress", className), "data-size": size, "data-tone": tone, "data-shape": shape, "data-state": value === undefined ? "indeterminate" : "determinate", style: shape === "circular" ? {
35
+ return (_jsxs("div", { className: classNames("hjm-progress", className), "data-size": size, "data-tone": tone, "data-shape": shape, "data-state": value === undefined ? "indeterminate" : "determinate",
36
+ // `layoutStyle` lands on this frame, not on the native <progress> that
37
+ // receives the rest props, so placement moves the label and bar together.
38
+ style: shape === "circular" ? {
39
+ ...layoutStyle,
36
40
  "--hjm-progress-diameter": `${diameter}px`,
37
41
  "--hjm-progress-stroke": `${strokeWidth}px`,
38
42
  // Conic sweep instead of an SVG arc: the same token drives both
39
43
  // shapes and no second color pipeline appears.
40
44
  "--hjm-progress-sweep": value === undefined ? "25%" : `${(value / max) * 100}%`,
41
- } : undefined, children: [_jsxs("span", { className: "hjm-progress__copy", children: [_jsx("span", { children: label }), valueText ? _jsx("span", { children: valueText }) : null] }), shape === "circular" ? (_jsx("span", { className: "hjm-progress__ring", "aria-hidden": "true", children: children ? _jsx("span", { className: "hjm-progress__ring-content", children: children }) : null })) : null, _jsx("progress", { ...props, ref: ref, className: "hjm-progress__native", max: max, ...(value === undefined ? {} : { value }), "aria-valuetext": typeof valueText === "string" ? valueText : undefined })] }));
45
+ } : layoutStyle, children: [_jsxs("span", { className: "hjm-progress__copy", children: [_jsx("span", { children: label }), valueText ? _jsx("span", { children: valueText }) : null] }), shape === "circular" ? (_jsx("span", { className: "hjm-progress__ring", "aria-hidden": "true", children: children ? _jsx("span", { className: "hjm-progress__ring-content", children: children }) : null })) : null, _jsx("progress", { ...props, ref: ref, className: "hjm-progress__native", max: max, ...(value === undefined ? {} : { value }), "aria-valuetext": typeof valueText === "string" ? valueText : undefined })] }));
42
46
  });
43
- export const Spinner = forwardRef(function Spinner({ label, size = spinnerRecipe.defaults.size, tone = spinnerRecipe.defaults.tone, className, ...props }, ref) {
44
- return (_jsxs("span", { ...props, ref: ref, className: classNames("hjm-spinner", className), "data-size": size, "data-tone": tone, role: "status", "aria-live": "polite", children: [_jsx("span", { className: "hjm-spinner__glyph", "aria-hidden": "true" }), _jsx("span", { className: "hjm-visually-hidden", children: label })] }));
45
- });
46
- export const Skeleton = forwardRef(function Skeleton({ shape = skeletonRecipe.defaults.shape, animated = skeletonRecipe.defaults.animated, width, height, className, style, ...props }, ref) {
47
- return (_jsx("span", { ...props, ref: ref, className: classNames("hjm-skeleton", className), "data-shape": shape, "data-animated": animated, "aria-hidden": "true", style: { width, height, ...style } }));
47
+ export { Spinner } from "./internal/spinner.js";
48
+ export const Skeleton = forwardRef(function Skeleton({ shape = skeletonRecipe.defaults.shape, animated = skeletonRecipe.defaults.animated, width, height, className, style, layoutStyle, ...props }, ref) {
49
+ return (_jsx("span", { ...props, ref: ref, className: classNames("hjm-skeleton", className), "data-shape": shape, "data-animated": animated, "aria-hidden": "true", style: { width, height, ...style, ...layoutStyle } }));
48
50
  });
49
51
  //# sourceMappingURL=feedback.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,aAAa,GAOd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,uBAAuB,GAExB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,UAAU,GAKX,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAetC,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAA2B,SAAS,MAAM,CACxE,EACE,KAAK,EACL,WAAW,EACX,MAAM,EACN,IAAI,EACJ,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,EACjC,SAAS,EACT,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,MAAM,GAAG,IAAI,KAAK,QAAQ,CAAC;IACjC,OAAO,CACL,sBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,YAAY,EAAE,SAAS,CAAC,eACnC,IAAI,EACf,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,eACtB,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,aAEzC,IAAI,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,kBAAkB,iBAAa,MAAM,YAAE,IAAI,GAAO,CAAC,CAAC,CAAC,IAAI,EAChF,eAAK,SAAS,EAAC,qBAAqB,aAClC,iBAAQ,SAAS,EAAC,mBAAmB,YAAE,KAAK,GAAU,EACrD,WAAW,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,yBAAyB,YAAE,WAAW,GAAO,CAAC,CAAC,CAAC,IAAI,IAC9E,EACL,MAAM,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,oBAAoB,YAAE,MAAM,GAAO,CAAC,CAAC,CAAC,IAAI,IAC3D,CACX,CAAC;AACJ,CAAC,CAAC,CAAC;AAaH,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAClC,SAAS,UAAU,CACjB,EACE,KAAK,EACL,WAAW,EACX,MAAM,EACN,IAAI,EACJ,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,OAAO,EAC3C,SAAS,EACT,GAAG,KAAK,EACT,EACD,GAAG;IAEH,OAAO,CACL,kBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,iBAAiB,EAAE,SAAS,CAAC,kBACrC,OAAO,EACrB,IAAI,EAAC,QAAQ,aAEZ,IAAI,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,uBAAuB,iBAAa,MAAM,YAAE,IAAI,GAAO,CAAC,CAAC,CAAC,IAAI,EACrF,iBAAQ,SAAS,EAAC,wBAAwB,YAAE,KAAK,GAAU,EAC1D,WAAW,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,8BAA8B,YAAE,WAAW,GAAO,CAAC,CAAC,CAAC,IAAI,EACtF,MAAM,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,yBAAyB,YAAE,MAAM,GAAO,CAAC,CAAC,CAAC,IAAI,IACpE,CACP,CAAC;AACJ,CAAC,CACF,CAAC;AAaF,iFAAiF;AACjF,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAA8B,SAAS,MAAM,CAC3E,EACE,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,YAAY,GAAG,CAAC,EAChB,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,MAAM,GAAG,uBAAuB,CAAC;QACrC,MAAM;QACN,KAAK;QACL,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QACrD,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;KAC9C,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAEjD,OAAO,CACL,kBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,YAAY,EAAE,SAAS,CAAC,iBACjC,MAAM,CAAC,MAAM,EAC1B,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,aAEhE,eAAM,SAAS,EAAC,kBAAkB,iBAAa,MAAM,YAClD,IAAI,GACA,EACP,KAAC,OAAO,IAAC,SAAS,EAAC,mBAAmB,YAAE,MAAM,CAAC,KAAK,GAAW,EAC9D,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CACpB,YAAG,SAAS,EAAC,yBAAyB,YAAE,MAAM,CAAC,WAAW,GAAK,CAChE,CAAC,CAAC,CAAC,IAAI,EACP,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAChD,eAAK,SAAS,EAAC,qBAAqB,aACjC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CACtB,KAAC,MAAM,kBACO,MAAM,CAAC,aAAa,CAAC,kBAAkB,EACnD,OAAO,EAAE,MAAM,CAAC,aAAa,CAAC,QAAQ,YAErC,MAAM,CAAC,aAAa,CAAC,KAAK,GACpB,CACV,CAAC,CAAC,CAAC,IAAI,EACP,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CACxB,KAAC,MAAM,kBACO,MAAM,CAAC,eAAe,CAAC,kBAAkB,EACrD,OAAO,EAAE,MAAM,CAAC,eAAe,CAAC,QAAQ,EACxC,IAAI,EAAC,WAAW,YAEf,MAAM,CAAC,eAAe,CAAC,KAAK,GACtB,CACV,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAuBH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,SAAS,QAAQ,CACf,EACE,KAAK,EACL,KAAK,EACL,SAAS,EACT,GAAG,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,EACjC,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,EACnC,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,EACnC,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,EACrC,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EACD,GAAG;IAEH,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,UAAU,CAAC,+CAA+C,CAAC,CAAC;IACxE,CAAC;IACD,IACE,KAAK,KAAK,SAAS;QACnB,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,GAAG,CAAC,EACrD,CAAC;QACD,MAAM,IAAI,UAAU,CAAC,6CAA6C,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9D,OAAO,CACL,eACE,SAAS,EAAE,UAAU,CAAC,cAAc,EAAE,SAAS,CAAC,eACrC,IAAI,eACJ,IAAI,gBACH,KAAK,gBACL,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa,EACjE,KAAK,EAAE,KAAK,KAAK,UAAU,CAAC,CAAC,CAAE;YAC7B,yBAAyB,EAAE,GAAG,QAAQ,IAAI;YAC1C,uBAAuB,EAAE,GAAG,WAAW,IAAI;YAC3C,gEAAgE;YAChE,+CAA+C;YAC/C,sBAAsB,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG;SAC9D,CAAC,CAAC,CAAC,SAAS,aAE/B,gBAAM,SAAS,EAAC,oBAAoB,aAClC,yBAAO,KAAK,GAAQ,EACnB,SAAS,CAAC,CAAC,CAAC,yBAAO,SAAS,GAAQ,CAAC,CAAC,CAAC,IAAI,IACvC,EACN,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CACtB,eAAM,SAAS,EAAC,oBAAoB,iBAAa,MAAM,YACpD,QAAQ,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,4BAA4B,YAAE,QAAQ,GAAQ,CAAC,CAAC,CAAC,IAAI,GAC5E,CACR,CAAC,CAAC,CAAC,IAAI,EACR,sBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAC,sBAAsB,EAChC,GAAG,EAAE,GAAG,KACJ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,oBAC1B,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GACrE,IACE,CACP,CAAC;AACJ,CAAC,CACF,CAAC;AASF,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAgC,SAAS,OAAO,CAC/E,EACE,KAAK,EACL,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAClC,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAClC,SAAS,EACT,GAAG,KAAK,EACT,EACD,GAAG;IAEH,OAAO,CACL,mBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,aAAa,EAAE,SAAS,CAAC,eACpC,IAAI,eACJ,IAAI,EACf,IAAI,EAAC,QAAQ,eACH,QAAQ,aAElB,eAAM,SAAS,EAAC,oBAAoB,iBAAa,MAAM,GAAG,EAC1D,eAAM,SAAS,EAAC,qBAAqB,YAAE,KAAK,GAAQ,IAC/C,CACR,CAAC;AACJ,CAAC,CAAC,CAAC;AAYH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,SAAS,QAAQ,CACf,EACE,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,EACrC,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,QAAQ,EAC3C,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EACD,GAAG;IAEH,OAAO,CACL,kBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,cAAc,EAAE,SAAS,CAAC,gBACpC,KAAK,mBACF,QAAQ,iBACX,MAAM,EAClB,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAClC,CACH,CAAC;AACJ,CAAC,CACF,CAAC","sourcesContent":["import {\n emptyStateRecipe,\n noticeRecipe,\n progressRecipe,\n skeletonRecipe,\n spinnerRecipe,\n type NoticeTone,\n type ProgressShape,\n type ProgressSize,\n type ProgressTone,\n type SpinnerSize,\n type SpinnerTone,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n resolveResultDescriptor,\n type ResultDescriptor,\n} from \"@hjmds/design-contracts/components/result\";\nimport {\n forwardRef,\n type HTMLAttributes,\n type ProgressHTMLAttributes,\n type ReactNode,\n type CSSProperties,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { Button } from \"./actions.js\";\n\n// The HTML `title` attribute (tooltip string) shares its name with the heading slot.\n// Left in the intersection, `string & ReactNode` collapses the slot to `string`, so\n// consumers had to cast heading elements (BurnTok, 2026-09-27 audit). Omit it like\n// Result/Card/Section already do.\nexport type NoticeProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n icon?: ReactNode;\n tone?: NoticeTone;\n }>;\n\nexport const Notice = forwardRef<HTMLElement, NoticeProps>(function Notice(\n {\n title,\n description,\n action,\n icon,\n tone = noticeRecipe.defaults.tone,\n className,\n ...props\n },\n ref,\n) {\n const urgent = tone === \"danger\";\n return (\n <section\n {...props}\n ref={ref}\n className={classNames(\"hjm-notice\", className)}\n data-tone={tone}\n role={urgent ? \"alert\" : \"status\"}\n aria-live={urgent ? \"assertive\" : \"polite\"}\n >\n {icon ? <div className=\"hjm-notice__icon\" aria-hidden=\"true\">{icon}</div> : null}\n <div className=\"hjm-notice__content\">\n <strong className=\"hjm-notice__title\">{title}</strong>\n {description ? <div className=\"hjm-notice__description\">{description}</div> : null}\n </div>\n {action ? <div className=\"hjm-notice__action\">{action}</div> : null}\n </section>\n );\n});\n\ntype EmptyStateDensity = keyof typeof emptyStateRecipe.density;\n\nexport type EmptyStateProps = Omit<HTMLAttributes<HTMLDivElement>, \"title\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n icon?: ReactNode;\n density?: EmptyStateDensity;\n }>;\n\nexport const EmptyState = forwardRef<HTMLDivElement, EmptyStateProps>(\n function EmptyState(\n {\n title,\n description,\n action,\n icon,\n density = emptyStateRecipe.defaults.density,\n className,\n ...props\n },\n ref,\n ) {\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-empty-state\", className)}\n data-density={density}\n role=\"status\"\n >\n {icon ? <div className=\"hjm-empty-state__icon\" aria-hidden=\"true\">{icon}</div> : null}\n <strong className=\"hjm-empty-state__title\">{title}</strong>\n {description ? <div className=\"hjm-empty-state__description\">{description}</div> : null}\n {action ? <div className=\"hjm-empty-state__action\">{action}</div> : null}\n </div>\n );\n },\n);\n\nexport type ResultProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n \"children\" | \"title\"\n> &\n ResultDescriptor &\n Readonly<{\n headingLevel?: 1 | 2;\n /** Optional product glyph; its meaning is already carried by title/status. */\n icon?: ReactNode;\n }>;\n\n/** A terminal flow outcome. EmptyState remains reserved for fillable content. */\nexport const Result = forwardRef<HTMLDivElement, ResultProps>(function Result(\n {\n status,\n title,\n description,\n actions,\n headingLevel = 2,\n icon,\n className,\n role,\n ...props\n },\n ref,\n) {\n const result = resolveResultDescriptor({\n status,\n title,\n ...(description === undefined ? {} : { description }),\n ...(actions === undefined ? {} : { actions }),\n });\n const Heading = headingLevel === 1 ? \"h1\" : \"h2\";\n\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-result\", className)}\n data-status={result.status}\n role={role ?? (result.status === \"failure\" ? \"alert\" : \"status\")}\n >\n <span className=\"hjm-result__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n <Heading className=\"hjm-result__title\">{result.title}</Heading>\n {result.description ? (\n <p className=\"hjm-result__description\">{result.description}</p>\n ) : null}\n {result.primaryAction || result.secondaryAction ? (\n <div className=\"hjm-result__actions\">\n {result.primaryAction ? (\n <Button\n aria-label={result.primaryAction.accessibilityLabel}\n onClick={result.primaryAction.onAction}\n >\n {result.primaryAction.label}\n </Button>\n ) : null}\n {result.secondaryAction ? (\n <Button\n aria-label={result.secondaryAction.accessibilityLabel}\n onClick={result.secondaryAction.onAction}\n tone=\"secondary\"\n >\n {result.secondaryAction.label}\n </Button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n});\n\nexport type ProgressProps = Omit<\n ProgressHTMLAttributes<HTMLProgressElement>,\n \"children\" | \"max\" | \"size\" | \"value\"\n> &\n Readonly<{\n label: ReactNode;\n value?: number;\n max?: number;\n valueText?: string;\n size?: ProgressSize;\n tone?: ProgressTone;\n /**\n * `circular` draws the same value as a ring. It is a shape, not a second\n * component: min/max/now, the indeterminate case and the announcement are\n * identical, so the accessibility contract stays in one place.\n */\n shape?: ProgressShape;\n /** Content inside the ring — a percentage, a count, an icon. Ignored when linear. */\n children?: ReactNode;\n }>;\n\nexport const Progress = forwardRef<HTMLProgressElement, ProgressProps>(\n function Progress(\n {\n label,\n value,\n valueText,\n max = progressRecipe.defaults.max,\n size = progressRecipe.defaults.size,\n tone = progressRecipe.defaults.tone,\n shape = progressRecipe.defaults.shape,\n children,\n className,\n ...props\n },\n ref,\n ) {\n if (typeof max !== \"number\" || !Number.isFinite(max) || max <= 0) {\n throw new RangeError(\"Progress max must be a positive finite number\");\n }\n if (\n value !== undefined &&\n (!Number.isFinite(value) || value < 0 || value > max)\n ) {\n throw new RangeError(\"Progress value must be between zero and max\");\n }\n const diameter = progressRecipe.circular.sizes[size];\n const strokeWidth = progressRecipe.circular.strokeWidth[size];\n return (\n <div\n className={classNames(\"hjm-progress\", className)}\n data-size={size}\n data-tone={tone}\n data-shape={shape}\n data-state={value === undefined ? \"indeterminate\" : \"determinate\"}\n style={shape === \"circular\" ? ({\n \"--hjm-progress-diameter\": `${diameter}px`,\n \"--hjm-progress-stroke\": `${strokeWidth}px`,\n // Conic sweep instead of an SVG arc: the same token drives both\n // shapes and no second color pipeline appears.\n \"--hjm-progress-sweep\": value === undefined ? \"25%\" : `${(value / max) * 100}%`,\n } as CSSProperties) : undefined}\n >\n <span className=\"hjm-progress__copy\">\n <span>{label}</span>\n {valueText ? <span>{valueText}</span> : null}\n </span>\n {shape === \"circular\" ? (\n <span className=\"hjm-progress__ring\" aria-hidden=\"true\">\n {children ? <span className=\"hjm-progress__ring-content\">{children}</span> : null}\n </span>\n ) : null}\n <progress\n {...props}\n ref={ref}\n className=\"hjm-progress__native\"\n max={max}\n {...(value === undefined ? {} : { value })}\n aria-valuetext={typeof valueText === \"string\" ? valueText : undefined}\n />\n </div>\n );\n },\n);\n\nexport type SpinnerProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{\n label: string;\n size?: SpinnerSize;\n tone?: SpinnerTone;\n }>;\n\nexport const Spinner = forwardRef<HTMLSpanElement, SpinnerProps>(function Spinner(\n {\n label,\n size = spinnerRecipe.defaults.size,\n tone = spinnerRecipe.defaults.tone,\n className,\n ...props\n },\n ref,\n) {\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-spinner\", className)}\n data-size={size}\n data-tone={tone}\n role=\"status\"\n aria-live=\"polite\"\n >\n <span className=\"hjm-spinner__glyph\" aria-hidden=\"true\" />\n <span className=\"hjm-visually-hidden\">{label}</span>\n </span>\n );\n});\n\ntype SkeletonShape = keyof typeof skeletonRecipe.shapes;\n\nexport type SkeletonProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n shape?: SkeletonShape;\n animated?: boolean;\n width?: string | number;\n height?: string | number;\n }>;\n\nexport const Skeleton = forwardRef<HTMLSpanElement, SkeletonProps>(\n function Skeleton(\n {\n shape = skeletonRecipe.defaults.shape,\n animated = skeletonRecipe.defaults.animated,\n width,\n height,\n className,\n style,\n ...props\n },\n ref,\n ) {\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-skeleton\", className)}\n data-shape={shape}\n data-animated={animated}\n aria-hidden=\"true\"\n style={{ width, height, ...style }}\n />\n );\n },\n);\n"]}
1
+ {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n emptyStateRecipe,\n noticeRecipe,\n progressRecipe,\n skeletonRecipe,\n type NoticeTone,\n type ProgressShape,\n type ProgressSize,\n type ProgressTone,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n resolveResultDescriptor,\n type ResultDescriptor,\n} from \"@hjmds/design-contracts/components/result\";\nimport {\n forwardRef,\n type HTMLAttributes,\n type ProgressHTMLAttributes,\n type ReactNode,\n type CSSProperties,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { Button } from \"./actions.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\n// The HTML `title` attribute (tooltip string) shares its name with the heading slot.\n// Left in the intersection, `string & ReactNode` collapses the slot to `string`, so\n// consumers had to cast heading elements (BurnTok, 2026-09-27 audit). Omit it like\n// Result/Card/Section already do.\nexport type NoticeProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n icon?: ReactNode;\n tone?: NoticeTone;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Notice = forwardRef<HTMLElement, NoticeProps>(function Notice(\n {\n title,\n description,\n action,\n icon,\n tone = noticeRecipe.defaults.tone,\n className,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const urgent = tone === \"danger\";\n return (\n <section\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-notice\", className)}\n data-tone={tone}\n role={urgent ? \"alert\" : \"status\"}\n aria-live={urgent ? \"assertive\" : \"polite\"}\n >\n {icon ? <div className=\"hjm-notice__icon\" aria-hidden=\"true\">{icon}</div> : null}\n <div className=\"hjm-notice__content\">\n <strong className=\"hjm-notice__title\">{title}</strong>\n {description ? <div className=\"hjm-notice__description\">{description}</div> : null}\n </div>\n {action ? <div className=\"hjm-notice__action\">{action}</div> : null}\n </section>\n );\n});\n\ntype EmptyStateDensity = keyof typeof emptyStateRecipe.density;\n\nexport type EmptyStateProps = Omit<HTMLAttributes<HTMLDivElement>, \"title\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n icon?: ReactNode;\n density?: EmptyStateDensity;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const EmptyState = forwardRef<HTMLDivElement, EmptyStateProps>(\n function EmptyState(\n {\n title,\n description,\n action,\n icon,\n density = emptyStateRecipe.defaults.density,\n className,\n layoutStyle,\n ...props\n },\n ref,\n ) {\n return (\n <div\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-empty-state\", className)}\n data-density={density}\n role=\"status\"\n >\n {icon ? <div className=\"hjm-empty-state__icon\" aria-hidden=\"true\">{icon}</div> : null}\n <strong className=\"hjm-empty-state__title\">{title}</strong>\n {description ? <div className=\"hjm-empty-state__description\">{description}</div> : null}\n {action ? <div className=\"hjm-empty-state__action\">{action}</div> : null}\n </div>\n );\n },\n);\n\nexport type ResultProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n \"children\" | \"title\"\n> &\n ResultDescriptor &\n Readonly<{\n headingLevel?: 1 | 2;\n /** Optional product glyph; its meaning is already carried by title/status. */\n icon?: ReactNode;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** A terminal flow outcome. EmptyState remains reserved for fillable content. */\nexport const Result = forwardRef<HTMLDivElement, ResultProps>(function Result(\n {\n status,\n title,\n description,\n actions,\n headingLevel = 2,\n icon,\n className,\n role,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const result = resolveResultDescriptor({\n status,\n title,\n ...(description === undefined ? {} : { description }),\n ...(actions === undefined ? {} : { actions }),\n });\n const Heading = headingLevel === 1 ? \"h1\" : \"h2\";\n\n return (\n <div\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-result\", className)}\n data-status={result.status}\n role={role ?? (result.status === \"failure\" ? \"alert\" : \"status\")}\n >\n <span className=\"hjm-result__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n <Heading className=\"hjm-result__title\">{result.title}</Heading>\n {result.description ? (\n <p className=\"hjm-result__description\">{result.description}</p>\n ) : null}\n {result.primaryAction || result.secondaryAction ? (\n <div className=\"hjm-result__actions\">\n {/* Button row rule (usage/components/button.md): secondary → primary, so the main action ends the row\n like Dialog footers. Until 2026-10-06 Result drew primary first, the reverse of every other action row. */}\n {result.secondaryAction ? (\n <Button\n aria-label={result.secondaryAction.accessibilityLabel}\n onClick={result.secondaryAction.onAction}\n tone=\"secondary\"\n >\n {result.secondaryAction.label}\n </Button>\n ) : null}\n {result.primaryAction ? (\n <Button\n aria-label={result.primaryAction.accessibilityLabel}\n onClick={result.primaryAction.onAction}\n >\n {result.primaryAction.label}\n </Button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n});\n\nexport type ProgressProps = Omit<\n ProgressHTMLAttributes<HTMLProgressElement>,\n \"children\" | \"max\" | \"size\" | \"value\"\n> &\n Readonly<{\n label: ReactNode;\n value?: number;\n max?: number;\n valueText?: string;\n size?: ProgressSize;\n tone?: ProgressTone;\n /**\n * `circular` draws the same value as a ring. It is a shape, not a second\n * component: min/max/now, the indeterminate case and the announcement are\n * identical, so the accessibility contract stays in one place.\n */\n shape?: ProgressShape;\n /** Content inside the ring — a percentage, a count, an icon. Ignored when linear. */\n children?: ReactNode;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Progress = forwardRef<HTMLProgressElement, ProgressProps>(\n function Progress(\n {\n label,\n value,\n valueText,\n max = progressRecipe.defaults.max,\n size = progressRecipe.defaults.size,\n tone = progressRecipe.defaults.tone,\n shape = progressRecipe.defaults.shape,\n children,\n className,\n layoutStyle,\n ...props\n },\n ref,\n ) {\n if (typeof max !== \"number\" || !Number.isFinite(max) || max <= 0) {\n throw new RangeError(\"Progress max must be a positive finite number\");\n }\n if (\n value !== undefined &&\n (!Number.isFinite(value) || value < 0 || value > max)\n ) {\n throw new RangeError(\"Progress value must be between zero and max\");\n }\n const diameter = progressRecipe.circular.sizes[size];\n const strokeWidth = progressRecipe.circular.strokeWidth[size];\n return (\n <div\n className={classNames(\"hjm-progress\", className)}\n data-size={size}\n data-tone={tone}\n data-shape={shape}\n data-state={value === undefined ? \"indeterminate\" : \"determinate\"}\n // `layoutStyle` lands on this frame, not on the native <progress> that\n // receives the rest props, so placement moves the label and bar together.\n style={shape === \"circular\" ? ({\n ...layoutStyle,\n \"--hjm-progress-diameter\": `${diameter}px`,\n \"--hjm-progress-stroke\": `${strokeWidth}px`,\n // Conic sweep instead of an SVG arc: the same token drives both\n // shapes and no second color pipeline appears.\n \"--hjm-progress-sweep\": value === undefined ? \"25%\" : `${(value / max) * 100}%`,\n } as CSSProperties) : layoutStyle}\n >\n <span className=\"hjm-progress__copy\">\n <span>{label}</span>\n {valueText ? <span>{valueText}</span> : null}\n </span>\n {shape === \"circular\" ? (\n <span className=\"hjm-progress__ring\" aria-hidden=\"true\">\n {children ? <span className=\"hjm-progress__ring-content\">{children}</span> : null}\n </span>\n ) : null}\n <progress\n {...props}\n ref={ref}\n className=\"hjm-progress__native\"\n max={max}\n {...(value === undefined ? {} : { value })}\n aria-valuetext={typeof valueText === \"string\" ? valueText : undefined}\n />\n </div>\n );\n },\n);\n\nexport { Spinner, type SpinnerProps } from \"./internal/spinner.js\";\n\ntype SkeletonShape = keyof typeof skeletonRecipe.shapes;\n\nexport type SkeletonProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n shape?: SkeletonShape;\n animated?: boolean;\n width?: string | number;\n height?: string | number;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Skeleton = forwardRef<HTMLSpanElement, SkeletonProps>(\n function Skeleton(\n {\n shape = skeletonRecipe.defaults.shape,\n animated = skeletonRecipe.defaults.animated,\n width,\n height,\n className,\n style,\n layoutStyle,\n ...props\n },\n ref,\n ) {\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-skeleton\", className)}\n data-shape={shape}\n data-animated={animated}\n aria-hidden=\"true\"\n style={{ width, height, ...style, ...layoutStyle }}\n />\n );\n },\n);\n"]}
@@ -1,5 +1,6 @@
1
1
  import { type FilePickerDescriptor, type FilePickerSelectionResult } from "@hjmds/design-contracts/components/file-picker";
2
2
  import { type HTMLAttributes, type ReactNode } from "react";
3
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
3
4
  export type FilePickerProps = Omit<HTMLAttributes<HTMLDivElement>, "children" | "onSelect"> & Readonly<{
4
5
  descriptor: FilePickerDescriptor;
5
6
  label: ReactNode;
@@ -12,6 +13,8 @@ export type FilePickerProps = Omit<HTMLAttributes<HTMLDivElement>, "children" |
12
13
  error?: ReactNode;
13
14
  inputId?: string;
14
15
  getCandidateId?: (file: File, index: number) => string;
16
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
17
+ layoutStyle?: HjmCompositionStyleProp;
15
18
  }>;
16
19
  /** Native file input plus an optional Web dropzone sharing one selection resolver. */
17
20
  export declare const FilePicker: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children" | "onSelect"> & Readonly<{
@@ -26,5 +29,7 @@ export declare const FilePicker: import("react").ForwardRefExoticComponent<Omit<
26
29
  error?: ReactNode;
27
30
  inputId?: string;
28
31
  getCandidateId?: (file: File, index: number) => string;
32
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
33
+ layoutStyle?: HjmCompositionStyleProp;
29
34
  }> & import("react").RefAttributes<HTMLDivElement>>;
30
35
  //# sourceMappingURL=file-picker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-picker.d.ts","sourceRoot":"","sources":["../src/file-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAOL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,GACzF,QAAQ,CAAC;IACP,UAAU,EAAE,oBAAoB,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,SAAS,CAAC;IACzB,QAAQ,EAAE,CAAC,MAAM,EAAE,yBAAyB,KAAK,IAAI,CAAC;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACxD,CAAC,CAAC;AAML,sFAAsF;AACtF,eAAO,MAAM,UAAU;gBAlBP,oBAAoB;WACzB,SAAS;iBACH,MAAM;mBACJ,SAAS;cACd,CAAC,MAAM,EAAE,yBAAyB,KAAK,IAAI;oBACrC,MAAM;eACX,OAAO;WACX,SAAS;YACR,SAAS;cACP,MAAM;qBACC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM;mDAwFxD,CAAC"}
1
+ {"version":3,"file":"file-picker.d.ts","sourceRoot":"","sources":["../src/file-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAOL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,GACzF,QAAQ,CAAC;IACP,UAAU,EAAE,oBAAoB,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,SAAS,CAAC;IACzB,QAAQ,EAAE,CAAC,MAAM,EAAE,yBAAyB,KAAK,IAAI,CAAC;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACvD,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAML,sFAAsF;AACtF,eAAO,MAAM,UAAU;gBApBP,oBAAoB;WACzB,SAAS;iBACH,MAAM;mBACJ,SAAS;cACd,CAAC,MAAM,EAAE,yBAAyB,KAAK,IAAI;oBACrC,MAAM;eACX,OAAO;WACX,SAAS;YACR,SAAS;cACP,MAAM;qBACC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM;IACtD,gGAAgG;kBAClF,uBAAuB;mDAyFvC,CAAC"}
@@ -6,7 +6,7 @@ function defaultCandidateId(file, index) {
6
6
  return `${file.name}:${file.size}:${file.lastModified}:${index}`;
7
7
  }
8
8
  /** Native file input plus an optional Web dropzone sharing one selection resolver. */
9
- export const FilePicker = forwardRef(function FilePicker({ descriptor, label, buttonLabel, dropzoneLabel, onSelect, existingCount = 0, disabled = false, hint, error, inputId, getCandidateId = defaultCandidateId, className, ...props }, ref) {
9
+ export const FilePicker = forwardRef(function FilePicker({ descriptor, label, buttonLabel, dropzoneLabel, onSelect, existingCount = 0, disabled = false, hint, error, inputId, getCandidateId = defaultCandidateId, className, layoutStyle, ...props }, ref) {
10
10
  validateFilePickerTriggers("web", filePickerTriggerDefaults.web);
11
11
  const resolved = resolveFilePickerDescriptor(descriptor);
12
12
  const generatedId = useId();
@@ -33,7 +33,7 @@ export const FilePicker = forwardRef(function FilePicker({ descriptor, label, bu
33
33
  if (!disabled && event.dataTransfer.files.length > 0)
34
34
  commit(event.dataTransfer.files);
35
35
  };
36
- return (_jsxs("div", { ...props, ref: composeRefs(ref), className: classNames("hjm-file-picker", className), "data-dragging": dragging || undefined, "data-invalid": error !== undefined || undefined, children: [_jsx("span", { className: "hjm-file-picker__label", id: `${id}-label`, children: label }), _jsx("input", { accept: resolved.accept?.join(","), "aria-labelledby": `${id}-label`, className: "hjm-visually-hidden", disabled: disabled, id: id, tabIndex: -1, multiple: resolved.mode === "multiple", onChange: handleChange, ref: inputRef, type: "file" }), _jsxs("div", { className: "hjm-file-picker__dropzone", onDragEnter: (event) => { event.preventDefault(); if (!disabled)
36
+ return (_jsxs("div", { ...props, style: { ...props.style, ...layoutStyle }, ref: composeRefs(ref), className: classNames("hjm-file-picker", className), "data-dragging": dragging || undefined, "data-invalid": error !== undefined || undefined, children: [_jsx("span", { className: "hjm-file-picker__label", id: `${id}-label`, children: label }), _jsx("input", { accept: resolved.accept?.join(","), "aria-labelledby": `${id}-label`, className: "hjm-visually-hidden", disabled: disabled, id: id, tabIndex: -1, multiple: resolved.mode === "multiple", onChange: handleChange, ref: inputRef, type: "file" }), _jsxs("div", { className: "hjm-file-picker__dropzone", onDragEnter: (event) => { event.preventDefault(); if (!disabled)
37
37
  setDragging(true); }, onDragLeave: (event) => { if (!event.currentTarget.contains(event.relatedTarget))
38
38
  setDragging(false); }, onDragOver: (event) => event.preventDefault(), onDrop: handleDrop, children: [_jsx("span", { children: dropzoneLabel }), _jsx("button", { disabled: disabled, onClick: () => inputRef.current?.click(), type: "button", children: buttonLabel })] }), hint === undefined ? null : _jsx("span", { className: "hjm-file-picker__hint", children: hint }), error === undefined ? null : _jsx("span", { className: "hjm-file-picker__error", role: "alert", children: error })] }));
39
39
  });
@@ -1 +1 @@
1
- {"version":3,"file":"file-picker.js","sourceRoot":"","sources":["../src/file-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n filePickerTriggerDefaults,\n resolveFilePickerDescriptor,\n resolveFilePickerSelection,\n validateFilePickerTriggers,\n type FilePickerCandidate,\n type FilePickerDescriptor,\n type FilePickerSelectionResult,\n} from \"@hjmds/design-contracts/components/file-picker\";\nimport {\n forwardRef,\n useId,\n useRef,\n useState,\n type ChangeEvent,\n type DragEvent,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\n\nimport { classNames, composeRefs } from \"./internal.js\";\n\nexport type FilePickerProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"onSelect\"> &\n Readonly<{\n descriptor: FilePickerDescriptor;\n label: ReactNode;\n buttonLabel: string;\n dropzoneLabel: ReactNode;\n onSelect: (result: FilePickerSelectionResult) => void;\n existingCount?: number;\n disabled?: boolean;\n hint?: ReactNode;\n error?: ReactNode;\n inputId?: string;\n getCandidateId?: (file: File, index: number) => string;\n }>;\n\nfunction defaultCandidateId(file: File, index: number): string {\n return `${file.name}:${file.size}:${file.lastModified}:${index}`;\n}\n\n/** Native file input plus an optional Web dropzone sharing one selection resolver. */\nexport const FilePicker = forwardRef<HTMLDivElement, FilePickerProps>(function FilePicker(\n {\n descriptor,\n label,\n buttonLabel,\n dropzoneLabel,\n onSelect,\n existingCount = 0,\n disabled = false,\n hint,\n error,\n inputId,\n getCandidateId = defaultCandidateId,\n className,\n ...props\n },\n ref,\n) {\n validateFilePickerTriggers(\"web\", filePickerTriggerDefaults.web);\n const resolved = resolveFilePickerDescriptor(descriptor);\n const generatedId = useId();\n const id = inputId ?? `hjm-file-${generatedId.replaceAll(\":\", \"\")}`;\n const inputRef = useRef<HTMLInputElement>(null);\n const [dragging, setDragging] = useState(false);\n\n const commit = (files: FileList | readonly File[]) => {\n const candidates: FilePickerCandidate[] = Array.from(files).map((file, index) => ({\n id: getCandidateId(file, index),\n name: file.name,\n mimeType: file.type,\n sizeBytes: file.size,\n }));\n onSelect(resolveFilePickerSelection(candidates, resolved, existingCount));\n };\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (event.currentTarget.files) commit(event.currentTarget.files);\n event.currentTarget.value = \"\";\n };\n const handleDrop = (event: DragEvent<HTMLDivElement>) => {\n event.preventDefault();\n setDragging(false);\n if (!disabled && event.dataTransfer.files.length > 0) commit(event.dataTransfer.files);\n };\n\n return (\n <div {...props} ref={composeRefs(ref)} className={classNames(\"hjm-file-picker\", className)} data-dragging={dragging || undefined} data-invalid={error !== undefined || undefined}>\n <span className=\"hjm-file-picker__label\" id={`${id}-label`}>{label}</span>\n {/*\n The visible button below is the keyboard entry point. Before 1.5.0 this\n hidden input was a second, unnamed tab stop (the label span was not\n associated with it), so a screen reader announced a nameless \"file\"\n control. It stays in the accessibility tree for virtual cursors, named\n by the label, and leaves the tab order.\n */}\n <input\n accept={resolved.accept?.join(\",\")}\n aria-labelledby={`${id}-label`}\n className=\"hjm-visually-hidden\"\n disabled={disabled}\n id={id}\n tabIndex={-1}\n multiple={resolved.mode === \"multiple\"}\n onChange={handleChange}\n ref={inputRef}\n type=\"file\"\n />\n <div\n className=\"hjm-file-picker__dropzone\"\n onDragEnter={(event) => { event.preventDefault(); if (!disabled) setDragging(true); }}\n onDragLeave={(event) => { if (!event.currentTarget.contains(event.relatedTarget as Node | null)) setDragging(false); }}\n onDragOver={(event) => event.preventDefault()}\n onDrop={handleDrop}\n >\n <span>{dropzoneLabel}</span>\n <button disabled={disabled} onClick={() => inputRef.current?.click()} type=\"button\">{buttonLabel}</button>\n </div>\n {hint === undefined ? null : <span className=\"hjm-file-picker__hint\">{hint}</span>}\n {error === undefined ? null : <span className=\"hjm-file-picker__error\" role=\"alert\">{error}</span>}\n </div>\n );\n});\n"]}
1
+ {"version":3,"file":"file-picker.js","sourceRoot":"","sources":["../src/file-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n filePickerTriggerDefaults,\n resolveFilePickerDescriptor,\n resolveFilePickerSelection,\n validateFilePickerTriggers,\n type FilePickerCandidate,\n type FilePickerDescriptor,\n type FilePickerSelectionResult,\n} from \"@hjmds/design-contracts/components/file-picker\";\nimport {\n forwardRef,\n useId,\n useRef,\n useState,\n type ChangeEvent,\n type DragEvent,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\n\nimport { classNames, composeRefs } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type FilePickerProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"onSelect\"> &\n Readonly<{\n descriptor: FilePickerDescriptor;\n label: ReactNode;\n buttonLabel: string;\n dropzoneLabel: ReactNode;\n onSelect: (result: FilePickerSelectionResult) => void;\n existingCount?: number;\n disabled?: boolean;\n hint?: ReactNode;\n error?: ReactNode;\n inputId?: string;\n getCandidateId?: (file: File, index: number) => string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nfunction defaultCandidateId(file: File, index: number): string {\n return `${file.name}:${file.size}:${file.lastModified}:${index}`;\n}\n\n/** Native file input plus an optional Web dropzone sharing one selection resolver. */\nexport const FilePicker = forwardRef<HTMLDivElement, FilePickerProps>(function FilePicker(\n {\n descriptor,\n label,\n buttonLabel,\n dropzoneLabel,\n onSelect,\n existingCount = 0,\n disabled = false,\n hint,\n error,\n inputId,\n getCandidateId = defaultCandidateId,\n className,\n layoutStyle,\n ...props\n },\n ref,\n) {\n validateFilePickerTriggers(\"web\", filePickerTriggerDefaults.web);\n const resolved = resolveFilePickerDescriptor(descriptor);\n const generatedId = useId();\n const id = inputId ?? `hjm-file-${generatedId.replaceAll(\":\", \"\")}`;\n const inputRef = useRef<HTMLInputElement>(null);\n const [dragging, setDragging] = useState(false);\n\n const commit = (files: FileList | readonly File[]) => {\n const candidates: FilePickerCandidate[] = Array.from(files).map((file, index) => ({\n id: getCandidateId(file, index),\n name: file.name,\n mimeType: file.type,\n sizeBytes: file.size,\n }));\n onSelect(resolveFilePickerSelection(candidates, resolved, existingCount));\n };\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (event.currentTarget.files) commit(event.currentTarget.files);\n event.currentTarget.value = \"\";\n };\n const handleDrop = (event: DragEvent<HTMLDivElement>) => {\n event.preventDefault();\n setDragging(false);\n if (!disabled && event.dataTransfer.files.length > 0) commit(event.dataTransfer.files);\n };\n\n return (\n <div {...props} style={{ ...props.style, ...layoutStyle }} ref={composeRefs(ref)} className={classNames(\"hjm-file-picker\", className)} data-dragging={dragging || undefined} data-invalid={error !== undefined || undefined}>\n <span className=\"hjm-file-picker__label\" id={`${id}-label`}>{label}</span>\n {/*\n The visible button below is the keyboard entry point. Before 1.5.0 this\n hidden input was a second, unnamed tab stop (the label span was not\n associated with it), so a screen reader announced a nameless \"file\"\n control. It stays in the accessibility tree for virtual cursors, named\n by the label, and leaves the tab order.\n */}\n <input\n accept={resolved.accept?.join(\",\")}\n aria-labelledby={`${id}-label`}\n className=\"hjm-visually-hidden\"\n disabled={disabled}\n id={id}\n tabIndex={-1}\n multiple={resolved.mode === \"multiple\"}\n onChange={handleChange}\n ref={inputRef}\n type=\"file\"\n />\n <div\n className=\"hjm-file-picker__dropzone\"\n onDragEnter={(event) => { event.preventDefault(); if (!disabled) setDragging(true); }}\n onDragLeave={(event) => { if (!event.currentTarget.contains(event.relatedTarget as Node | null)) setDragging(false); }}\n onDragOver={(event) => event.preventDefault()}\n onDrop={handleDrop}\n >\n <span>{dropzoneLabel}</span>\n <button disabled={disabled} onClick={() => inputRef.current?.click()} type=\"button\">{buttonLabel}</button>\n </div>\n {hint === undefined ? null : <span className=\"hjm-file-picker__hint\">{hint}</span>}\n {error === undefined ? null : <span className=\"hjm-file-picker__error\" role=\"alert\">{error}</span>}\n </div>\n );\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"floating-action-button.d.ts","sourceRoot":"","sources":["../src/floating-action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACpG,OAAO,EAEkC,2CAA2C,EAClF,KAAK,8BAA8B,EAAE,KAAK,8BAA8B,EACzE,MAAM,2DAA2D,CAAC;AAEnE,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAIxD,OAAO,EAAE,2CAA2C,EAAE,CAAC;AACvD,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,IAAI,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC;IAC1H,UAAU,EAAE,8BAA8B,CAAC;IAC3C,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,IAAI,CAAA;KAAE,CAAC,KAAK,SAAS,CAAC;IAC3G,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qFAAqF;IACrF,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD,CAAC,CAAC;AAEH,uEAAuE;AACvE,eAAO,MAAM,oBAAoB;gBARnB,8BAA8B;gBAC9B,CAAC,IAAI,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,IAAI,CAAA;KAAE,CAAC,KAAK,SAAS;0BACpF,MAAM;IAC5B,qFAAqF;8BAC3D,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI;sDAiCrD,CAAC;AAEH,yFAAyF;AACzF,wBAAgB,6BAA6B,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,8BAA8B,CAmBzG"}
1
+ {"version":3,"file":"floating-action-button.d.ts","sourceRoot":"","sources":["../src/floating-action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACpG,OAAO,EAEkC,2CAA2C,EAClF,KAAK,8BAA8B,EAAE,KAAK,8BAA8B,EACzE,MAAM,2DAA2D,CAAC;AAEnE,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAIxD,OAAO,EAAE,2CAA2C,EAAE,CAAC;AAEvD,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,IAAI,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC;IAC1H,UAAU,EAAE,8BAA8B,CAAC;IAC3C,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,IAAI,CAAA;KAAE,CAAC,KAAK,SAAS,CAAC;IAC3G,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qFAAqF;IACrF,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD,CAAC,CAAC;AAEH,uEAAuE;AACvE,eAAO,MAAM,oBAAoB;gBARnB,8BAA8B;gBAC9B,CAAC,IAAI,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,IAAI,CAAA;KAAE,CAAC,KAAK,SAAS;0BACpF,MAAM;IAC5B,qFAAqF;8BAC3D,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI;sDAiCrD,CAAC;AAEH,yFAAyF;AACzF,wBAAgB,6BAA6B,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,8BAA8B,CAmBzG"}
@@ -1 +1 @@
1
- {"version":3,"file":"floating-action-button.js","sourceRoot":"","sources":["../src/floating-action-button.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef, useEffect, useRef, useState, type CSSProperties, type ReactNode } from \"react\";\nimport {\n floatingActionButtonRecipe as recipe, resolveFloatingActionButtonDescriptor,\n resolveFloatingActionButtonLayoutMode, resolveFloatingActionButtonContentClearance,\n type FloatingActionButtonDescriptor, type FloatingActionButtonLayoutMode,\n} from \"@hjmds/design-contracts/components/floating-action-button\";\nimport { glyph, easing } from \"@hjmds/design-contracts/foundations\";\nimport { Button, type ButtonProps } from \"./actions.js\";\nimport { assignRef, classNames } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\n\nexport { resolveFloatingActionButtonContentClearance };\nexport type FloatingActionButtonProps = Pick<ButtonProps, \"onClick\" | \"onFocus\" | \"onBlur\" | \"id\" | \"className\"> & Readonly<{\n descriptor: FloatingActionButtonDescriptor;\n renderIcon: (icon: Readonly<{ name: string; size: number; color: string; decorative: true }>) => ReactNode;\n safeAreaBottomInset?: number;\n /** Apply this to the scroll content's bottom padding, including multiline labels. */\n onContentClearanceChange: (clearance: number) => void;\n}>;\n\n/** One persistent button preserves focus while its label collapses. */\nexport const FloatingActionButton = forwardRef<HTMLButtonElement, FloatingActionButtonProps>(function FloatingActionButton({\n descriptor, renderIcon, safeAreaBottomInset = 0, onContentClearanceChange, className, ...props\n}, forwardedRef) {\n const resolved = resolveFloatingActionButtonDescriptor(descriptor);\n const theme = useOptionalHjmTheme();\n const minimumClearance = resolveFloatingActionButtonContentClearance(safeAreaBottomInset);\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n useEffect(() => {\n const button = buttonRef.current;\n if (!button) return;\n const measure = () => {\n const bottom = parseFloat(getComputedStyle(button).bottom);\n onContentClearanceChange(Math.max(minimumClearance, button.getBoundingClientRect().height\n + (Number.isFinite(bottom) ? bottom : recipe.margin + safeAreaBottomInset) + recipe.margin));\n };\n measure(); const observer = new ResizeObserver(measure); observer.observe(button);\n window.addEventListener(\"resize\", measure);\n return () => { observer.disconnect(); window.removeEventListener(\"resize\", measure); };\n }, [minimumClearance, safeAreaBottomInset, onContentClearanceChange]);\n return <Button {...props} ref={(node) => { buttonRef.current = node; assignRef(forwardedRef, node); }}\n className={classNames(\"hjm-fab\", className)} size=\"large\" tone=\"primary\" shape=\"pill\"\n data-mode={resolved.layoutMode} data-direction={theme?.environment.direction ?? \"ltr\"} data-reduced-motion={theme?.environment.reducedMotion ?? false} aria-label={resolved.resolvedAccessibilityLabel}\n style={{ \"--hjm-fab-diameter\": `${recipe.circle.diameter}px`, \"--hjm-fab-margin\": `${recipe.margin}px`,\n \"--hjm-fab-safe-area\": `${safeAreaBottomInset}px`, \"--hjm-fab-duration\": `${recipe.transition.duration}ms`,\n \"--hjm-fab-easing\": `cubic-bezier(${easing[recipe.transition.easing].join(\",\")})`,\n boxShadow: `0 ${recipe.shadow.offsetY}px ${recipe.shadow.radius}px color-mix(in srgb, ${recipe.shadow.color} ${recipe.shadow.opacity * 100}%, transparent)` } as CSSProperties}\n leading={<span aria-hidden=\"true\" className=\"hjm-fab__icon\">{renderIcon({ name: resolved.icon.name, size: glyph[recipe.circle.glyph], color: \"currentColor\", decorative: true })}</span>}>\n {resolved.label}\n </Button>;\n});\n\n/** Omit target for window scrolling; null waits for a custom scroll element to mount. */\nexport function useFloatingActionButtonScroll(target?: HTMLElement | null): FloatingActionButtonLayoutMode {\n const [layoutMode, setLayoutMode] = useState<FloatingActionButtonLayoutMode>(\"expanded\");\n useEffect(() => {\n if (target === null) return;\n const source = target ?? window;\n let anchor = target?.scrollTop ?? window.scrollY;\n const onScroll = () => {\n const offset = Math.max(0, target?.scrollTop ?? window.scrollY);\n const delta = offset - anchor;\n // Half the edge margin ignores tiny trackpad tremors, but accumulates small\n // deltas until direction is clear instead of resetting on every frame.\n if (offset > 0 && Math.abs(delta) < recipe.margin / 2) return;\n anchor = offset;\n setLayoutMode((mode) => resolveFloatingActionButtonLayoutMode(offset === 0 || delta < 0 ? \"toward-start\" : \"away-from-start\", mode));\n };\n source.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => source.removeEventListener(\"scroll\", onScroll);\n }, [target]);\n return layoutMode;\n}\n"]}
1
+ {"version":3,"file":"floating-action-button.js","sourceRoot":"","sources":["../src/floating-action-button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAsC,MAAM,OAAO,CAAC;AACpG,OAAO,EACL,0BAA0B,IAAI,MAAM,EAAE,qCAAqC,EAC3E,qCAAqC,EAAE,2CAA2C,GAEnF,MAAM,2DAA2D,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAoB,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,2CAA2C,EAAE,CAAC;AAUvD,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAA+C,SAAS,oBAAoB,CAAC,EACzH,UAAU,EAAE,UAAU,EAAE,mBAAmB,GAAG,CAAC,EAAE,wBAAwB,EAAE,SAAS,EAAE,GAAG,KAAK,EAC/F,EAAE,YAAY;IACb,MAAM,QAAQ,GAAG,qCAAqC,CAAC,UAAU,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,mBAAmB,EAAE,CAAC;IACpC,MAAM,gBAAgB,GAAG,2CAA2C,CAAC,mBAAmB,CAAC,CAAC;IAC1F,MAAM,SAAS,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;IACzD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;QACjC,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,MAAM,MAAM,GAAG,UAAU,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;YAC3D,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,qBAAqB,EAAE,CAAC,MAAM;kBACrF,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,mBAAmB,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACjG,CAAC,CAAC;QACF,OAAO,EAAE,CAAC;QAAC,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClF,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC3C,OAAO,GAAG,EAAE,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACzF,CAAC,EAAE,CAAC,gBAAgB,EAAE,mBAAmB,EAAE,wBAAwB,CAAC,CAAC,CAAC;IACtE,OAAO,KAAC,MAAM,OAAK,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EACnG,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,IAAI,EAAC,OAAO,EAAC,IAAI,EAAC,SAAS,EAAC,KAAK,EAAC,MAAM,eAC1E,QAAQ,CAAC,UAAU,oBAAkB,KAAK,EAAE,WAAW,CAAC,SAAS,IAAI,KAAK,yBAAuB,KAAK,EAAE,WAAW,CAAC,aAAa,IAAI,KAAK,gBAAc,QAAQ,CAAC,0BAA0B,EACtM,KAAK,EAAE,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI;YACpG,qBAAqB,EAAE,GAAG,mBAAmB,IAAI,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,IAAI;YAC1G,kBAAkB,EAAE,gBAAgB,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG;YACjF,SAAS,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,yBAAyB,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,iBAAiB,EAAmB,EAChL,OAAO,EAAE,8BAAkB,MAAM,EAAC,SAAS,EAAC,eAAe,YAAE,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,GAAQ,YACvL,QAAQ,CAAC,KAAK,GACR,CAAC;AACZ,CAAC,CAAC,CAAC;AAEH,yFAAyF;AACzF,MAAM,UAAU,6BAA6B,CAAC,MAA2B;IACvE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAiC,UAAU,CAAC,CAAC;IACzF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAC5B,MAAM,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC;QAChC,IAAI,MAAM,GAAG,MAAM,EAAE,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC;QACjD,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;YAChE,MAAM,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;YAC9B,4EAA4E;YAC5E,uEAAuE;YACvE,IAAI,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO;YAC9D,MAAM,GAAG,MAAM,CAAC;YAChB,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qCAAqC,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC;QACvI,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACb,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import { forwardRef, useEffect, useRef, useState, type CSSProperties, type ReactNode } from \"react\";\nimport {\n floatingActionButtonRecipe as recipe, resolveFloatingActionButtonDescriptor,\n resolveFloatingActionButtonLayoutMode, resolveFloatingActionButtonContentClearance,\n type FloatingActionButtonDescriptor, type FloatingActionButtonLayoutMode,\n} from \"@hjmds/design-contracts/components/floating-action-button\";\nimport { glyph, easing } from \"@hjmds/design-contracts/foundations\";\nimport { Button, type ButtonProps } from \"./actions.js\";\nimport { assignRef, classNames } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\n\nexport { resolveFloatingActionButtonContentClearance };\n// No `layoutStyle`: fixed to the viewport corner with safe-area and content-clearance math the recipe owns; margins would desync `onContentClearanceChange`.\nexport type FloatingActionButtonProps = Pick<ButtonProps, \"onClick\" | \"onFocus\" | \"onBlur\" | \"id\" | \"className\"> & Readonly<{\n descriptor: FloatingActionButtonDescriptor;\n renderIcon: (icon: Readonly<{ name: string; size: number; color: string; decorative: true }>) => ReactNode;\n safeAreaBottomInset?: number;\n /** Apply this to the scroll content's bottom padding, including multiline labels. */\n onContentClearanceChange: (clearance: number) => void;\n}>;\n\n/** One persistent button preserves focus while its label collapses. */\nexport const FloatingActionButton = forwardRef<HTMLButtonElement, FloatingActionButtonProps>(function FloatingActionButton({\n descriptor, renderIcon, safeAreaBottomInset = 0, onContentClearanceChange, className, ...props\n}, forwardedRef) {\n const resolved = resolveFloatingActionButtonDescriptor(descriptor);\n const theme = useOptionalHjmTheme();\n const minimumClearance = resolveFloatingActionButtonContentClearance(safeAreaBottomInset);\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n useEffect(() => {\n const button = buttonRef.current;\n if (!button) return;\n const measure = () => {\n const bottom = parseFloat(getComputedStyle(button).bottom);\n onContentClearanceChange(Math.max(minimumClearance, button.getBoundingClientRect().height\n + (Number.isFinite(bottom) ? bottom : recipe.margin + safeAreaBottomInset) + recipe.margin));\n };\n measure(); const observer = new ResizeObserver(measure); observer.observe(button);\n window.addEventListener(\"resize\", measure);\n return () => { observer.disconnect(); window.removeEventListener(\"resize\", measure); };\n }, [minimumClearance, safeAreaBottomInset, onContentClearanceChange]);\n return <Button {...props} ref={(node) => { buttonRef.current = node; assignRef(forwardedRef, node); }}\n className={classNames(\"hjm-fab\", className)} size=\"large\" tone=\"primary\" shape=\"pill\"\n data-mode={resolved.layoutMode} data-direction={theme?.environment.direction ?? \"ltr\"} data-reduced-motion={theme?.environment.reducedMotion ?? false} aria-label={resolved.resolvedAccessibilityLabel}\n style={{ \"--hjm-fab-diameter\": `${recipe.circle.diameter}px`, \"--hjm-fab-margin\": `${recipe.margin}px`,\n \"--hjm-fab-safe-area\": `${safeAreaBottomInset}px`, \"--hjm-fab-duration\": `${recipe.transition.duration}ms`,\n \"--hjm-fab-easing\": `cubic-bezier(${easing[recipe.transition.easing].join(\",\")})`,\n boxShadow: `0 ${recipe.shadow.offsetY}px ${recipe.shadow.radius}px color-mix(in srgb, ${recipe.shadow.color} ${recipe.shadow.opacity * 100}%, transparent)` } as CSSProperties}\n leading={<span aria-hidden=\"true\" className=\"hjm-fab__icon\">{renderIcon({ name: resolved.icon.name, size: glyph[recipe.circle.glyph], color: \"currentColor\", decorative: true })}</span>}>\n {resolved.label}\n </Button>;\n});\n\n/** Omit target for window scrolling; null waits for a custom scroll element to mount. */\nexport function useFloatingActionButtonScroll(target?: HTMLElement | null): FloatingActionButtonLayoutMode {\n const [layoutMode, setLayoutMode] = useState<FloatingActionButtonLayoutMode>(\"expanded\");\n useEffect(() => {\n if (target === null) return;\n const source = target ?? window;\n let anchor = target?.scrollTop ?? window.scrollY;\n const onScroll = () => {\n const offset = Math.max(0, target?.scrollTop ?? window.scrollY);\n const delta = offset - anchor;\n // Half the edge margin ignores tiny trackpad tremors, but accumulates small\n // deltas until direction is clear instead of resetting on every frame.\n if (offset > 0 && Math.abs(delta) < recipe.margin / 2) return;\n anchor = offset;\n setLayoutMode((mode) => resolveFloatingActionButtonLayoutMode(offset === 0 || delta < 0 ? \"toward-start\" : \"away-from-start\", mode));\n };\n source.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => source.removeEventListener(\"scroll\", onScroll);\n }, [target]);\n return layoutMode;\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 FolderPreviewProps = Readonly<{
3
4
  label: string;
4
5
  open: boolean;
@@ -6,7 +7,9 @@ export type FolderPreviewProps = Readonly<{
6
7
  previews: readonly ReactNode[];
7
8
  children: ReactNode;
8
9
  disabled?: boolean;
10
+ /** Canonical layout-only placement on the root Collapsible. Controlled visual keys are excluded. */
11
+ layoutStyle?: HjmCompositionStyleProp;
9
12
  }>;
10
13
  /** Preview slots are decorative snapshots; expanded children own real actions and accessible content. */
11
- export declare function FolderPreview({ label, open, onOpenChange, previews, children, disabled }: FolderPreviewProps): import("react").JSX.Element;
14
+ export declare function FolderPreview({ label, open, onOpenChange, previews, children, disabled, layoutStyle }: FolderPreviewProps): import("react").JSX.Element;
12
15
  //# sourceMappingURL=folder-preview.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"folder-preview.d.ts","sourceRoot":"","sources":["../src/folder-preview.tsx"],"names":[],"mappings":"AACA,OAAO,KAAI,EAAC,SAAS,EAAC,MAAI,OAAO,CAAC;AAClC,MAAM,MAAM,kBAAkB,GAAC,QAAQ,CAAC;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,IAAI,EAAC,OAAO,CAAC;IAAA,YAAY,EAAC,CAAC,IAAI,EAAC,OAAO,KAAG,IAAI,CAAC;IAAA,QAAQ,EAAC,SAAS,SAAS,EAAE,CAAC;IAAA,QAAQ,EAAC,SAAS,CAAC;IAAA,QAAQ,CAAC,EAAC,OAAO,CAAA;CAAC,CAAC,CAAC;AAC1K,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,EAAC,KAAK,EAAC,IAAI,EAAC,YAAY,EAAC,QAAQ,EAAC,QAAQ,EAAC,QAAc,EAAC,EAAC,kBAAkB,+BAA+nC"}
1
+ {"version":3,"file":"folder-preview.d.ts","sourceRoot":"","sources":["../src/folder-preview.tsx"],"names":[],"mappings":"AACA,OAAO,KAAI,EAAC,SAAS,EAAC,MAAI,OAAO,CAAC;AAClC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAC,QAAQ,CAAC;IAAC,KAAK,EAAC,MAAM,CAAC;IAAA,IAAI,EAAC,OAAO,CAAC;IAAA,YAAY,EAAC,CAAC,IAAI,EAAC,OAAO,KAAG,IAAI,CAAC;IAAA,QAAQ,EAAC,SAAS,SAAS,EAAE,CAAC;IAAA,QAAQ,EAAC,SAAS,CAAC;IAAA,QAAQ,CAAC,EAAC,OAAO,CAAC;IACvK,oGAAoG;IACpG,WAAW,CAAC,EAAC,uBAAuB,CAAA;CAAC,CAAC,CAAC;AACxC,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,EAAC,KAAK,EAAC,IAAI,EAAC,YAAY,EAAC,QAAQ,EAAC,QAAQ,EAAC,QAAc,EAAC,WAAW,EAAC,EAAC,kBAAkB,+BAA+qC"}
@@ -2,6 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Collapsible } from './collapsible.js';
3
3
  import { useHjmTheme } from './provider.js';
4
4
  /** Preview slots are decorative snapshots; expanded children own real actions and accessible content. */
5
- export function FolderPreview({ label, open, onOpenChange, previews, children, disabled = false }) { const { environment } = useHjmTheme(); if (!label.trim())
6
- throw new TypeError('Folder needs a label'); return _jsx(Collapsible, { open: open, onOpenChange: onOpenChange, disabled: disabled, trigger: _jsxs("div", { style: { width: '100%', minWidth: 0 }, children: [_jsxs("div", { inert: true, "aria-hidden": "true", style: { position: 'relative', height: 160, marginInline: 'auto', maxWidth: 260, pointerEvents: 'none' }, children: [previews.slice(0, 3).map((preview, index) => _jsx("div", { style: { position: 'absolute', insetInlineStart: '20%', top: 24 + index * 8, width: '60%', height: 104, overflow: 'hidden', borderRadius: 'var(--hjm-radius-md)', background: 'var(--hjm-color-surface-alt)', border: '1px solid var(--hjm-color-border)', transform: `translateX(${(index - 1) * (open ? 34 : 10)}px) rotate(${(index - 1) * (open ? 12 : 4)}deg)`, transition: environment.reducedMotion ? 'none' : 'transform 200ms ease-out' }, children: preview }, index)), _jsx("div", { style: { position: 'absolute', bottom: 0, insetInline: 0, height: 56, borderRadius: 'var(--hjm-radius-lg)', background: 'var(--hjm-color-surface-accent)', border: '1px solid var(--hjm-color-border)', transformOrigin: 'bottom', transform: open ? 'perspective(400px) rotateX(-15deg)' : 'none' } })] }), _jsx("span", { children: label })] }), children: children }); }
5
+ export function FolderPreview({ label, open, onOpenChange, previews, children, disabled = false, layoutStyle }) { const { environment } = useHjmTheme(); if (!label.trim())
6
+ throw new TypeError('Folder needs a label'); return _jsx(Collapsible, { open: open, onOpenChange: onOpenChange, disabled: disabled, ...(layoutStyle === undefined ? {} : { layoutStyle }), trigger: _jsxs("div", { style: { width: '100%', minWidth: 0 }, children: [_jsxs("div", { inert: true, "aria-hidden": "true", style: { position: 'relative', height: 160, marginInline: 'auto', maxWidth: 260, pointerEvents: 'none' }, children: [previews.slice(0, 3).map((preview, index) => _jsx("div", { style: { position: 'absolute', insetInlineStart: '20%', top: 24 + index * 8, width: '60%', height: 104, overflow: 'hidden', borderRadius: 'var(--hjm-radius-md)', background: 'var(--hjm-color-surface-alt)', border: '1px solid var(--hjm-color-border)', transform: `translateX(${(index - 1) * (open ? 34 : 10)}px) rotate(${(index - 1) * (open ? 12 : 4)}deg)`, transition: environment.reducedMotion ? 'none' : 'transform 200ms ease-out' }, children: preview }, index)), _jsx("div", { style: { position: 'absolute', bottom: 0, insetInline: 0, height: 56, borderRadius: 'var(--hjm-radius-lg)', background: 'var(--hjm-color-surface-accent)', border: '1px solid var(--hjm-color-border)', transformOrigin: 'bottom', transform: open ? 'perspective(400px) rotateX(-15deg)' : 'none' } })] }), _jsx("span", { children: label })] }), children: children }); }
7
7
  //# sourceMappingURL=folder-preview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"folder-preview.js","sourceRoot":"","sources":["../src/folder-preview.tsx"],"names":[],"mappings":";AACkC,OAAM,EAAC,WAAW,EAAC,MAAI,kBAAkB,CAAC;AAAA,OAAM,EAAC,WAAW,EAAC,MAAI,eAAe,CAAC;AAEnH,yGAAyG;AACzG,MAAM,UAAU,aAAa,CAAC,EAAC,KAAK,EAAC,IAAI,EAAC,YAAY,EAAC,QAAQ,EAAC,QAAQ,EAAC,QAAQ,GAAC,KAAK,EAAoB,IAAE,MAAK,EAAC,WAAW,EAAC,GAAC,WAAW,EAAE,CAAC,CAAA,IAAG,CAAC,KAAK,CAAC,IAAI,EAAE;IAAC,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAA,OAAO,KAAC,WAAW,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAK,KAAK,EAAE,EAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,EAAC,CAAC,EAAC,aAAE,eAAK,KAAK,uBAAa,MAAM,EAAC,KAAK,EAAE,EAAC,QAAQ,EAAC,UAAU,EAAC,MAAM,EAAC,GAAG,EAAC,YAAY,EAAC,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,aAAa,EAAC,MAAM,EAAC,aAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAC,KAAK,EAAC,EAAE,CAAA,cAAiB,KAAK,EAAE,EAAC,QAAQ,EAAC,UAAU,EAAC,gBAAgB,EAAC,KAAK,EAAC,GAAG,EAAC,EAAE,GAAC,KAAK,GAAC,CAAC,EAAC,KAAK,EAAC,KAAK,EAAC,MAAM,EAAC,GAAG,EAAC,QAAQ,EAAC,QAAQ,EAAC,YAAY,EAAC,sBAAsB,EAAC,UAAU,EAAC,8BAA8B,EAAC,MAAM,EAAC,mCAAmC,EAAC,SAAS,EAAC,cAAc,CAAC,KAAK,GAAC,CAAC,CAAC,GAAC,CAAC,IAAI,CAAA,CAAC,CAAA,EAAE,CAAA,CAAC,CAAA,EAAE,CAAC,cAAc,CAAC,KAAK,GAAC,CAAC,CAAC,GAAC,CAAC,IAAI,CAAA,CAAC,CAAA,EAAE,CAAA,CAAC,CAAA,CAAC,CAAC,MAAM,EAAC,UAAU,EAAC,WAAW,CAAC,aAAa,CAAA,CAAC,CAAA,MAAM,CAAA,CAAC,CAAA,0BAA0B,EAAC,YAAG,OAAO,IAApZ,KAAK,CAAsZ,CAAC,EAAC,cAAK,KAAK,EAAE,EAAC,QAAQ,EAAC,UAAU,EAAC,MAAM,EAAC,CAAC,EAAC,WAAW,EAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAC,YAAY,EAAC,sBAAsB,EAAC,UAAU,EAAC,iCAAiC,EAAC,MAAM,EAAC,mCAAmC,EAAC,eAAe,EAAC,QAAQ,EAAC,SAAS,EAAC,IAAI,CAAA,CAAC,CAAA,oCAAoC,CAAA,CAAC,CAAA,MAAM,EAAC,GAAG,IAAM,EAAA,yBAAO,KAAK,GAAQ,IAAM,YAAG,QAAQ,GAAe,CAAC,CAAA,CAAC","sourcesContent":["// Fixed 260×160 artwork is decorative; cap at three previews to keep the motif bounded. The trigger label and expanded content remain fluid.\nimport type{ReactNode}from'react';import{Collapsible}from'./collapsible.js';import{useHjmTheme}from'./provider.js';\nexport type FolderPreviewProps=Readonly<{label:string;open:boolean;onOpenChange:(open:boolean)=>void;previews:readonly ReactNode[];children:ReactNode;disabled?:boolean}>;\n/** Preview slots are decorative snapshots; expanded children own real actions and accessible content. */\nexport function FolderPreview({label,open,onOpenChange,previews,children,disabled=false}:FolderPreviewProps){const{environment}=useHjmTheme();if(!label.trim())throw new TypeError('Folder needs a label');return <Collapsible open={open} onOpenChange={onOpenChange} disabled={disabled} trigger={<div style={{width:'100%',minWidth:0}}><div inert aria-hidden=\"true\" style={{position:'relative',height:160,marginInline:'auto',maxWidth:260,pointerEvents:'none'}}>{previews.slice(0,3).map((preview,index)=><div key={index} style={{position:'absolute',insetInlineStart:'20%',top:24+index*8,width:'60%',height:104,overflow:'hidden',borderRadius:'var(--hjm-radius-md)',background:'var(--hjm-color-surface-alt)',border:'1px solid var(--hjm-color-border)',transform:`translateX(${(index-1)*(open?34:10)}px) rotate(${(index-1)*(open?12:4)}deg)`,transition:environment.reducedMotion?'none':'transform 200ms ease-out'}}>{preview}</div>)}<div style={{position:'absolute',bottom:0,insetInline:0,height:56,borderRadius:'var(--hjm-radius-lg)',background:'var(--hjm-color-surface-accent)',border:'1px solid var(--hjm-color-border)',transformOrigin:'bottom',transform:open?'perspective(400px) rotateX(-15deg)':'none'}}/></div><span>{label}</span></div>}>{children}</Collapsible>;}\n"]}
1
+ {"version":3,"file":"folder-preview.js","sourceRoot":"","sources":["../src/folder-preview.tsx"],"names":[],"mappings":";AACkC,OAAM,EAAC,WAAW,EAAC,MAAI,kBAAkB,CAAC;AAAA,OAAM,EAAC,WAAW,EAAC,MAAI,eAAe,CAAC;AAKnH,yGAAyG;AACzG,MAAM,UAAU,aAAa,CAAC,EAAC,KAAK,EAAC,IAAI,EAAC,YAAY,EAAC,QAAQ,EAAC,QAAQ,EAAC,QAAQ,GAAC,KAAK,EAAC,WAAW,EAAoB,IAAE,MAAK,EAAC,WAAW,EAAC,GAAC,WAAW,EAAE,CAAC,CAAA,IAAG,CAAC,KAAK,CAAC,IAAI,EAAE;IAAC,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAA,OAAO,KAAC,WAAW,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,KAAM,CAAC,WAAW,KAAG,SAAS,CAAA,CAAC,CAAA,EAAE,CAAA,CAAC,CAAA,EAAC,WAAW,EAAC,CAAC,EAAE,OAAO,EAAE,eAAK,KAAK,EAAE,EAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,EAAC,CAAC,EAAC,aAAE,eAAK,KAAK,uBAAa,MAAM,EAAC,KAAK,EAAE,EAAC,QAAQ,EAAC,UAAU,EAAC,MAAM,EAAC,GAAG,EAAC,YAAY,EAAC,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,aAAa,EAAC,MAAM,EAAC,aAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAC,KAAK,EAAC,EAAE,CAAA,cAAiB,KAAK,EAAE,EAAC,QAAQ,EAAC,UAAU,EAAC,gBAAgB,EAAC,KAAK,EAAC,GAAG,EAAC,EAAE,GAAC,KAAK,GAAC,CAAC,EAAC,KAAK,EAAC,KAAK,EAAC,MAAM,EAAC,GAAG,EAAC,QAAQ,EAAC,QAAQ,EAAC,YAAY,EAAC,sBAAsB,EAAC,UAAU,EAAC,8BAA8B,EAAC,MAAM,EAAC,mCAAmC,EAAC,SAAS,EAAC,cAAc,CAAC,KAAK,GAAC,CAAC,CAAC,GAAC,CAAC,IAAI,CAAA,CAAC,CAAA,EAAE,CAAA,CAAC,CAAA,EAAE,CAAC,cAAc,CAAC,KAAK,GAAC,CAAC,CAAC,GAAC,CAAC,IAAI,CAAA,CAAC,CAAA,EAAE,CAAA,CAAC,CAAA,CAAC,CAAC,MAAM,EAAC,UAAU,EAAC,WAAW,CAAC,aAAa,CAAA,CAAC,CAAA,MAAM,CAAA,CAAC,CAAA,0BAA0B,EAAC,YAAG,OAAO,IAApZ,KAAK,CAAsZ,CAAC,EAAC,cAAK,KAAK,EAAE,EAAC,QAAQ,EAAC,UAAU,EAAC,MAAM,EAAC,CAAC,EAAC,WAAW,EAAC,CAAC,EAAC,MAAM,EAAC,EAAE,EAAC,YAAY,EAAC,sBAAsB,EAAC,UAAU,EAAC,iCAAiC,EAAC,MAAM,EAAC,mCAAmC,EAAC,eAAe,EAAC,QAAQ,EAAC,SAAS,EAAC,IAAI,CAAA,CAAC,CAAA,oCAAoC,CAAA,CAAC,CAAA,MAAM,EAAC,GAAG,IAAM,EAAA,yBAAO,KAAK,GAAQ,IAAM,YAAG,QAAQ,GAAe,CAAC,CAAA,CAAC","sourcesContent":["// Fixed 260×160 artwork is decorative; cap at three previews to keep the motif bounded. The trigger label and expanded content remain fluid.\nimport type{ReactNode}from'react';import{Collapsible}from'./collapsible.js';import{useHjmTheme}from'./provider.js';\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nexport type FolderPreviewProps=Readonly<{label:string;open:boolean;onOpenChange:(open:boolean)=>void;previews:readonly ReactNode[];children:ReactNode;disabled?:boolean;\n /** Canonical layout-only placement on the root Collapsible. Controlled visual keys are excluded. */\n layoutStyle?:HjmCompositionStyleProp}>;\n/** Preview slots are decorative snapshots; expanded children own real actions and accessible content. */\nexport function FolderPreview({label,open,onOpenChange,previews,children,disabled=false,layoutStyle}:FolderPreviewProps){const{environment}=useHjmTheme();if(!label.trim())throw new TypeError('Folder needs a label');return <Collapsible open={open} onOpenChange={onOpenChange} disabled={disabled} {...(layoutStyle===undefined?{}:{layoutStyle})} trigger={<div style={{width:'100%',minWidth:0}}><div inert aria-hidden=\"true\" style={{position:'relative',height:160,marginInline:'auto',maxWidth:260,pointerEvents:'none'}}>{previews.slice(0,3).map((preview,index)=><div key={index} style={{position:'absolute',insetInlineStart:'20%',top:24+index*8,width:'60%',height:104,overflow:'hidden',borderRadius:'var(--hjm-radius-md)',background:'var(--hjm-color-surface-alt)',border:'1px solid var(--hjm-color-border)',transform:`translateX(${(index-1)*(open?34:10)}px) rotate(${(index-1)*(open?12:4)}deg)`,transition:environment.reducedMotion?'none':'transform 200ms ease-out'}}>{preview}</div>)}<div style={{position:'absolute',bottom:0,insetInline:0,height:56,borderRadius:'var(--hjm-radius-lg)',background:'var(--hjm-color-surface-accent)',border:'1px solid var(--hjm-color-border)',transformOrigin:'bottom',transform:open?'perspective(400px) rotateX(-15deg)':'none'}}/></div><span>{label}</span></div>}>{children}</Collapsible>;}\n"]}
package/dist/forms.d.ts CHANGED
@@ -3,6 +3,7 @@ import { type SearchFieldSize } from "@hjmds/design-contracts/recipes";
3
3
  import { type PasswordFieldAutofillHint, type PasswordFieldSize } from "@hjmds/design-contracts/components/password-field";
4
4
  import { type OtpFieldSize, type OtpFieldPresentation } from "@hjmds/design-contracts/components/otp-field";
5
5
  import { type HTMLAttributes, type InputHTMLAttributes, type ReactNode, type TextareaHTMLAttributes } from "react";
6
+ import type { HjmCompositionStyleProp } from "./composition-style.js";
6
7
  type FieldCopyProps = Readonly<{
7
8
  label?: ReactNode;
8
9
  description?: ReactNode;
@@ -18,7 +19,11 @@ type FieldFrameProps = HTMLAttributes<HTMLDivElement> & FieldCopyProps & Readonl
18
19
  variant?: FieldVariant;
19
20
  shape?: FieldShape;
20
21
  align?: FieldAlign;
22
+ /** Component recipe override of fieldRecipe.disabledOpacity (OtpField). */
23
+ disabledOpacity?: number;
21
24
  children: ReactNode;
25
+ /** Canonical layout-only placement on the field frame (`.hjm-field`), not the input. Controlled visual keys are excluded. */
26
+ layoutStyle?: HjmCompositionStyleProp;
22
27
  }>;
23
28
  export type FieldControlProps = Readonly<{
24
29
  id: string;
@@ -27,7 +32,7 @@ export type FieldControlProps = Readonly<{
27
32
  "aria-invalid"?: true;
28
33
  "aria-describedby"?: string;
29
34
  }>;
30
- export type FieldProps = Omit<FieldFrameProps, "children" | "descriptionId" | "errorId"> & Readonly<{
35
+ export type FieldProps = Omit<FieldFrameProps, "children" | "descriptionId" | "errorId" | "disabledOpacity"> & Readonly<{
31
36
  label: ReactNode;
32
37
  children: ReactNode | ((props: FieldControlProps) => ReactNode);
33
38
  }>;
@@ -45,6 +50,11 @@ type SharedInputProps = FieldCopyProps & Readonly<{
45
50
  leading?: ReactNode;
46
51
  trailing?: ReactNode;
47
52
  fieldClassName?: string;
53
+ /**
54
+ * Canonical layout-only placement on the field frame. `style` keeps going to
55
+ * the input element, where it always went, so existing callers do not move.
56
+ */
57
+ layoutStyle?: HjmCompositionStyleProp;
48
58
  }>;
49
59
  export type TextFieldProps = Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & SharedInputProps & Readonly<{
50
60
  /**
@@ -72,6 +82,11 @@ export declare const TextField: import("react").ForwardRefExoticComponent<Omit<I
72
82
  leading?: ReactNode;
73
83
  trailing?: ReactNode;
74
84
  fieldClassName?: string;
85
+ /**
86
+ * Canonical layout-only placement on the field frame. `style` keeps going to
87
+ * the input element, where it always went, so existing callers do not move.
88
+ */
89
+ layoutStyle?: HjmCompositionStyleProp;
75
90
  }> & Readonly<{
76
91
  /**
77
92
  * Receives the next string value, the same callback name and shape as the
@@ -81,7 +96,13 @@ export declare const TextField: import("react").ForwardRefExoticComponent<Omit<I
81
96
  */
82
97
  onValueChange?: (value: string) => void;
83
98
  }> & import("react").RefAttributes<HTMLInputElement>>;
84
- export type TextAreaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & Omit<SharedInputProps, "leading" | "trailing"> & Readonly<{
99
+ export type TextAreaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & Omit<SharedInputProps, "leading"> & Readonly<{
100
+ /**
101
+ * Action before the text inside the field frame (for example a composer's camera button),
102
+ * vertically centred while the text grows. Mirrors `trailing`; `leading` stays omitted because
103
+ * TextField's `leading` is a decorative affix with muted color, not an action slot.
104
+ */
105
+ leadingAction?: ReactNode;
85
106
  /**
86
107
  * Lower bound for a growing multiline field, in visible lines. Height is
87
108
  * recipe-owned, so this semantic axis replaces a `min-height` override.
@@ -90,7 +111,13 @@ export type TextAreaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & Omit<S
90
111
  /** Upper bound for a growing multiline field, in visible lines. */
91
112
  maxVisibleLines?: number;
92
113
  }>;
93
- export declare const TextArea: import("react").ForwardRefExoticComponent<TextareaHTMLAttributes<HTMLTextAreaElement> & Omit<SharedInputProps, "leading" | "trailing"> & Readonly<{
114
+ export declare const TextArea: import("react").ForwardRefExoticComponent<TextareaHTMLAttributes<HTMLTextAreaElement> & Omit<SharedInputProps, "leading"> & Readonly<{
115
+ /**
116
+ * Action before the text inside the field frame (for example a composer's camera button),
117
+ * vertically centred while the text grows. Mirrors `trailing`; `leading` stays omitted because
118
+ * TextField's `leading` is a decorative affix with muted color, not an action slot.
119
+ */
120
+ leadingAction?: ReactNode;
94
121
  /**
95
122
  * Lower bound for a growing multiline field, in visible lines. Height is
96
123
  * recipe-owned, so this semantic axis replaces a `min-height` override.
@@ -137,6 +164,11 @@ export declare const SearchField: import("react").ForwardRefExoticComponent<Omit
137
164
  leading?: ReactNode;
138
165
  trailing?: ReactNode;
139
166
  fieldClassName?: string;
167
+ /**
168
+ * Canonical layout-only placement on the field frame. `style` keeps going to
169
+ * the input element, where it always went, so existing callers do not move.
170
+ */
171
+ layoutStyle?: HjmCompositionStyleProp;
140
172
  }> & Readonly<{
141
173
  value?: string;
142
174
  defaultValue?: string;