@hjmds/react 1.17.2 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/dist/activity-chip.d.ts +33 -0
  2. package/dist/activity-chip.d.ts.map +1 -0
  3. package/dist/activity-chip.js +24 -0
  4. package/dist/activity-chip.js.map +1 -0
  5. package/dist/advanced-display.d.ts.map +1 -1
  6. package/dist/advanced-display.js +41 -9
  7. package/dist/advanced-display.js.map +1 -1
  8. package/dist/advanced-forms.d.ts.map +1 -1
  9. package/dist/advanced-forms.js +22 -9
  10. package/dist/advanced-forms.js.map +1 -1
  11. package/dist/agreement.d.ts.map +1 -1
  12. package/dist/agreement.js +17 -11
  13. package/dist/agreement.js.map +1 -1
  14. package/dist/auth-screen.d.ts.map +1 -1
  15. package/dist/auth-screen.js +15 -2
  16. package/dist/auth-screen.js.map +1 -1
  17. package/dist/avatar-blobatar-motion.d.ts.map +1 -1
  18. package/dist/avatar-blobatar-motion.js +10 -2
  19. package/dist/avatar-blobatar-motion.js.map +1 -1
  20. package/dist/bottom-navigation.d.ts.map +1 -1
  21. package/dist/bottom-navigation.js +2 -2
  22. package/dist/bottom-navigation.js.map +1 -1
  23. package/dist/calendar.d.ts.map +1 -1
  24. package/dist/calendar.js +10 -2
  25. package/dist/calendar.js.map +1 -1
  26. package/dist/carousel-motion.d.ts +1 -0
  27. package/dist/carousel-motion.d.ts.map +1 -1
  28. package/dist/carousel-motion.js +4 -3
  29. package/dist/carousel-motion.js.map +1 -1
  30. package/dist/carousel.d.ts.map +1 -1
  31. package/dist/carousel.js +22 -4
  32. package/dist/carousel.js.map +1 -1
  33. package/dist/collapsible.d.ts.map +1 -1
  34. package/dist/collapsible.js +28 -4
  35. package/dist/collapsible.js.map +1 -1
  36. package/dist/collection-rail.d.ts.map +1 -1
  37. package/dist/collection-rail.js +19 -1
  38. package/dist/collection-rail.js.map +1 -1
  39. package/dist/color-picker.d.ts.map +1 -1
  40. package/dist/color-picker.js +12 -4
  41. package/dist/color-picker.js.map +1 -1
  42. package/dist/command-palette.d.ts.map +1 -1
  43. package/dist/command-palette.js +14 -2
  44. package/dist/command-palette.js.map +1 -1
  45. package/dist/content-transition.d.ts +2 -1
  46. package/dist/content-transition.d.ts.map +1 -1
  47. package/dist/content-transition.js +2 -2
  48. package/dist/content-transition.js.map +1 -1
  49. package/dist/context-menu.d.ts.map +1 -1
  50. package/dist/context-menu.js +31 -10
  51. package/dist/context-menu.js.map +1 -1
  52. package/dist/date-entry.d.ts +1 -1
  53. package/dist/date-entry.d.ts.map +1 -1
  54. package/dist/date-entry.js +20 -7
  55. package/dist/date-entry.js.map +1 -1
  56. package/dist/date-picker.d.ts.map +1 -1
  57. package/dist/date-picker.js +22 -6
  58. package/dist/date-picker.js.map +1 -1
  59. package/dist/display.d.ts +11 -1
  60. package/dist/display.d.ts.map +1 -1
  61. package/dist/display.js +13 -4
  62. package/dist/display.js.map +1 -1
  63. package/dist/duration-field.d.ts +2 -2
  64. package/dist/duration-field.d.ts.map +1 -1
  65. package/dist/duration-field.js +11 -3
  66. package/dist/duration-field.js.map +1 -1
  67. package/dist/evidence.d.ts +1 -1
  68. package/dist/evidence.js +1 -1
  69. package/dist/evidence.js.map +1 -1
  70. package/dist/feedback.d.ts +1 -0
  71. package/dist/feedback.d.ts.map +1 -1
  72. package/dist/feedback.js +7 -2
  73. package/dist/feedback.js.map +1 -1
  74. package/dist/field-group.d.ts +4 -2
  75. package/dist/field-group.d.ts.map +1 -1
  76. package/dist/field-group.js +4 -3
  77. package/dist/field-group.js.map +1 -1
  78. package/dist/file-picker.d.ts.map +1 -1
  79. package/dist/file-picker.js +15 -5
  80. package/dist/file-picker.js.map +1 -1
  81. package/dist/forms.d.ts +2 -2
  82. package/dist/forms.js +1 -1
  83. package/dist/forms.js.map +1 -1
  84. package/dist/gravity-letters.d.ts.map +1 -1
  85. package/dist/gravity-letters.js +9 -1
  86. package/dist/gravity-letters.js.map +1 -1
  87. package/dist/grid-reveal.d.ts.map +1 -1
  88. package/dist/grid-reveal.js +9 -1
  89. package/dist/grid-reveal.js.map +1 -1
  90. package/dist/index.d.ts +1 -0
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +1 -0
  93. package/dist/index.js.map +1 -1
  94. package/dist/inline-confirm.d.ts.map +1 -1
  95. package/dist/inline-confirm.js +25 -4
  96. package/dist/inline-confirm.js.map +1 -1
  97. package/dist/internal/document-resource.d.ts.map +1 -1
  98. package/dist/internal/document-resource.js +2 -2
  99. package/dist/internal/document-resource.js.map +1 -1
  100. package/dist/layout.d.ts +8 -2
  101. package/dist/layout.d.ts.map +1 -1
  102. package/dist/layout.js.map +1 -1
  103. package/dist/masonry.d.ts.map +1 -1
  104. package/dist/masonry.js +2 -1
  105. package/dist/masonry.js.map +1 -1
  106. package/dist/mentions.d.ts.map +1 -1
  107. package/dist/mentions.js +12 -4
  108. package/dist/mentions.js.map +1 -1
  109. package/dist/menu-morph.js +1 -1
  110. package/dist/menu-morph.js.map +1 -1
  111. package/dist/menubar.d.ts.map +1 -1
  112. package/dist/menubar.js +43 -19
  113. package/dist/menubar.js.map +1 -1
  114. package/dist/modal.d.ts.map +1 -1
  115. package/dist/modal.js +15 -4
  116. package/dist/modal.js.map +1 -1
  117. package/dist/navigation.d.ts.map +1 -1
  118. package/dist/navigation.js +8 -2
  119. package/dist/navigation.js.map +1 -1
  120. package/dist/number-field.d.ts.map +1 -1
  121. package/dist/number-field.js +3 -1
  122. package/dist/number-field.js.map +1 -1
  123. package/dist/overlay-stack.d.ts.map +1 -1
  124. package/dist/overlay-stack.js +23 -6
  125. package/dist/overlay-stack.js.map +1 -1
  126. package/dist/overlays.d.ts.map +1 -1
  127. package/dist/overlays.js +8 -0
  128. package/dist/overlays.js.map +1 -1
  129. package/dist/pagination.d.ts.map +1 -1
  130. package/dist/pagination.js +16 -4
  131. package/dist/pagination.js.map +1 -1
  132. package/dist/saved-items.d.ts.map +1 -1
  133. package/dist/saved-items.js +6 -1
  134. package/dist/saved-items.js.map +1 -1
  135. package/dist/screen-flows.d.ts +1 -2
  136. package/dist/screen-flows.d.ts.map +1 -1
  137. package/dist/screen-flows.js +120 -16
  138. package/dist/screen-flows.js.map +1 -1
  139. package/dist/screens.d.ts +1 -1
  140. package/dist/screens.d.ts.map +1 -1
  141. package/dist/screens.js +38 -10
  142. package/dist/screens.js.map +1 -1
  143. package/dist/select.d.ts.map +1 -1
  144. package/dist/select.js +6 -1
  145. package/dist/select.js.map +1 -1
  146. package/dist/side-panel.d.ts.map +1 -1
  147. package/dist/side-panel.js +11 -2
  148. package/dist/side-panel.js.map +1 -1
  149. package/dist/sidebar.d.ts.map +1 -1
  150. package/dist/sidebar.js +8 -1
  151. package/dist/sidebar.js.map +1 -1
  152. package/dist/skip-nav.d.ts.map +1 -1
  153. package/dist/skip-nav.js +16 -3
  154. package/dist/skip-nav.js.map +1 -1
  155. package/dist/sortable.d.ts.map +1 -1
  156. package/dist/sortable.js +2 -1
  157. package/dist/sortable.js.map +1 -1
  158. package/dist/splitter.d.ts.map +1 -1
  159. package/dist/splitter.js +23 -11
  160. package/dist/splitter.js.map +1 -1
  161. package/dist/statistic-motion.d.ts.map +1 -1
  162. package/dist/statistic-motion.js +30 -2
  163. package/dist/statistic-motion.js.map +1 -1
  164. package/dist/status-text.d.ts +11 -0
  165. package/dist/status-text.d.ts.map +1 -0
  166. package/dist/status-text.js +7 -0
  167. package/dist/status-text.js.map +1 -0
  168. package/dist/styles.css +53 -7
  169. package/dist/styles.layered.css +53 -7
  170. package/dist/supplemental-display.d.ts.map +1 -1
  171. package/dist/supplemental-display.js +19 -8
  172. package/dist/supplemental-display.js.map +1 -1
  173. package/dist/supplemental-navigation.d.ts.map +1 -1
  174. package/dist/supplemental-navigation.js +10 -1
  175. package/dist/supplemental-navigation.js.map +1 -1
  176. package/dist/tags-input.d.ts.map +1 -1
  177. package/dist/tags-input.js +18 -8
  178. package/dist/tags-input.js.map +1 -1
  179. package/dist/theme.d.ts.map +1 -1
  180. package/dist/theme.js +11 -0
  181. package/dist/theme.js.map +1 -1
  182. package/dist/toast.d.ts.map +1 -1
  183. package/dist/toast.js +41 -16
  184. package/dist/toast.js.map +1 -1
  185. package/dist/toggle-group.d.ts.map +1 -1
  186. package/dist/toggle-group.js +6 -1
  187. package/dist/toggle-group.js.map +1 -1
  188. package/dist/tour.d.ts.map +1 -1
  189. package/dist/tour.js +15 -2
  190. package/dist/tour.js.map +1 -1
  191. package/dist/transfer-list.d.ts +1 -1
  192. package/dist/transfer-list.d.ts.map +1 -1
  193. package/dist/transfer-list.js +52 -7
  194. package/dist/transfer-list.js.map +1 -1
  195. package/dist/tree.d.ts.map +1 -1
  196. package/dist/tree.js +41 -8
  197. package/dist/tree.js.map +1 -1
  198. package/dist/virtual-list.d.ts.map +1 -1
  199. package/dist/virtual-list.js +44 -7
  200. package/dist/virtual-list.js.map +1 -1
  201. package/package.json +13 -3
@@ -1 +1 @@
1
- {"version":3,"file":"date-entry.js","sourceRoot":"","sources":["../src/date-entry.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useId } from \"react\";\nimport { resolveDateEntryControl, updateDateEntryDraft, type DateEntryControlProps } from \"@hjmds/design-contracts/date-entry\";\nimport { TextField } from \"./forms.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nexport type DateEntryProps = DateEntryControlProps & Readonly<{ className?: string; layoutStyle?: HjmCompositionStyleProp }>;\n/** Direct date drafts reuse TextField; Calendar/DatePicker continue to own calendar selection. */\nexport function DateEntry(props: DateEntryProps) {\n const id = useId();\n const resolved = resolveDateEntryControl(props);\n const support = [props.description ? `${id}-hint` : undefined, resolved.error ? `${id}-error` : undefined].filter(Boolean).join(\" \") || undefined;\n return <fieldset className={props.className} disabled={props.disabled}\n aria-describedby={support} style={{ border: 0, margin: 0, padding: 0, minWidth: 0, ...props.layoutStyle }}>\n <legend style={{ marginBlockEnd: \"var(--hjm-space-sm)\" }}>{props.labels.label}</legend>\n {props.description ? <p id={`${id}-hint`}>{props.description}</p> : null}\n {resolved.error ? <p id={`${id}-error`} role=\"alert\" style={{ color: \"var(--hjm-color-danger)\" }}>{resolved.error}</p> : null}\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit, minmax(min(100%, 10ch), 1fr))\", gap: \"var(--hjm-space-md)\" }}>\n {resolved.fields.map(field => <TextField key={field.part} id={`${id}-${field.part}`}\n label={props.labels[field.part]} value={field.value} type=\"text\"\n inputMode={field.part === \"month\" && props.monthInput !== \"numeric\" ? \"text\" : \"numeric\"}\n autoComplete={props.purpose === \"birthdate\" ? `bday-${field.part}` : \"off\"}\n required={props.required ?? false} disabled={props.disabled ?? false} readOnly={props.readOnly ?? false}\n aria-describedby={support} aria-invalid={Boolean(resolved.error && field.invalid)}\n onBlur={() => props.onBlur?.(field.part)}\n onValueChange={value => { if (!props.disabled && !props.readOnly) props.onValueChange(updateDateEntryDraft(props.value, field.part, value)); }} />)}\n </div>\n </fieldset>;\n}\n"]}
1
+ {"version":3,"file":"date-entry.js","sourceRoot":"","sources":["../src/date-entry.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useRef } from \"react\";\nimport { resolveDateEntryControl, updateDateEntryDraft, type DateEntryControlProps } from \"@hjmds/design-contracts/date-entry\";\nimport { FieldGroup } from \"./field-group.js\";\nimport { TextField } from \"./forms.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nexport type DateEntryProps = DateEntryControlProps & Readonly<{ className?: string; layoutStyle?: HjmCompositionStyleProp }>;\n/** Date policy stays here; FieldGroup owns related-input semantics, feedback and edit lifetime. */\nexport function DateEntry(props: DateEntryProps) {\n const resolved = resolveDateEntryControl(props);\n const current = useRef(props);\n current.current = props;\n return <FieldGroup layout=\"inline\" {...(props.className === undefined ? {} : { className: props.className })} {...(props.layoutStyle === undefined ? {} : { layoutStyle: props.layoutStyle })}\n descriptor={{ label: props.labels.label, disabled: props.disabled ?? false,\n ...(props.description ? { description: props.description } : {}),\n ...(resolved.error ? { error: { message: resolved.error, fieldIds: resolved.fields.filter(field => field.invalid).map(field => field.part) } } : {}),\n fields: resolved.fields.map(field => ({ id: field.part, label: props.labels[field.part] })) }}\n renderField={({ id, controlProps, guardChange }) => {\n const field = resolved.fields.find(field => field.part === id);\n if (!field) return null;\n return <TextField {...controlProps} value={field.value} type=\"text\"\n inputMode={field.part === \"month\" && props.monthInput !== \"numeric\" ? \"text\" : \"numeric\"}\n autoComplete={props.purpose === \"birthdate\" ? `bday-${field.part}` : \"off\"}\n required={props.required ?? false} readOnly={props.readOnly ?? false}\n onBlur={() => current.current.onBlur?.(field.part)}\n onValueChange={guardChange((value: string) => {\n // Retained host callbacks must not edit an old draft or bypass a new read-only policy.\n const latest = current.current;\n if (!latest.readOnly) latest.onValueChange(updateDateEntryDraft(latest.value, field.part, value));\n })} />;\n }} />;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../src/date-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC9B,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,cAAc,EACpB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAY,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAErF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAItE,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/E,MAAM,MAAM,eAAe,CAAC,OAAO,GAAG,OAAO,IAAI,QAAQ,CAAC;IACxD,UAAU,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC9D,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAClG,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,wBAAwB,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,OAAO,EAAE,EAClC,UAAU,EACV,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,SAAS,EACT,UAAU,EACV,UAAU,EACV,IAAe,EACf,WAAW,EACX,KAAK,EACL,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACT,WAAW,GACZ,EAAE,eAAe,CAAC,OAAO,CAAC,+BA6H1B"}
1
+ {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../src/date-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC9B,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,cAAc,EACpB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAY,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAErF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAItE,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/E,MAAM,MAAM,eAAe,CAAC,OAAO,GAAG,OAAO,IAAI,QAAQ,CAAC;IACxD,UAAU,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC9D,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAClG,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,wBAAwB,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,OAAO,EAAE,EAClC,UAAU,EACV,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,SAAS,EACT,UAAU,EACV,UAAU,EACV,IAAe,EACf,WAAW,EACX,KAAK,EACL,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACT,WAAW,GACZ,EAAE,eAAe,CAAC,OAAO,CAAC,+BA0I1B"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import {} from "@hjmds/design-contracts/components/calendar";
3
3
  import { resolveDatePickerTriggerText, validateDatePickerDescriptor, } from "@hjmds/design-contracts/components/date-picker";
4
- import { useEffect, useId, useLayoutEffect, useRef, useState, } from "react";
4
+ import { useCallback, useEffect, useId, useLayoutEffect, useRef, useState, } from "react";
5
5
  import { Calendar } from "./calendar.js";
6
6
  import { classNames } from "./internal.js";
7
7
  const popoverViewportInset = 16;
@@ -18,11 +18,17 @@ export function DatePicker({ descriptor, monthLabel, composeAccessibleName, prev
18
18
  const controlledSelection = descriptor.selectedDate !== undefined;
19
19
  const [internalSelection, setInternalSelection] = useState(descriptor.defaultSelectedDate ?? null);
20
20
  const selectedDate = controlledSelection ? descriptor.selectedDate ?? null : internalSelection;
21
- const requestOpen = (next, reason) => {
21
+ const closeReasonRef = useRef("programmatic");
22
+ const requestOpen = useCallback((next, reason) => {
23
+ closeReasonRef.current = next ? "programmatic" : reason;
22
24
  if (!controlledOpen)
23
25
  setInternalOpen(next);
24
26
  descriptor.onOpenChange?.(next, reason);
25
- };
27
+ }, [controlledOpen, descriptor.onOpenChange]);
28
+ useEffect(() => {
29
+ if (open && (descriptor.disabled || descriptor.readOnly))
30
+ requestOpen(false, "programmatic");
31
+ }, [descriptor.disabled, descriptor.readOnly, open, requestOpen]);
26
32
  const commit = (date, reason) => {
27
33
  // A controlled open field can become read-only while its grid remains mounted.
28
34
  if (descriptor.disabled || descriptor.readOnly)
@@ -31,13 +37,17 @@ export function DatePicker({ descriptor, monthLabel, composeAccessibleName, prev
31
37
  setInternalSelection(date);
32
38
  descriptor.onSelectionChange?.(date, reason);
33
39
  requestOpen(false, reason === "activate" ? "selection" : "clear");
40
+ // Clearing a closed field removes the focused clear button without an open transition.
41
+ if (reason === "clear")
42
+ triggerRef.current?.focus();
34
43
  };
35
44
  const wasOpenRef = useRef(open);
36
45
  useEffect(() => {
37
46
  const wasOpen = wasOpenRef.current;
38
47
  wasOpenRef.current = open;
39
48
  if (!open) {
40
- if (wasOpen)
49
+ // Outside/Tab dismissal keeps the user's new target; confirmation/Escape returns here.
50
+ if (wasOpen && closeReasonRef.current !== "outside" && closeReasonRef.current !== "blur")
41
51
  triggerRef.current?.focus();
42
52
  return;
43
53
  }
@@ -51,7 +61,7 @@ export function DatePicker({ descriptor, monthLabel, composeAccessibleName, prev
51
61
  return () => {
52
62
  document.removeEventListener("pointerdown", outside);
53
63
  };
54
- }, [open]);
64
+ }, [open, requestOpen]);
55
65
  // Keep the popover inside the viewport (2026-09-30 audit WR-0930-3): shift inline, flip up
56
66
  // when short. Not portaled: Calendar autoFocus runs before a portal popup is measured.
57
67
  useLayoutEffect(() => {
@@ -96,7 +106,13 @@ export function DatePicker({ descriptor, monthLabel, composeAccessibleName, prev
96
106
  : descriptor.grid;
97
107
  const label = descriptor.label ?? descriptor.accessibilityLabel;
98
108
  const triggerText = resolveDatePickerTriggerText(descriptor);
99
- return (_jsxs("div", { style: layoutStyle, className: classNames("hjm-date-picker", className), "data-disabled": descriptor.disabled || undefined, "data-invalid": descriptor.invalid || error !== undefined || undefined, "data-size": size, children: [descriptor.label === undefined ? null : _jsx("span", { className: "hjm-date-picker__label", children: descriptor.label }), _jsxs("div", { className: "hjm-date-picker__anchor", children: [_jsxs("button", { "aria-controls": open ? dialogId : undefined, "aria-expanded": open, "aria-haspopup": "dialog", "aria-label": descriptor.accessibilityLabel, className: "hjm-date-picker__trigger", disabled: descriptor.disabled, onClick: () => !descriptor.readOnly && requestOpen(!open, "trigger"), ref: triggerRef, type: "button", children: [_jsx("span", { "aria-hidden": "true", children: "\u25A3" }), _jsx("span", { "data-placeholder": descriptor.displayValue === null || undefined, children: triggerText })] }), selectedDate === null ? null : (_jsx("button", { "aria-label": clearLabel, className: "hjm-date-picker__clear", disabled: descriptor.disabled || descriptor.readOnly, onClick: () => commit(null, "clear"), type: "button", children: "\u00D7" })), open ? (_jsxs("div", { "aria-label": label, className: "hjm-date-picker__popover", id: dialogId, ref: dialogRef, role: "dialog", onKeyDown: (event) => { if (event.key === "Escape") {
109
+ return (_jsxs("div", { style: layoutStyle, className: classNames("hjm-date-picker", className), onBlur: (event) => {
110
+ const field = event.currentTarget;
111
+ queueMicrotask(() => {
112
+ if (open && dialogRef.current && !field.contains(document.activeElement))
113
+ requestOpen(false, "blur");
114
+ });
115
+ }, "data-disabled": descriptor.disabled || undefined, "data-invalid": descriptor.invalid || error !== undefined || undefined, "data-size": size, children: [descriptor.label === undefined ? null : _jsx("span", { className: "hjm-date-picker__label", children: descriptor.label }), _jsxs("div", { className: "hjm-date-picker__anchor", children: [_jsxs("button", { "aria-controls": open ? dialogId : undefined, "aria-expanded": open, "aria-haspopup": "dialog", "aria-label": descriptor.accessibilityLabel ?? `${label}, ${triggerText}`, className: "hjm-date-picker__trigger", disabled: descriptor.disabled, onClick: () => !descriptor.readOnly && requestOpen(!open, "trigger"), ref: triggerRef, type: "button", children: [_jsx("span", { "aria-hidden": "true", children: "\u25A3" }), _jsx("span", { "data-placeholder": descriptor.displayValue === null || undefined, children: triggerText })] }), selectedDate === null ? null : (_jsx("button", { "aria-label": clearLabel, className: "hjm-date-picker__clear", disabled: descriptor.disabled || descriptor.readOnly, onClick: () => commit(null, "clear"), type: "button", children: "\u00D7" })), open ? (_jsxs("div", { "aria-label": label, className: "hjm-date-picker__popover", id: dialogId, ref: dialogRef, role: "dialog", onKeyDown: (event) => { if (event.key === "Escape") {
100
116
  event.preventDefault();
101
117
  requestOpen(false, "escape");
102
118
  } }, children: [_jsx("button", { "aria-label": closeLabel, className: "hjm-date-picker__calendar-close", onClick: () => requestOpen(false, "trigger"), type: "button", children: "\u00D7" }), _jsx(Calendar, { descriptor: { ...calendarDescriptor, grid: calendarGrid, monthLabel, selectedDate, onSelectionChange: (date) => commit(date, "activate") }, composeAccessibleName: composeAccessibleName, size: size, autoFocus: true, ...(previousMonth ? { previousMonth } : {}), ...(nextMonth ? { nextMonth } : {}), ...(renderCellContent ? { renderCellContent } : {}), ...(onNavigateBeyondGrid ? { onNavigateBeyondGrid } : {}) })] })) : null] }), description === undefined ? null : _jsx("span", { className: "hjm-date-picker__description", children: description }), error === undefined ? null : _jsx("span", { className: "hjm-date-picker__error", role: "alert", children: error })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker.js","sourceRoot":"","sources":["../src/date-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n type ComposeCalendarAccessibleName,\n type ResolvedCalendarDateCell,\n} from \"@hjmds/design-contracts/components/calendar\";\nimport {\n resolveDatePickerTriggerText,\n validateDatePickerDescriptor,\n type DatePickerDescriptor,\n type DatePickerOpenChangeReason,\n type DatePickerSize,\n} from \"@hjmds/design-contracts/components/date-picker\";\nimport {\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport { Calendar, type CalendarOverflow, type CalendarHandle } from \"./calendar.js\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nconst popoverViewportInset = 16;\n\nexport type DatePickerMonthAction = Readonly<{ month: string; label: string }>;\n\nexport type DatePickerProps<Content = unknown> = Readonly<{\n descriptor: DatePickerDescriptor<Content>;\n monthLabel: string;\n composeAccessibleName: ComposeCalendarAccessibleName<Content>;\n previousMonth?: DatePickerMonthAction;\n nextMonth?: DatePickerMonthAction;\n clearLabel: string;\n closeLabel: string;\n size?: DatePickerSize;\n description?: ReactNode;\n error?: ReactNode;\n onNavigateBeyondGrid?: (detail: CalendarOverflow, focusDate: CalendarHandle[\"focusDate\"]) => void;\n renderCellContent?: (cell: ResolvedCalendarDateCell<Content>) => ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Single-date field with an anchored, focus-bearing calendar dialog. */\nexport function DatePicker<Content>({\n descriptor,\n monthLabel,\n composeAccessibleName,\n previousMonth,\n nextMonth,\n clearLabel,\n closeLabel,\n size = \"medium\",\n description,\n error,\n renderCellContent,\n onNavigateBeyondGrid,\n className,\n layoutStyle,\n}: DatePickerProps<Content>) {\n validateDatePickerDescriptor(descriptor);\n const generatedId = useId().replaceAll(\":\", \"\");\n const dialogId = `hjm-date-picker-${generatedId}`;\n const triggerRef = useRef<HTMLButtonElement>(null);\n const dialogRef = useRef<HTMLDivElement>(null);\n const controlledOpen = descriptor.open !== undefined;\n const [internalOpen, setInternalOpen] = useState(descriptor.defaultOpen ?? false);\n const open = controlledOpen ? descriptor.open === true : internalOpen;\n const controlledSelection = descriptor.selectedDate !== undefined;\n const [internalSelection, setInternalSelection] = useState(\n descriptor.defaultSelectedDate ?? null,\n );\n const selectedDate = controlledSelection ? descriptor.selectedDate ?? null : internalSelection;\n\n const requestOpen = (next: boolean, reason: DatePickerOpenChangeReason) => {\n if (!controlledOpen) setInternalOpen(next);\n descriptor.onOpenChange?.(next, reason);\n };\n const commit = (date: string | null, reason: \"activate\" | \"clear\") => {\n // A controlled open field can become read-only while its grid remains mounted.\n if (descriptor.disabled || descriptor.readOnly) return;\n if (!controlledSelection) setInternalSelection(date);\n descriptor.onSelectionChange?.(date, reason);\n requestOpen(false, reason === \"activate\" ? \"selection\" : \"clear\");\n };\n\n const wasOpenRef = useRef(open);\n useEffect(() => {\n const wasOpen = wasOpenRef.current;\n wasOpenRef.current = open;\n if (!open) {\n if (wasOpen) triggerRef.current?.focus();\n return;\n }\n const outside = (event: PointerEvent) => {\n const target = event.target as Node;\n if (!dialogRef.current?.contains(target) && !triggerRef.current?.contains(target)) {\n requestOpen(false, \"outside\");\n }\n };\n document.addEventListener(\"pointerdown\", outside);\n return () => {\n document.removeEventListener(\"pointerdown\", outside);\n };\n }, [open]);\n\n // Keep the popover inside the viewport (2026-09-30 audit WR-0930-3): shift inline, flip up\n // when short. Not portaled: Calendar autoFocus runs before a portal popup is measured.\n useLayoutEffect(() => {\n const popover = dialogRef.current;\n if (!open || !popover) return;\n const place = () => {\n const viewport = window.visualViewport;\n const left = (viewport?.offsetLeft ?? 0) + popoverViewportInset;\n const right = (viewport?.offsetLeft ?? 0) + (viewport?.width ?? document.documentElement.clientWidth) - popoverViewportInset;\n // Layout offset, not translate: mobile Chromium widened the page for a translated box.\n popover.style.insetInlineStart = \"\";\n popover.style.maxInlineSize = `${Math.max(0, right - left)}px`;\n const rect = popover.getBoundingClientRect();\n let shift = rect.right > right ? Math.floor(right - rect.right) : 0;\n if (rect.left + shift < left) shift = Math.ceil(left - rect.left);\n const logical = getComputedStyle(popover).direction === \"rtl\" ? -shift : shift;\n popover.style.insetInlineStart = shift === 0 ? \"\" : `${logical}px`;\n popover.style.insetBlockStart = \"\";\n popover.style.insetBlockEnd = \"\";\n const box = popover.getBoundingClientRect();\n const bottom = (viewport?.offsetTop ?? 0) + (viewport?.height ?? window.innerHeight) - popoverViewportInset;\n const anchor = popover.parentElement?.getBoundingClientRect();\n if (anchor && box.bottom > bottom && anchor.top - box.height - popoverViewportInset >= (viewport?.offsetTop ?? 0)) {\n popover.style.insetBlockStart = \"auto\";\n popover.style.insetBlockEnd = \"calc(100% + var(--hjm-space-xs))\";\n }\n };\n place();\n window.addEventListener(\"resize\", place);\n window.visualViewport?.addEventListener(\"resize\", place);\n return () => {\n window.removeEventListener(\"resize\", place);\n window.visualViewport?.removeEventListener(\"resize\", place);\n };\n }, [open]);\n\n // The outer field owns selection; the shared grid receives only its resolved controlled value.\n const { defaultSelectedDate: _defaultSelectedDate, ...calendarDescriptor } = descriptor;\n const calendarGrid = descriptor.disabled || descriptor.readOnly\n ? { ...descriptor.grid, cells: descriptor.grid.cells.map((cell) => cell.date ? { ...cell, disabled: true } : cell) }\n : descriptor.grid;\n const label = descriptor.label ?? descriptor.accessibilityLabel;\n const triggerText = resolveDatePickerTriggerText(descriptor);\n return (\n <div style={layoutStyle} className={classNames(\"hjm-date-picker\", className)} data-disabled={descriptor.disabled || undefined} data-invalid={descriptor.invalid || error !== undefined || undefined} data-size={size}>\n {descriptor.label === undefined ? null : <span className=\"hjm-date-picker__label\">{descriptor.label}</span>}\n <div className=\"hjm-date-picker__anchor\">\n <button\n aria-controls={open ? dialogId : undefined}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-label={descriptor.accessibilityLabel}\n className=\"hjm-date-picker__trigger\"\n disabled={descriptor.disabled}\n onClick={() => !descriptor.readOnly && requestOpen(!open, \"trigger\")}\n ref={triggerRef}\n type=\"button\"\n >\n <span aria-hidden=\"true\">▣</span>\n <span data-placeholder={descriptor.displayValue === null || undefined}>{triggerText}</span>\n </button>\n {selectedDate === null ? null : (\n <button aria-label={clearLabel} className=\"hjm-date-picker__clear\" disabled={descriptor.disabled || descriptor.readOnly} onClick={() => commit(null, \"clear\")} type=\"button\">×</button>\n )}\n {open ? (\n <div aria-label={label} className=\"hjm-date-picker__popover\" id={dialogId} ref={dialogRef} role=\"dialog\" onKeyDown={(event) => { if (event.key === \"Escape\") { event.preventDefault(); requestOpen(false, \"escape\"); } }}>\n <button aria-label={closeLabel} className=\"hjm-date-picker__calendar-close\" onClick={() => requestOpen(false, \"trigger\")} type=\"button\">×</button>\n <Calendar descriptor={{ ...calendarDescriptor, grid: calendarGrid, monthLabel, selectedDate, onSelectionChange: (date) => commit(date, \"activate\") }}\n composeAccessibleName={composeAccessibleName} size={size} autoFocus\n {...(previousMonth ? { previousMonth } : {})} {...(nextMonth ? { nextMonth } : {})}\n {...(renderCellContent ? { renderCellContent } : {})} {...(onNavigateBeyondGrid ? { onNavigateBeyondGrid } : {})} />\n </div>\n ) : null}\n </div>\n {description === undefined ? null : <span className=\"hjm-date-picker__description\">{description}</span>}\n {error === undefined ? null : <span className=\"hjm-date-picker__error\" role=\"alert\">{error}</span>}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"date-picker.js","sourceRoot":"","sources":["../src/date-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n type ComposeCalendarAccessibleName,\n type ResolvedCalendarDateCell,\n} from \"@hjmds/design-contracts/components/calendar\";\nimport {\n resolveDatePickerTriggerText,\n validateDatePickerDescriptor,\n type DatePickerDescriptor,\n type DatePickerOpenChangeReason,\n type DatePickerSize,\n} from \"@hjmds/design-contracts/components/date-picker\";\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport { Calendar, type CalendarOverflow, type CalendarHandle } from \"./calendar.js\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nconst popoverViewportInset = 16;\n\nexport type DatePickerMonthAction = Readonly<{ month: string; label: string }>;\n\nexport type DatePickerProps<Content = unknown> = Readonly<{\n descriptor: DatePickerDescriptor<Content>;\n monthLabel: string;\n composeAccessibleName: ComposeCalendarAccessibleName<Content>;\n previousMonth?: DatePickerMonthAction;\n nextMonth?: DatePickerMonthAction;\n clearLabel: string;\n closeLabel: string;\n size?: DatePickerSize;\n description?: ReactNode;\n error?: ReactNode;\n onNavigateBeyondGrid?: (detail: CalendarOverflow, focusDate: CalendarHandle[\"focusDate\"]) => void;\n renderCellContent?: (cell: ResolvedCalendarDateCell<Content>) => ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Single-date field with an anchored, focus-bearing calendar dialog. */\nexport function DatePicker<Content>({\n descriptor,\n monthLabel,\n composeAccessibleName,\n previousMonth,\n nextMonth,\n clearLabel,\n closeLabel,\n size = \"medium\",\n description,\n error,\n renderCellContent,\n onNavigateBeyondGrid,\n className,\n layoutStyle,\n}: DatePickerProps<Content>) {\n validateDatePickerDescriptor(descriptor);\n const generatedId = useId().replaceAll(\":\", \"\");\n const dialogId = `hjm-date-picker-${generatedId}`;\n const triggerRef = useRef<HTMLButtonElement>(null);\n const dialogRef = useRef<HTMLDivElement>(null);\n const controlledOpen = descriptor.open !== undefined;\n const [internalOpen, setInternalOpen] = useState(descriptor.defaultOpen ?? false);\n const open = controlledOpen ? descriptor.open === true : internalOpen;\n const controlledSelection = descriptor.selectedDate !== undefined;\n const [internalSelection, setInternalSelection] = useState(\n descriptor.defaultSelectedDate ?? null,\n );\n const selectedDate = controlledSelection ? descriptor.selectedDate ?? null : internalSelection;\n\n const closeReasonRef = useRef<DatePickerOpenChangeReason>(\"programmatic\");\n const requestOpen = useCallback((next: boolean, reason: DatePickerOpenChangeReason) => {\n closeReasonRef.current = next ? \"programmatic\" : reason;\n if (!controlledOpen) setInternalOpen(next);\n descriptor.onOpenChange?.(next, reason);\n }, [controlledOpen, descriptor.onOpenChange]);\n useEffect(() => {\n if (open && (descriptor.disabled || descriptor.readOnly)) requestOpen(false, \"programmatic\");\n }, [descriptor.disabled, descriptor.readOnly, open, requestOpen]);\n const commit = (date: string | null, reason: \"activate\" | \"clear\") => {\n // A controlled open field can become read-only while its grid remains mounted.\n if (descriptor.disabled || descriptor.readOnly) return;\n if (!controlledSelection) setInternalSelection(date);\n descriptor.onSelectionChange?.(date, reason);\n requestOpen(false, reason === \"activate\" ? \"selection\" : \"clear\");\n // Clearing a closed field removes the focused clear button without an open transition.\n if (reason === \"clear\") triggerRef.current?.focus();\n };\n\n const wasOpenRef = useRef(open);\n useEffect(() => {\n const wasOpen = wasOpenRef.current;\n wasOpenRef.current = open;\n if (!open) {\n // Outside/Tab dismissal keeps the user's new target; confirmation/Escape returns here.\n if (wasOpen && closeReasonRef.current !== \"outside\" && closeReasonRef.current !== \"blur\") triggerRef.current?.focus();\n return;\n }\n const outside = (event: PointerEvent) => {\n const target = event.target as Node;\n if (!dialogRef.current?.contains(target) && !triggerRef.current?.contains(target)) {\n requestOpen(false, \"outside\");\n }\n };\n document.addEventListener(\"pointerdown\", outside);\n return () => {\n document.removeEventListener(\"pointerdown\", outside);\n };\n }, [open, requestOpen]);\n\n // Keep the popover inside the viewport (2026-09-30 audit WR-0930-3): shift inline, flip up\n // when short. Not portaled: Calendar autoFocus runs before a portal popup is measured.\n useLayoutEffect(() => {\n const popover = dialogRef.current;\n if (!open || !popover) return;\n const place = () => {\n const viewport = window.visualViewport;\n const left = (viewport?.offsetLeft ?? 0) + popoverViewportInset;\n const right = (viewport?.offsetLeft ?? 0) + (viewport?.width ?? document.documentElement.clientWidth) - popoverViewportInset;\n // Layout offset, not translate: mobile Chromium widened the page for a translated box.\n popover.style.insetInlineStart = \"\";\n popover.style.maxInlineSize = `${Math.max(0, right - left)}px`;\n const rect = popover.getBoundingClientRect();\n let shift = rect.right > right ? Math.floor(right - rect.right) : 0;\n if (rect.left + shift < left) shift = Math.ceil(left - rect.left);\n const logical = getComputedStyle(popover).direction === \"rtl\" ? -shift : shift;\n popover.style.insetInlineStart = shift === 0 ? \"\" : `${logical}px`;\n popover.style.insetBlockStart = \"\";\n popover.style.insetBlockEnd = \"\";\n const box = popover.getBoundingClientRect();\n const bottom = (viewport?.offsetTop ?? 0) + (viewport?.height ?? window.innerHeight) - popoverViewportInset;\n const anchor = popover.parentElement?.getBoundingClientRect();\n if (anchor && box.bottom > bottom && anchor.top - box.height - popoverViewportInset >= (viewport?.offsetTop ?? 0)) {\n popover.style.insetBlockStart = \"auto\";\n popover.style.insetBlockEnd = \"calc(100% + var(--hjm-space-xs))\";\n }\n };\n place();\n window.addEventListener(\"resize\", place);\n window.visualViewport?.addEventListener(\"resize\", place);\n return () => {\n window.removeEventListener(\"resize\", place);\n window.visualViewport?.removeEventListener(\"resize\", place);\n };\n }, [open]);\n\n // The outer field owns selection; the shared grid receives only its resolved controlled value.\n const { defaultSelectedDate: _defaultSelectedDate, ...calendarDescriptor } = descriptor;\n const calendarGrid = descriptor.disabled || descriptor.readOnly\n ? { ...descriptor.grid, cells: descriptor.grid.cells.map((cell) => cell.date ? { ...cell, disabled: true } : cell) }\n : descriptor.grid;\n const label = descriptor.label ?? descriptor.accessibilityLabel;\n const triggerText = resolveDatePickerTriggerText(descriptor);\n return (\n <div style={layoutStyle} className={classNames(\"hjm-date-picker\", className)} onBlur={(event) => {\n const field = event.currentTarget;\n queueMicrotask(() => {\n if (open && dialogRef.current && !field.contains(document.activeElement)) requestOpen(false, \"blur\");\n });\n }} data-disabled={descriptor.disabled || undefined} data-invalid={descriptor.invalid || error !== undefined || undefined} data-size={size}>\n {descriptor.label === undefined ? null : <span className=\"hjm-date-picker__label\">{descriptor.label}</span>}\n <div className=\"hjm-date-picker__anchor\">\n <button\n aria-controls={open ? dialogId : undefined}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-label={descriptor.accessibilityLabel ?? `${label}, ${triggerText}`}\n className=\"hjm-date-picker__trigger\"\n disabled={descriptor.disabled}\n onClick={() => !descriptor.readOnly && requestOpen(!open, \"trigger\")}\n ref={triggerRef}\n type=\"button\"\n >\n <span aria-hidden=\"true\">▣</span>\n <span data-placeholder={descriptor.displayValue === null || undefined}>{triggerText}</span>\n </button>\n {selectedDate === null ? null : (\n <button aria-label={clearLabel} className=\"hjm-date-picker__clear\" disabled={descriptor.disabled || descriptor.readOnly} onClick={() => commit(null, \"clear\")} type=\"button\">×</button>\n )}\n {open ? (\n <div aria-label={label} className=\"hjm-date-picker__popover\" id={dialogId} ref={dialogRef} role=\"dialog\" onKeyDown={(event) => { if (event.key === \"Escape\") { event.preventDefault(); requestOpen(false, \"escape\"); } }}>\n <button aria-label={closeLabel} className=\"hjm-date-picker__calendar-close\" onClick={() => requestOpen(false, \"trigger\")} type=\"button\">×</button>\n <Calendar descriptor={{ ...calendarDescriptor, grid: calendarGrid, monthLabel, selectedDate, onSelectionChange: (date) => commit(date, \"activate\") }}\n composeAccessibleName={composeAccessibleName} size={size} autoFocus\n {...(previousMonth ? { previousMonth } : {})} {...(nextMonth ? { nextMonth } : {})}\n {...(renderCellContent ? { renderCellContent } : {})} {...(onNavigateBeyondGrid ? { onNavigateBeyondGrid } : {})} />\n </div>\n ) : null}\n </div>\n {description === undefined ? null : <span className=\"hjm-date-picker__description\">{description}</span>}\n {error === undefined ? null : <span className=\"hjm-date-picker__error\" role=\"alert\">{error}</span>}\n </div>\n );\n}\n"]}
package/dist/display.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type BadgeSize, type BadgeTone, type BadgeVariant as ContractBadgeVariant, type ListRowDensity, type ListRowLeadingShape } from "@hjmds/design-contracts/recipes";
1
+ import { listRowRecipe, type BadgeSize, type BadgeTone, type BadgeVariant as ContractBadgeVariant, type ListRowDensity, type ListRowLeadingShape } from "@hjmds/design-contracts/recipes";
2
2
  import { type TagTone } from "@hjmds/design-contracts/components/tag";
3
3
  import { type CardHeadingLevel } from "@hjmds/design-contracts/components/card";
4
4
  import { type SurfacePadding, type SurfaceRadius, type SurfaceTone } from "@hjmds/design-contracts/recipes/base";
@@ -43,6 +43,9 @@ export type CardProps = Omit<HTMLAttributes<HTMLElement>, "title"> & Readonly<{
43
43
  actions?: ReactNode;
44
44
  headingLevel?: CardHeadingLevel;
45
45
  selected?: boolean;
46
+ /** Whole-card activation. Do not combine with interactive children or actions. */
47
+ onActivate?: () => void;
48
+ disabled?: boolean;
46
49
  tone?: SurfaceTone;
47
50
  bordered?: boolean;
48
51
  padding?: SurfacePadding;
@@ -58,6 +61,9 @@ export declare const Card: import("react").ForwardRefExoticComponent<Omit<HTMLAt
58
61
  actions?: ReactNode;
59
62
  headingLevel?: CardHeadingLevel;
60
63
  selected?: boolean;
64
+ /** Whole-card activation. Do not combine with interactive children or actions. */
65
+ onActivate?: () => void;
66
+ disabled?: boolean;
61
67
  tone?: SurfaceTone;
62
68
  bordered?: boolean;
63
69
  padding?: SurfacePadding;
@@ -71,6 +77,8 @@ export type ListRowProps = Omit<HTMLAttributes<HTMLElement>, "title" | "onClick"
71
77
  leading?: ReactNode;
72
78
  trailing?: ReactNode;
73
79
  density?: ListRowDensity;
80
+ /** Semantic emphasis for destructive destinations; selection stays independent. */
81
+ tone?: keyof typeof listRowRecipe.tones;
74
82
  /** Frame the ListRow paints around `leading`; the recipe owns its size. */
75
83
  leadingShape?: ListRowLeadingShape;
76
84
  selected?: boolean;
@@ -94,6 +102,8 @@ export declare const ListRow: import("react").ForwardRefExoticComponent<Omit<HTM
94
102
  leading?: ReactNode;
95
103
  trailing?: ReactNode;
96
104
  density?: ListRowDensity;
105
+ /** Semantic emphasis for destructive destinations; selection stays independent. */
106
+ tone?: keyof typeof listRowRecipe.tones;
97
107
  /** Frame the ListRow paints around `leading`; the recipe owns its size. */
98
108
  leadingShape?: ListRowLeadingShape;
99
109
  selected?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"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"}
package/dist/display.js CHANGED
@@ -17,13 +17,21 @@ export const Tag = forwardRef(function Tag({ children, tone, className, layoutSt
17
17
  });
18
18
  return (_jsx("span", { ...props, style: { ...style, ...layoutStyle }, ref: ref, className: classNames("hjm-tag", className), "data-tone": descriptor.tone, children: _jsx("span", { className: "hjm-tag__label", children: descriptor.label }) }));
19
19
  });
20
- export const Card = forwardRef(function Card({ title, description, leading, media, actions, headingLevel = cardRecipe.defaults.headingLevel, selected = cardRecipe.defaults.selected, tone = cardRecipe.defaults.tone, bordered = cardRecipe.defaults.bordered, padding = cardRecipe.defaults.padding, radius, className, children, ...props }, ref) {
20
+ export const Card = forwardRef(function Card({ title, description, leading, media, actions, headingLevel = cardRecipe.defaults.headingLevel, selected = cardRecipe.defaults.selected, onActivate, disabled = false, tone = cardRecipe.defaults.tone, bordered = cardRecipe.defaults.bordered, padding = cardRecipe.defaults.padding, radius, className, children, ...props }, ref) {
21
+ if (onActivate && (!props["aria-label"]?.trim() || actions !== undefined)) {
22
+ throw new TypeError("Interactive Card requires aria-label and no actions");
23
+ }
21
24
  const hasHeader = leading !== undefined || title !== undefined || description !== undefined;
22
- return (_jsxs(Surface, { ...props, ref: ref, as: "article", tone: selected ? cardRecipe.selectedTone : tone, bordered: bordered, ...(radius === undefined ? {} : { radius }), className: classNames("hjm-card", className), "data-state": selected ? "selected" : "idle", children: [media ? _jsx("div", { className: "hjm-card__media", "data-slot": "media", children: media }) : null, _jsxs("div", { className: "hjm-card__body", "data-slot": "body", style: { padding: surfaceGeometry.paddings[padding] }, children: [hasHeader ? (_jsxs("div", { className: "hjm-card__header", "data-slot": "header", children: [leading === undefined ? null : (_jsx("span", { className: "hjm-card__leading", "data-slot": "leading", children: leading })), _jsxs("div", { className: "hjm-card__copy", children: [title === undefined
25
+ return (_jsxs(Surface, { ...props, ref: ref, as: onActivate ? "button" : "article", ...(onActivate ? {
26
+ type: "button", disabled, "aria-pressed": selected,
27
+ "data-interactive": true, onClick: () => { if (!disabled)
28
+ onActivate(); },
29
+ } : {}), tone: selected ? cardRecipe.selectedTone : tone, bordered: bordered, ...(radius === undefined ? {} : { radius }), className: classNames("hjm-card", className), "data-state": onActivate && disabled ? "disabled" : selected ? "selected" : "idle", style: { "--hjm-card-disabled-opacity": cardRecipe.interaction.disabledOpacity,
30
+ "--hjm-card-pressed-opacity": cardRecipe.interaction.pressedOpacity, ...props.style }, children: [media ? _jsx("div", { className: "hjm-card__media", "data-slot": "media", children: media }) : null, _jsxs("div", { className: "hjm-card__body", "data-slot": "body", style: { padding: surfaceGeometry.paddings[padding] }, children: [hasHeader ? (_jsxs("div", { className: "hjm-card__header", "data-slot": "header", children: [leading === undefined ? null : (_jsx("span", { className: "hjm-card__leading", "data-slot": "leading", children: leading })), _jsxs("div", { className: "hjm-card__copy", children: [title === undefined
23
31
  ? null
24
32
  : createElement(`h${headingLevel}`, { className: "hjm-card__title", "data-slot": "title" }, title), description === undefined ? null : (_jsx(Text, { as: "p", tone: "muted", className: "hjm-card__description", "data-slot": "description", children: description }))] })] })) : null, children === undefined ? null : (_jsx("div", { className: "hjm-card__content", "data-slot": "content", children: children }))] }), actions ? _jsx("div", { className: "hjm-card__actions", "data-slot": "actions", children: actions }) : null] }));
25
33
  });
26
- export const ListRow = forwardRef(function ListRow({ title, description, leading, trailing, density: densityProp, leadingShape = "square", selected = listRowRecipe.defaults.selected, disabled = false, loading = false, loadingLabel, href, onClick, className, layoutStyle, style, ...props }, ref) {
34
+ export const ListRow = forwardRef(function ListRow({ title, description, leading, trailing, density: densityProp, tone = listRowRecipe.defaults.tone, leadingShape = "square", selected = listRowRecipe.defaults.selected, disabled = false, loading = false, loadingLabel, href, onClick, className, layoutStyle, style, ...props }, ref) {
27
35
  // The hook runs unconditionally — `??` would short-circuit it and break the
28
36
  // rules of hooks on the very first row that passes `density`.
29
37
  const densityDefault = useHjmDensityDefault({
@@ -33,7 +41,7 @@ export const ListRow = forwardRef(function ListRow({ title, description, leading
33
41
  const density = densityProp ?? densityDefault;
34
42
  if (loading) {
35
43
  // A loading row is never interactive: there is nothing to activate yet.
36
- return (_jsxs("div", { ...props, ref: ref, role: "status", "aria-busy": "true", "aria-label": loadingLabel, className: classNames("hjm-list-row", "hjm-list-row--loading", className), "data-density": density, "data-lines": description ? "two" : "one", "data-state": "loading", style: { ...style, ...layoutStyle }, children: [leading ? _jsx("span", { className: "hjm-list-row__leading", "data-shape": leadingShape, "data-placeholder": "" }) : null, _jsxs("span", { className: "hjm-list-row__content", children: [_jsx("span", { className: "hjm-list-row__title", "data-placeholder": "" }), description ? _jsx("span", { className: "hjm-list-row__description", "data-placeholder": "" }) : null] }), trailing ? _jsx("span", { className: "hjm-list-row__trailing", "data-placeholder": "" }) : null] }));
44
+ return (_jsxs("div", { ...props, ref: ref, role: loadingLabel ? "status" : undefined, "aria-busy": loadingLabel ? true : undefined, "aria-hidden": loadingLabel ? undefined : true, "aria-label": loadingLabel, className: classNames("hjm-list-row", "hjm-list-row--loading", className), "data-density": density, "data-lines": description ? "two" : "one", "data-state": "loading", style: { ...style, ...layoutStyle }, children: [leading ? _jsx("span", { className: "hjm-list-row__leading", "data-shape": leadingShape, "data-placeholder": "" }) : null, _jsxs("span", { className: "hjm-list-row__content", children: [_jsx("span", { className: "hjm-list-row__title", "data-placeholder": "", style: { width: `${listRowRecipe.loading.titleWidthPercent}%` } }), description ? _jsx("span", { className: "hjm-list-row__description", "data-placeholder": "", style: { width: `${listRowRecipe.loading.descriptionWidthPercent}%` } }) : null] }), trailing ? _jsx("span", { className: "hjm-list-row__trailing", "data-placeholder": "", style: { width: listRowRecipe.loading.trailingWidth } }) : null] }));
37
45
  }
38
46
  const element = href ? "a" : onClick ? "button" : "div";
39
47
  const interactiveProps = href
@@ -57,6 +65,7 @@ export const ListRow = forwardRef(function ListRow({ title, description, leading
57
65
  ref,
58
66
  className: classNames("hjm-list-row", className),
59
67
  "data-density": density,
68
+ "data-tone": tone,
60
69
  // One- and two-line rows have different minimum heights in the recipe;
61
70
  // the web renderer used a single hardcoded value until now.
62
71
  "data-lines": description ? "two" : "one",
@@ -1 +1 @@
1
- {"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n badgeRecipe,\n listRowRecipe,\n type BadgeSize,\n type BadgeTone,\n type BadgeVariant as ContractBadgeVariant,\n type ListRowDensity,\n type ListRowLeadingShape,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n resolveTagDescriptor,\n type TagTone,\n} from \"@hjmds/design-contracts/components/tag\";\nimport {\n cardRecipe,\n type CardHeadingLevel,\n} from \"@hjmds/design-contracts/components/card\";\nimport {\n surfaceGeometry,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n createElement,\n forwardRef,\n type HTMLAttributes,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useHjmDensityDefault } from \"./provider.js\";\nimport { Surface, Text } from \"./layout.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type { CardHeadingLevel } from \"@hjmds/design-contracts/components/card\";\nexport type { TagTone } from \"@hjmds/design-contracts/components/tag\";\nexport type BadgeVariant = ContractBadgeVariant;\n\nexport type BadgeProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{\n tone?: BadgeTone;\n size?: BadgeSize;\n variant?: BadgeVariant;\n leading?: ReactNode;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n {\n tone = badgeRecipe.defaults.tone,\n size = badgeRecipe.defaults.size,\n variant = badgeRecipe.defaults.variant,\n leading,\n className,\n children,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-badge\", className)}\n data-tone={tone}\n data-size={size}\n data-variant={variant}\n >\n {leading === undefined ? null : (\n <span aria-hidden=\"true\" className=\"hjm-badge__icon\">\n {leading}\n </span>\n )}\n <span className=\"hjm-badge__label\">{children}</span>\n </span>\n );\n});\n\nexport type TagProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n children: string;\n tone?: TagTone;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Tag = forwardRef<HTMLSpanElement, TagProps>(function Tag(\n { children, tone, className, layoutStyle, style, ...props },\n ref,\n) {\n const descriptor = resolveTagDescriptor({\n label: children,\n ...(tone === undefined ? {} : { tone }),\n });\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-tag\", className)}\n data-tone={descriptor.tone}\n >\n <span className=\"hjm-tag__label\">{descriptor.label}</span>\n </span>\n );\n});\n\nexport type CardProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n media?: ReactNode;\n actions?: ReactNode;\n headingLevel?: CardHeadingLevel;\n selected?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement; forwarded to the root Surface, which applies it. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Card = forwardRef<HTMLElement, CardProps>(function Card(\n {\n title,\n description,\n leading,\n media,\n actions,\n headingLevel = cardRecipe.defaults.headingLevel,\n selected = cardRecipe.defaults.selected,\n tone = cardRecipe.defaults.tone,\n bordered = cardRecipe.defaults.bordered,\n padding = cardRecipe.defaults.padding,\n radius,\n className,\n children,\n ...props\n },\n ref,\n) {\n const hasHeader =\n leading !== undefined || title !== undefined || description !== undefined;\n\n return (\n <Surface\n {...props}\n ref={ref}\n as=\"article\"\n tone={selected ? cardRecipe.selectedTone : tone}\n bordered={bordered}\n {...(radius === undefined ? {} : { radius })}\n className={classNames(\"hjm-card\", className)}\n data-state={selected ? \"selected\" : \"idle\"}\n >\n {media ? <div className=\"hjm-card__media\" data-slot=\"media\">{media}</div> : null}\n <div\n className=\"hjm-card__body\"\n data-slot=\"body\"\n style={{ padding: surfaceGeometry.paddings[padding] }}\n >\n {hasHeader ? (\n <div className=\"hjm-card__header\" data-slot=\"header\">\n {leading === undefined ? null : (\n <span className=\"hjm-card__leading\" data-slot=\"leading\">\n {leading}\n </span>\n )}\n <div className=\"hjm-card__copy\">\n {title === undefined\n ? null\n : createElement(\n `h${headingLevel}`,\n { className: \"hjm-card__title\", \"data-slot\": \"title\" },\n title,\n )}\n {description === undefined ? null : (\n <Text\n as=\"p\"\n tone=\"muted\"\n className=\"hjm-card__description\"\n data-slot=\"description\"\n >\n {description}\n </Text>\n )}\n </div>\n </div>\n ) : null}\n {children === undefined ? null : (\n <div className=\"hjm-card__content\" data-slot=\"content\">{children}</div>\n )}\n </div>\n {actions ? <div className=\"hjm-card__actions\" data-slot=\"actions\">{actions}</div> : null}\n </Surface>\n );\n});\n\nexport type ListRowProps = Omit<HTMLAttributes<HTMLElement>, \"title\" | \"onClick\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n trailing?: ReactNode;\n density?: ListRowDensity;\n /** Frame the ListRow paints around `leading`; the recipe owns its size. */\n leadingShape?: ListRowLeadingShape;\n selected?: boolean;\n disabled?: boolean;\n /**\n * Placeholder row while the real one loads. It keeps the row's own height\n * and slot geometry, so a list does not jump when the content arrives —\n * which is exactly what a product-owned skeleton next to the list cannot do.\n */\n loading?: boolean;\n /** Localized status text announced while `loading`. */\n loadingLabel?: string;\n href?: string;\n onClick?: MouseEventHandler<HTMLElement>;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const ListRow = forwardRef<HTMLElement, ListRowProps>(function ListRow(\n {\n title,\n description,\n leading,\n trailing,\n density: densityProp,\n leadingShape = \"square\",\n selected = listRowRecipe.defaults.selected,\n disabled = false,\n loading = false,\n loadingLabel,\n href,\n onClick,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n // The hook runs unconditionally — `??` would short-circuit it and break the\n // rules of hooks on the very first row that passes `density`.\n const densityDefault = useHjmDensityDefault({\n comfortable: listRowRecipe.defaults.density,\n compact: \"compact\",\n });\n const density = densityProp ?? densityDefault;\n if (loading) {\n // A loading row is never interactive: there is nothing to activate yet.\n return (\n <div\n {...props}\n ref={ref as React.Ref<HTMLDivElement>}\n role=\"status\"\n aria-busy=\"true\"\n aria-label={loadingLabel}\n className={classNames(\"hjm-list-row\", \"hjm-list-row--loading\", className)}\n data-density={density}\n data-lines={description ? \"two\" : \"one\"}\n data-state=\"loading\"\n style={{ ...style, ...layoutStyle }}\n >\n {leading ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape} data-placeholder=\"\" /> : null}\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\" data-placeholder=\"\" />\n {description ? <span className=\"hjm-list-row__description\" data-placeholder=\"\" /> : null}\n </span>\n {trailing ? <span className=\"hjm-list-row__trailing\" data-placeholder=\"\" /> : null}\n </div>\n );\n }\n const element = href ? \"a\" : onClick ? \"button\" : \"div\";\n const interactiveProps = href\n ? {\n href: disabled ? undefined : href,\n \"aria-current\": selected ? (\"page\" as const) : undefined,\n \"aria-disabled\": disabled || undefined,\n tabIndex: disabled ? -1 : undefined,\n }\n : onClick\n ? {\n type: \"button\" as const,\n onClick: disabled ? undefined : onClick,\n disabled,\n \"aria-pressed\": selected,\n }\n : {};\n\n return createElement(\n element,\n {\n ...props,\n ...interactiveProps,\n ref,\n className: classNames(\"hjm-list-row\", className),\n \"data-density\": density,\n // One- and two-line rows have different minimum heights in the recipe;\n // the web renderer used a single hardcoded value until now.\n \"data-lines\": description ? \"two\" : \"one\",\n \"data-state\": disabled ? \"disabled\" : selected ? \"selected\" : \"idle\",\n // Placement wins over the legacy `style`, matching Surface's ordering.\n style: { ...style, ...layoutStyle },\n },\n leading\n ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape}>{leading}</span>\n : null,\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\">{title}</span>\n {description ? (\n <span className=\"hjm-list-row__description\">{description}</span>\n ) : null}\n </span>,\n trailing ? <span className=\"hjm-list-row__trailing\">{trailing}</span> : null,\n );\n});\n"]}
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n badgeRecipe,\n listRowRecipe,\n type BadgeSize,\n type BadgeTone,\n type BadgeVariant as ContractBadgeVariant,\n type ListRowDensity,\n type ListRowLeadingShape,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n resolveTagDescriptor,\n type TagTone,\n} from \"@hjmds/design-contracts/components/tag\";\nimport {\n cardRecipe,\n type CardHeadingLevel,\n} from \"@hjmds/design-contracts/components/card\";\nimport {\n surfaceGeometry,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n createElement,\n forwardRef,\n type CSSProperties,\n type HTMLAttributes,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useHjmDensityDefault } from \"./provider.js\";\nimport { Surface, Text } from \"./layout.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type { CardHeadingLevel } from \"@hjmds/design-contracts/components/card\";\nexport type { TagTone } from \"@hjmds/design-contracts/components/tag\";\nexport type BadgeVariant = ContractBadgeVariant;\n\nexport type BadgeProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{\n tone?: BadgeTone;\n size?: BadgeSize;\n variant?: BadgeVariant;\n leading?: ReactNode;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n {\n tone = badgeRecipe.defaults.tone,\n size = badgeRecipe.defaults.size,\n variant = badgeRecipe.defaults.variant,\n leading,\n className,\n children,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-badge\", className)}\n data-tone={tone}\n data-size={size}\n data-variant={variant}\n >\n {leading === undefined ? null : (\n <span aria-hidden=\"true\" className=\"hjm-badge__icon\">\n {leading}\n </span>\n )}\n <span className=\"hjm-badge__label\">{children}</span>\n </span>\n );\n});\n\nexport type TagProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n children: string;\n tone?: TagTone;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Tag = forwardRef<HTMLSpanElement, TagProps>(function Tag(\n { children, tone, className, layoutStyle, style, ...props },\n ref,\n) {\n const descriptor = resolveTagDescriptor({\n label: children,\n ...(tone === undefined ? {} : { tone }),\n });\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-tag\", className)}\n data-tone={descriptor.tone}\n >\n <span className=\"hjm-tag__label\">{descriptor.label}</span>\n </span>\n );\n});\n\nexport type CardProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n media?: ReactNode;\n actions?: ReactNode;\n headingLevel?: CardHeadingLevel;\n selected?: boolean;\n /** Whole-card activation. Do not combine with interactive children or actions. */\n onActivate?: () => void;\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement; forwarded to the root Surface, which applies it. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Card = forwardRef<HTMLElement, CardProps>(function Card(\n {\n title,\n description,\n leading,\n media,\n actions,\n headingLevel = cardRecipe.defaults.headingLevel,\n selected = cardRecipe.defaults.selected,\n onActivate,\n disabled = false,\n tone = cardRecipe.defaults.tone,\n bordered = cardRecipe.defaults.bordered,\n padding = cardRecipe.defaults.padding,\n radius,\n className,\n children,\n ...props\n },\n ref,\n) {\n if (onActivate && (!props[\"aria-label\"]?.trim() || actions !== undefined)) {\n throw new TypeError(\"Interactive Card requires aria-label and no actions\");\n }\n const hasHeader =\n leading !== undefined || title !== undefined || description !== undefined;\n\n return (\n <Surface\n {...props}\n ref={ref}\n as={onActivate ? \"button\" : \"article\"}\n {...(onActivate ? {\n type: \"button\" as const, disabled, \"aria-pressed\": selected,\n \"data-interactive\": true, onClick: () => { if (!disabled) onActivate(); },\n } : {})}\n tone={selected ? cardRecipe.selectedTone : tone}\n bordered={bordered}\n {...(radius === undefined ? {} : { radius })}\n className={classNames(\"hjm-card\", className)}\n data-state={onActivate && disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"}\n style={{ \"--hjm-card-disabled-opacity\": cardRecipe.interaction.disabledOpacity,\n \"--hjm-card-pressed-opacity\": cardRecipe.interaction.pressedOpacity, ...props.style } as CSSProperties}\n >\n {media ? <div className=\"hjm-card__media\" data-slot=\"media\">{media}</div> : null}\n <div\n className=\"hjm-card__body\"\n data-slot=\"body\"\n style={{ padding: surfaceGeometry.paddings[padding] }}\n >\n {hasHeader ? (\n <div className=\"hjm-card__header\" data-slot=\"header\">\n {leading === undefined ? null : (\n <span className=\"hjm-card__leading\" data-slot=\"leading\">\n {leading}\n </span>\n )}\n <div className=\"hjm-card__copy\">\n {title === undefined\n ? null\n : createElement(\n `h${headingLevel}`,\n { className: \"hjm-card__title\", \"data-slot\": \"title\" },\n title,\n )}\n {description === undefined ? null : (\n <Text\n as=\"p\"\n tone=\"muted\"\n className=\"hjm-card__description\"\n data-slot=\"description\"\n >\n {description}\n </Text>\n )}\n </div>\n </div>\n ) : null}\n {children === undefined ? null : (\n <div className=\"hjm-card__content\" data-slot=\"content\">{children}</div>\n )}\n </div>\n {actions ? <div className=\"hjm-card__actions\" data-slot=\"actions\">{actions}</div> : null}\n </Surface>\n );\n});\n\nexport type ListRowProps = Omit<HTMLAttributes<HTMLElement>, \"title\" | \"onClick\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n trailing?: ReactNode;\n density?: ListRowDensity;\n /** Semantic emphasis for destructive destinations; selection stays independent. */\n tone?: keyof typeof listRowRecipe.tones;\n /** Frame the ListRow paints around `leading`; the recipe owns its size. */\n leadingShape?: ListRowLeadingShape;\n selected?: boolean;\n disabled?: boolean;\n /**\n * Placeholder row while the real one loads. It keeps the row's own height\n * and slot geometry, so a list does not jump when the content arrives —\n * which is exactly what a product-owned skeleton next to the list cannot do.\n */\n loading?: boolean;\n /** Localized status text announced while `loading`. */\n loadingLabel?: string;\n href?: string;\n onClick?: MouseEventHandler<HTMLElement>;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const ListRow = forwardRef<HTMLElement, ListRowProps>(function ListRow(\n {\n title,\n description,\n leading,\n trailing,\n density: densityProp,\n tone = listRowRecipe.defaults.tone,\n leadingShape = \"square\",\n selected = listRowRecipe.defaults.selected,\n disabled = false,\n loading = false,\n loadingLabel,\n href,\n onClick,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n // The hook runs unconditionally — `??` would short-circuit it and break the\n // rules of hooks on the very first row that passes `density`.\n const densityDefault = useHjmDensityDefault({\n comfortable: listRowRecipe.defaults.density,\n compact: \"compact\",\n });\n const density = densityProp ?? densityDefault;\n if (loading) {\n // A loading row is never interactive: there is nothing to activate yet.\n return (\n <div\n {...props}\n ref={ref as React.Ref<HTMLDivElement>}\n role={loadingLabel ? \"status\" : undefined}\n aria-busy={loadingLabel ? true : undefined}\n aria-hidden={loadingLabel ? undefined : true}\n aria-label={loadingLabel}\n className={classNames(\"hjm-list-row\", \"hjm-list-row--loading\", className)}\n data-density={density}\n data-lines={description ? \"two\" : \"one\"}\n data-state=\"loading\"\n style={{ ...style, ...layoutStyle }}\n >\n {leading ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape} data-placeholder=\"\" /> : null}\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.titleWidthPercent}%` }} />\n {description ? <span className=\"hjm-list-row__description\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.descriptionWidthPercent}%` }} /> : null}\n </span>\n {trailing ? <span className=\"hjm-list-row__trailing\" data-placeholder=\"\" style={{ width: listRowRecipe.loading.trailingWidth }} /> : null}\n </div>\n );\n }\n const element = href ? \"a\" : onClick ? \"button\" : \"div\";\n const interactiveProps = href\n ? {\n href: disabled ? undefined : href,\n \"aria-current\": selected ? (\"page\" as const) : undefined,\n \"aria-disabled\": disabled || undefined,\n tabIndex: disabled ? -1 : undefined,\n }\n : onClick\n ? {\n type: \"button\" as const,\n onClick: disabled ? undefined : onClick,\n disabled,\n \"aria-pressed\": selected,\n }\n : {};\n\n return createElement(\n element,\n {\n ...props,\n ...interactiveProps,\n ref,\n className: classNames(\"hjm-list-row\", className),\n \"data-density\": density,\n \"data-tone\": tone,\n // One- and two-line rows have different minimum heights in the recipe;\n // the web renderer used a single hardcoded value until now.\n \"data-lines\": description ? \"two\" : \"one\",\n \"data-state\": disabled ? \"disabled\" : selected ? \"selected\" : \"idle\",\n // Placement wins over the legacy `style`, matching Surface's ordering.\n style: { ...style, ...layoutStyle },\n },\n leading\n ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape}>{leading}</span>\n : null,\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\">{title}</span>\n {description ? (\n <span className=\"hjm-list-row__description\">{description}</span>\n ) : null}\n </span>,\n trailing ? <span className=\"hjm-list-row__trailing\">{trailing}</span> : null,\n );\n});\n"]}
@@ -5,9 +5,9 @@ export type DurationFieldProps = DurationRange & Readonly<{
5
5
  onValueChange: (seconds: number) => void;
6
6
  labels: DurationFieldLabels;
7
7
  disabled?: boolean;
8
- className?: string; /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
8
+ className?: string;
9
9
  layoutStyle?: HjmCompositionStyleProp;
10
10
  }>;
11
- /** A NumberField composition; value and limits always use whole seconds. */
11
+ /** Units and limits remain in seconds; FieldGroup owns grouping and edit lifetime. */
12
12
  export declare function DurationField({ value, onValueChange, labels, min, max, disabled, className, layoutStyle }: DurationFieldProps): import("react").JSX.Element;
13
13
  //# sourceMappingURL=duration-field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"duration-field.d.ts","sourceRoot":"","sources":["../src/duration-field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAE3I,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC,gGAAgG;IAAC,WAAW,CAAC,EAAE,uBAAuB,CAAC;CAAE,CAAC,CAAC;AACrU,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,GAAO,EAAE,GAAG,EAAE,QAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,kBAAkB,+BAWzI"}
1
+ {"version":3,"file":"duration-field.d.ts","sourceRoot":"","sources":["../src/duration-field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAG3I,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAAC,CAAC;AAEnO,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,GAAO,EAAE,GAAG,EAAE,QAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,kBAAkB,+BAazI"}
@@ -1,9 +1,17 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { changeDurationUnit, resolveDuration } from "@hjmds/design-contracts/duration-field";
3
3
  import { NumberField } from "./number-field.js";
4
- /** A NumberField composition; value and limits always use whole seconds. */
4
+ import { FieldGroup } from "./field-group.js";
5
+ const units = ["hours", "minutes", "seconds"];
6
+ /** Units and limits remain in seconds; FieldGroup owns grouping and edit lifetime. */
5
7
  export function DurationField({ value, onValueChange, labels, min = 0, max, disabled = false, className, layoutStyle }) {
6
8
  const parts = resolveDuration(value, { min, max });
7
- return _jsxs("fieldset", { className: className, disabled: disabled, style: { border: 0, margin: 0, padding: 0, minWidth: 0, ...layoutStyle }, children: [_jsx("legend", { style: { marginBlockEnd: "var(--hjm-space-sm)" }, children: labels.label }), _jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 10ch), 1fr))", gap: "var(--hjm-space-md)" }, children: ["hours", "minutes", "seconds"].map(unit => _jsx(NumberField, { label: labels[unit], min: 0, max: unit === "hours" ? Math.max(1, Math.floor(max / 3600)) : 59, value: parts[unit], disabled: disabled || (unit === "hours" && max < 3600), step: 1, incrementLabel: labels.increment(unit), decrementLabel: labels.decrement(unit), onValueChange: next => onValueChange(changeDurationUnit(value, unit, next, { min, max })) }, unit)) })] });
9
+ return _jsx(FieldGroup, { layout: "inline", ...(className === undefined ? {} : { className }), ...(layoutStyle === undefined ? {} : { layoutStyle: layoutStyle }), descriptor: { label: labels.label, disabled,
10
+ fields: units.map(unit => ({ id: unit, label: labels[unit], disabled: unit === "hours" && max < 3600 })) }, renderField: ({ id, controlProps, guardChange }) => {
11
+ const unit = units.find(unit => unit === id);
12
+ if (!unit)
13
+ return null;
14
+ return _jsx(NumberField, { ...controlProps, min: 0, max: unit === "hours" ? Math.max(1, Math.floor(max / 3600)) : 59, value: parts[unit], step: 1, incrementLabel: labels.increment(unit), decrementLabel: labels.decrement(unit), onValueChange: guardChange((next) => onValueChange(changeDurationUnit(value, unit, next, { min, max }))) });
15
+ } });
8
16
  }
9
17
  //# sourceMappingURL=duration-field.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"duration-field.js","sourceRoot":"","sources":["../src/duration-field.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAgD,MAAM,wCAAwC,CAAC;AAC3I,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,EAAE,SAAS,EAAE,WAAW,EAAsB;IACxI,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACnD,OAAO,oBAAU,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,WAAW,EAAE,aACjI,iBAAQ,KAAK,EAAE,EAAE,cAAc,EAAE,qBAAqB,EAAE,YAAG,MAAM,CAAC,KAAK,GAAU,EACjF,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,gDAAgD,EAAE,GAAG,EAAE,qBAAqB,EAAE,YAC9H,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAC,WAAW,IAAY,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAC3K,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EACnF,cAAc,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAC9E,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,IAHjB,IAAI,CAGiB,CAAC,GAC5F,IACG,CAAC;AACd,CAAC","sourcesContent":["import { changeDurationUnit, resolveDuration, type DurationFieldLabels, type DurationRange } from \"@hjmds/design-contracts/duration-field\";\nimport { NumberField } from \"./number-field.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nexport type DurationFieldProps = DurationRange & Readonly<{ value: number; onValueChange: (seconds: number) => void; labels: DurationFieldLabels; disabled?: boolean; className?: string; /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */ layoutStyle?: HjmCompositionStyleProp; }>;\n/** A NumberField composition; value and limits always use whole seconds. */\nexport function DurationField({ value, onValueChange, labels, min = 0, max, disabled = false, className, layoutStyle }: DurationFieldProps) {\n const parts = resolveDuration(value, { min, max });\n return <fieldset className={className} disabled={disabled} style={{ border: 0, margin: 0, padding: 0, minWidth: 0, ...layoutStyle }}>\n <legend style={{ marginBlockEnd: \"var(--hjm-space-sm)\" }}>{labels.label}</legend>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit, minmax(min(100%, 10ch), 1fr))\", gap: \"var(--hjm-space-md)\" }}>\n {([\"hours\", \"minutes\", \"seconds\"] as const).map(unit => <NumberField key={unit} label={labels[unit]} min={0} max={unit === \"hours\" ? Math.max(1, Math.floor(max / 3600)) : 59}\n value={parts[unit]} disabled={disabled || (unit === \"hours\" && max < 3600)} step={1}\n incrementLabel={labels.increment(unit)} decrementLabel={labels.decrement(unit)}\n onValueChange={next => onValueChange(changeDurationUnit(value, unit, next, { min, max }))} />)}\n </div>\n </fieldset>;\n}\n"]}
1
+ {"version":3,"file":"duration-field.js","sourceRoot":"","sources":["../src/duration-field.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAgD,MAAM,wCAAwC,CAAC;AAC3I,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAU,CAAC;AACvD,sFAAsF;AACtF,MAAM,UAAU,aAAa,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,EAAE,SAAS,EAAE,WAAW,EAAsB;IACxI,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACnD,OAAO,KAAC,UAAU,IAAC,MAAM,EAAC,QAAQ,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,KAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,EACxJ,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ;YACzC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,KAAK,OAAO,IAAI,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,EAC5G,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE;YACjD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;YAC7C,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YACvB,OAAO,KAAC,WAAW,OAAK,YAAY,EAClC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EACrG,cAAc,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAC9E,aAAa,EAAE,WAAW,CAAC,CAAC,IAAmB,EAAE,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAI,CAAC;QAChI,CAAC,GAAI,CAAC;AACV,CAAC","sourcesContent":["import { changeDurationUnit, resolveDuration, type DurationFieldLabels, type DurationRange } from \"@hjmds/design-contracts/duration-field\";\nimport { NumberField } from \"./number-field.js\";\nimport { FieldGroup } from \"./field-group.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nexport type DurationFieldProps = DurationRange & Readonly<{ value: number; onValueChange: (seconds: number) => void; labels: DurationFieldLabels; disabled?: boolean; className?: string; layoutStyle?: HjmCompositionStyleProp }>;\nconst units = [\"hours\", \"minutes\", \"seconds\"] as const;\n/** Units and limits remain in seconds; FieldGroup owns grouping and edit lifetime. */\nexport function DurationField({ value, onValueChange, labels, min = 0, max, disabled = false, className, layoutStyle }: DurationFieldProps) {\n const parts = resolveDuration(value, { min, max });\n return <FieldGroup layout=\"inline\" {...(className === undefined ? {} : { className })} {...(layoutStyle === undefined ? {} : { layoutStyle: layoutStyle })}\n descriptor={{ label: labels.label, disabled,\n fields: units.map(unit => ({ id: unit, label: labels[unit], disabled: unit === \"hours\" && max < 3600 })) }}\n renderField={({ id, controlProps, guardChange }) => {\n const unit = units.find(unit => unit === id);\n if (!unit) return null;\n return <NumberField {...controlProps}\n min={0} max={unit === \"hours\" ? Math.max(1, Math.floor(max / 3600)) : 59} value={parts[unit]} step={1}\n incrementLabel={labels.increment(unit)} decrementLabel={labels.decrement(unit)}\n onValueChange={guardChange((next: number | null) => onValueChange(changeDurationUnit(value, unit, next, { min, max })))} />;\n }} />;\n}\n"]}
@@ -34,7 +34,7 @@ export type ReactRendererEvidenceManifest = Readonly<{
34
34
  export declare const reactRendererEvidence: {
35
35
  readonly schemaVersion: 2;
36
36
  readonly packageName: "@hjmds/react";
37
- readonly packageVersion: "1.17.2";
37
+ readonly packageVersion: "1.19.0";
38
38
  readonly surface: "web";
39
39
  readonly components: readonly [Readonly<{
40
40
  /** Canonical component id from the design-contracts catalog. */
package/dist/evidence.js CHANGED
@@ -155,7 +155,7 @@ function toastClaim() {
155
155
  export const reactRendererEvidence = {
156
156
  schemaVersion: reactRendererEvidenceSchemaVersion,
157
157
  packageName: "@hjmds/react",
158
- packageVersion: "1.17.2",
158
+ packageVersion: "1.19.0",
159
159
  surface: "web",
160
160
  components: [
161
161
  defaultClaim("top-bar", ["TopBar"], "./top-bar"),