@hjmds/react 1.18.0 → 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 (188) hide show
  1. package/dist/advanced-display.d.ts.map +1 -1
  2. package/dist/advanced-display.js +41 -9
  3. package/dist/advanced-display.js.map +1 -1
  4. package/dist/advanced-forms.d.ts.map +1 -1
  5. package/dist/advanced-forms.js +22 -9
  6. package/dist/advanced-forms.js.map +1 -1
  7. package/dist/agreement.d.ts.map +1 -1
  8. package/dist/agreement.js +17 -11
  9. package/dist/agreement.js.map +1 -1
  10. package/dist/auth-screen.d.ts.map +1 -1
  11. package/dist/auth-screen.js +15 -2
  12. package/dist/auth-screen.js.map +1 -1
  13. package/dist/avatar-blobatar-motion.d.ts.map +1 -1
  14. package/dist/avatar-blobatar-motion.js +10 -2
  15. package/dist/avatar-blobatar-motion.js.map +1 -1
  16. package/dist/bottom-navigation.d.ts.map +1 -1
  17. package/dist/bottom-navigation.js +1 -1
  18. package/dist/bottom-navigation.js.map +1 -1
  19. package/dist/calendar.d.ts.map +1 -1
  20. package/dist/calendar.js +10 -2
  21. package/dist/calendar.js.map +1 -1
  22. package/dist/carousel-motion.d.ts +1 -0
  23. package/dist/carousel-motion.d.ts.map +1 -1
  24. package/dist/carousel-motion.js +4 -3
  25. package/dist/carousel-motion.js.map +1 -1
  26. package/dist/carousel.d.ts.map +1 -1
  27. package/dist/carousel.js +22 -4
  28. package/dist/carousel.js.map +1 -1
  29. package/dist/collapsible.d.ts.map +1 -1
  30. package/dist/collapsible.js +28 -4
  31. package/dist/collapsible.js.map +1 -1
  32. package/dist/collection-rail.d.ts.map +1 -1
  33. package/dist/collection-rail.js +19 -1
  34. package/dist/collection-rail.js.map +1 -1
  35. package/dist/color-picker.d.ts.map +1 -1
  36. package/dist/color-picker.js +12 -4
  37. package/dist/color-picker.js.map +1 -1
  38. package/dist/command-palette.d.ts.map +1 -1
  39. package/dist/command-palette.js +14 -2
  40. package/dist/command-palette.js.map +1 -1
  41. package/dist/context-menu.d.ts.map +1 -1
  42. package/dist/context-menu.js +31 -10
  43. package/dist/context-menu.js.map +1 -1
  44. package/dist/date-entry.d.ts +1 -1
  45. package/dist/date-entry.d.ts.map +1 -1
  46. package/dist/date-entry.js +20 -7
  47. package/dist/date-entry.js.map +1 -1
  48. package/dist/date-picker.d.ts.map +1 -1
  49. package/dist/date-picker.js +22 -6
  50. package/dist/date-picker.js.map +1 -1
  51. package/dist/display.d.ts +5 -1
  52. package/dist/display.d.ts.map +1 -1
  53. package/dist/display.js +3 -2
  54. package/dist/display.js.map +1 -1
  55. package/dist/duration-field.d.ts +2 -2
  56. package/dist/duration-field.d.ts.map +1 -1
  57. package/dist/duration-field.js +11 -3
  58. package/dist/duration-field.js.map +1 -1
  59. package/dist/evidence.d.ts +1 -1
  60. package/dist/evidence.js +1 -1
  61. package/dist/evidence.js.map +1 -1
  62. package/dist/feedback.d.ts.map +1 -1
  63. package/dist/feedback.js +3 -2
  64. package/dist/feedback.js.map +1 -1
  65. package/dist/field-group.d.ts +4 -2
  66. package/dist/field-group.d.ts.map +1 -1
  67. package/dist/field-group.js +4 -3
  68. package/dist/field-group.js.map +1 -1
  69. package/dist/file-picker.d.ts.map +1 -1
  70. package/dist/file-picker.js +15 -5
  71. package/dist/file-picker.js.map +1 -1
  72. package/dist/forms.d.ts +2 -2
  73. package/dist/forms.js +1 -1
  74. package/dist/forms.js.map +1 -1
  75. package/dist/gravity-letters.d.ts.map +1 -1
  76. package/dist/gravity-letters.js +9 -1
  77. package/dist/gravity-letters.js.map +1 -1
  78. package/dist/grid-reveal.d.ts.map +1 -1
  79. package/dist/grid-reveal.js +9 -1
  80. package/dist/grid-reveal.js.map +1 -1
  81. package/dist/index.d.ts +1 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +1 -0
  84. package/dist/index.js.map +1 -1
  85. package/dist/inline-confirm.d.ts.map +1 -1
  86. package/dist/inline-confirm.js +25 -4
  87. package/dist/inline-confirm.js.map +1 -1
  88. package/dist/internal/document-resource.d.ts.map +1 -1
  89. package/dist/internal/document-resource.js +2 -2
  90. package/dist/internal/document-resource.js.map +1 -1
  91. package/dist/masonry.d.ts.map +1 -1
  92. package/dist/masonry.js +2 -1
  93. package/dist/masonry.js.map +1 -1
  94. package/dist/mentions.d.ts.map +1 -1
  95. package/dist/mentions.js +12 -4
  96. package/dist/mentions.js.map +1 -1
  97. package/dist/menu-morph.js +1 -1
  98. package/dist/menu-morph.js.map +1 -1
  99. package/dist/menubar.d.ts.map +1 -1
  100. package/dist/menubar.js +43 -19
  101. package/dist/menubar.js.map +1 -1
  102. package/dist/modal.d.ts.map +1 -1
  103. package/dist/modal.js +15 -4
  104. package/dist/modal.js.map +1 -1
  105. package/dist/navigation.d.ts.map +1 -1
  106. package/dist/navigation.js +8 -2
  107. package/dist/navigation.js.map +1 -1
  108. package/dist/number-field.d.ts.map +1 -1
  109. package/dist/number-field.js +3 -1
  110. package/dist/number-field.js.map +1 -1
  111. package/dist/overlay-stack.d.ts.map +1 -1
  112. package/dist/overlay-stack.js +23 -6
  113. package/dist/overlay-stack.js.map +1 -1
  114. package/dist/overlays.d.ts.map +1 -1
  115. package/dist/overlays.js +8 -0
  116. package/dist/overlays.js.map +1 -1
  117. package/dist/pagination.d.ts.map +1 -1
  118. package/dist/pagination.js +16 -4
  119. package/dist/pagination.js.map +1 -1
  120. package/dist/saved-items.d.ts.map +1 -1
  121. package/dist/saved-items.js +6 -1
  122. package/dist/saved-items.js.map +1 -1
  123. package/dist/screen-flows.d.ts +1 -2
  124. package/dist/screen-flows.d.ts.map +1 -1
  125. package/dist/screen-flows.js +120 -16
  126. package/dist/screen-flows.js.map +1 -1
  127. package/dist/screens.d.ts.map +1 -1
  128. package/dist/screens.js +32 -7
  129. package/dist/screens.js.map +1 -1
  130. package/dist/select.d.ts.map +1 -1
  131. package/dist/select.js +6 -1
  132. package/dist/select.js.map +1 -1
  133. package/dist/side-panel.d.ts.map +1 -1
  134. package/dist/side-panel.js +11 -2
  135. package/dist/side-panel.js.map +1 -1
  136. package/dist/sidebar.d.ts.map +1 -1
  137. package/dist/sidebar.js +8 -1
  138. package/dist/sidebar.js.map +1 -1
  139. package/dist/skip-nav.d.ts.map +1 -1
  140. package/dist/skip-nav.js +16 -3
  141. package/dist/skip-nav.js.map +1 -1
  142. package/dist/sortable.d.ts.map +1 -1
  143. package/dist/sortable.js +2 -1
  144. package/dist/sortable.js.map +1 -1
  145. package/dist/splitter.d.ts.map +1 -1
  146. package/dist/splitter.js +23 -11
  147. package/dist/splitter.js.map +1 -1
  148. package/dist/statistic-motion.d.ts.map +1 -1
  149. package/dist/statistic-motion.js +30 -2
  150. package/dist/statistic-motion.js.map +1 -1
  151. package/dist/status-text.d.ts +11 -0
  152. package/dist/status-text.d.ts.map +1 -0
  153. package/dist/status-text.js +7 -0
  154. package/dist/status-text.js.map +1 -0
  155. package/dist/styles.css +14 -4
  156. package/dist/styles.layered.css +14 -4
  157. package/dist/supplemental-display.d.ts.map +1 -1
  158. package/dist/supplemental-display.js +19 -8
  159. package/dist/supplemental-display.js.map +1 -1
  160. package/dist/supplemental-navigation.d.ts.map +1 -1
  161. package/dist/supplemental-navigation.js +10 -1
  162. package/dist/supplemental-navigation.js.map +1 -1
  163. package/dist/tags-input.d.ts.map +1 -1
  164. package/dist/tags-input.js +18 -8
  165. package/dist/tags-input.js.map +1 -1
  166. package/dist/theme.d.ts.map +1 -1
  167. package/dist/theme.js +1 -0
  168. package/dist/theme.js.map +1 -1
  169. package/dist/toast.d.ts.map +1 -1
  170. package/dist/toast.js +31 -16
  171. package/dist/toast.js.map +1 -1
  172. package/dist/toggle-group.d.ts.map +1 -1
  173. package/dist/toggle-group.js +6 -1
  174. package/dist/toggle-group.js.map +1 -1
  175. package/dist/tour.d.ts.map +1 -1
  176. package/dist/tour.js +15 -2
  177. package/dist/tour.js.map +1 -1
  178. package/dist/transfer-list.d.ts +1 -1
  179. package/dist/transfer-list.d.ts.map +1 -1
  180. package/dist/transfer-list.js +52 -7
  181. package/dist/transfer-list.js.map +1 -1
  182. package/dist/tree.d.ts.map +1 -1
  183. package/dist/tree.js +41 -8
  184. package/dist/tree.js.map +1 -1
  185. package/dist/virtual-list.d.ts.map +1 -1
  186. package/dist/virtual-list.js +44 -7
  187. package/dist/virtual-list.js.map +1 -1
  188. package/package.json +8 -3
@@ -1 +1 @@
1
- {"version":3,"file":"advanced-forms.js","sourceRoot":"","sources":["../src/advanced-forms.tsx"],"names":[],"mappings":"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","sourcesContent":["import { layer } from \"@hjmds/design-contracts/foundations\";\nimport {\n comboboxRecipe,\n selectRecipe,\n type SelectDensity,\n type SelectSize,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n formRecipe,\n type FormDensity,\n} from \"@hjmds/design-contracts/components/form\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type FormEvent,\n type FormHTMLAttributes,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n type SelectHTMLAttributes,\n} from \"react\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { Field } from \"./forms.js\";\nimport { classNames, composeRefs, useControllableState } from \"./internal.js\";\nimport { AnchoredPortal, useAnchoredPopup } from \"./portal.js\";\n\nfunction useControlId(id: string | undefined, prefix: string): string {\n const generated = useId().replaceAll(\":\", \"\");\n return id ?? `hjm-${prefix}-${generated}`;\n}\n\nexport type SelectOption = Readonly<{\n value: string;\n label: string;\n disabled?: boolean;\n}>;\n\nfunction validateOptions(options: readonly SelectOption[], component: string): void {\n if (options.length === 0) throw new TypeError(`${component} requires at least one option`);\n const values = new Set<string>();\n for (const option of options) {\n if (option.value.trim().length === 0) {\n throw new TypeError(`${component} option value must not be empty`);\n }\n if (option.label.trim().length === 0) {\n throw new TypeError(`${component} option label must not be empty`);\n }\n if (values.has(option.value)) {\n throw new TypeError(`Duplicate ${component} option value: ${option.value}`);\n }\n values.add(option.value);\n }\n}\n\nexport type NativeSelectProps = Omit<\n SelectHTMLAttributes<HTMLSelectElement>,\n \"children\" | \"defaultValue\" | \"onChange\" | \"size\" | \"value\"\n> &\n Readonly<{\n label: ReactNode;\n description?: ReactNode;\n error?: ReactNode;\n options: readonly SelectOption[];\n placeholder?: string;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n size?: SelectSize;\n density?: SelectDensity;\n fieldClassName?: string;\n /**\n * Canonical layout-only placement on the field frame. `style` keeps going to\n * the native control, where it always went, so existing callers do not move.\n */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** A native select keeps browser keyboard, form, autofill, and mobile picker behavior. */\nexport const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(function NativeSelect(\n {\n id,\n label,\n description,\n error,\n options,\n placeholder,\n value: valueProp,\n defaultValue = \"\",\n onValueChange,\n size = selectRecipe.defaults.size,\n density = selectRecipe.defaults.density,\n fieldClassName,\n className,\n layoutStyle,\n disabled = false,\n required = false,\n ...props\n },\n ref,\n) {\n validateOptions(options, \"Select\");\n const controlId = useControlId(id, \"select\");\n const [value, setValue] = useControllableState({\n ...(valueProp === undefined ? {} : { value: valueProp }),\n defaultValue,\n ...(onValueChange === undefined ? {} : { onChange: onValueChange }),\n });\n if (\n value !== \"\" &&\n !options.some((option) => option.value === value && !option.disabled)\n ) {\n throw new RangeError(`Select value must identify an enabled option: ${value}`);\n }\n\n return (\n <Field\n controlId={controlId}\n label={label}\n description={description}\n error={error}\n required={required}\n disabled={disabled}\n className={classNames(\"hjm-select\", fieldClassName)}\n {...(layoutStyle === undefined ? {} : { layoutStyle })}\n data-size={size}\n data-density={density}\n >\n {(controlProps) => (\n <div className=\"hjm-field__control hjm-select__control\">\n <select\n {...props}\n {...controlProps}\n ref={ref}\n value={value}\n className={classNames(\"hjm-field__input hjm-select__native\", className)}\n onChange={(event: ChangeEvent<HTMLSelectElement>) => setValue(event.target.value)}\n >\n {placeholder !== undefined ? (\n <option value=\"\" disabled={required}>\n {placeholder}\n </option>\n ) : null}\n {options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n <span className=\"hjm-select__indicator\" aria-hidden=\"true\">⌄</span>\n </div>\n )}\n </Field>\n );\n});\n\nexport type ComboboxItem = Readonly<{\n value: string;\n label: string;\n keywords?: readonly string[];\n disabled?: boolean;\n}>;\n\nexport type ComboboxOpenChangeReason =\n | \"focus\"\n | \"input\"\n | \"keyboard\"\n | \"selection\"\n | \"escape\"\n | \"blur\";\n\nexport type ComboboxProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"children\" | \"defaultValue\" | \"onChange\" | \"role\" | \"size\" | \"value\"\n> &\n Readonly<{\n label: ReactNode;\n description?: ReactNode;\n error?: ReactNode;\n items: readonly ComboboxItem[];\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n inputValue?: string;\n defaultInputValue?: string;\n onInputValueChange?: (value: string) => void;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean, reason: ComboboxOpenChangeReason) => void;\n /** Localized content rendered when filtering returns no items. */\n emptyMessage: ReactNode;\n loading?: boolean;\n /** Localized content announced while options are loading. */\n loadingMessage: ReactNode;\n /** Localized native-validation message for an empty required selection. */\n selectionRequiredMessage: string;\n openOnFocus?: boolean;\n size?: SelectSize;\n density?: SelectDensity;\n /** Logical listbox alignment against the input; automatically mirrors in RTL. */\n align?: \"start\" | \"end\";\n fieldClassName?: string;\n portalContainer?: HTMLElement;\n /**\n * Canonical layout-only placement on the field frame. `style` keeps going to\n * the input, where it always went, so existing callers do not move.\n */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nfunction nextEnabled(\n items: readonly ComboboxItem[],\n current: number,\n direction: 1 | -1,\n): number {\n if (items.length === 0) return -1;\n for (let offset = 1; offset <= items.length; offset += 1) {\n const candidate = (current + direction * offset + items.length) % items.length;\n if (!items[candidate]?.disabled) return candidate;\n }\n return -1;\n}\n\nexport const Combobox = forwardRef<HTMLInputElement, ComboboxProps>(\n function Combobox(\n {\n id,\n name,\n label,\n description,\n error,\n items,\n value: valueProp,\n defaultValue = \"\",\n onValueChange,\n inputValue: inputValueProp,\n defaultInputValue,\n onInputValueChange,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n emptyMessage,\n loading = false,\n loadingMessage,\n selectionRequiredMessage,\n openOnFocus = true,\n size = comboboxRecipe.defaults.size,\n density = comboboxRecipe.defaults.density,\n align = \"start\",\n fieldClassName,\n portalContainer,\n className,\n layoutStyle,\n disabled = false,\n required = false,\n autoComplete = \"off\",\n onFocus,\n onBlur,\n onKeyDown,\n ...props\n },\n forwardedRef,\n ) {\n validateOptions(items, \"Combobox\");\n const controlId = useControlId(id, \"combobox\");\n const listboxId = `${controlId}-listbox`;\n const rootRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const suppressFocusOpenRef = useRef(false);\n const listboxRef = useRef<HTMLDivElement>(null);\n const [listboxNode, setListboxNode] = useState<HTMLDivElement | null>(null);\n const popupPosition = useAnchoredPopup(inputRef, listboxNode, {\n align,\n // comboboxRecipe.popover (= selectRecipe.popover), same correction as Select (2026-10-06).\n gap: comboboxRecipe.popover.sideOffset,\n viewportPadding: comboboxRecipe.popover.collisionPadding,\n matchAnchorWidth: true,\n zIndex: layer.dropdown,\n });\n const setListboxRef = useCallback((node: HTMLDivElement | null) => {\n listboxRef.current = node;\n setListboxNode(node);\n }, []);\n const [selectedValue, setSelectedValue] = useControllableState({\n ...(valueProp === undefined ? {} : { value: valueProp }),\n defaultValue,\n ...(onValueChange === undefined ? {} : { onChange: onValueChange }),\n });\n const selectedItem = items.find((item) => item.value === selectedValue);\n if (selectedValue !== \"\" && (!selectedItem || selectedItem.disabled)) {\n throw new RangeError(\n `Combobox value must identify an enabled option: ${selectedValue}`,\n );\n }\n if (required && selectionRequiredMessage.trim().length === 0) {\n throw new TypeError(\"Combobox selectionRequiredMessage must not be empty\");\n }\n const [query, setQuery] = useControllableState({\n ...(inputValueProp === undefined ? {} : { value: inputValueProp }),\n defaultValue: defaultInputValue ?? selectedItem?.label ?? \"\",\n ...(onInputValueChange === undefined ? {} : { onChange: onInputValueChange }),\n });\n const [open, setOpenState] = useControllableState({\n ...(openProp === undefined ? {} : { value: openProp }),\n defaultValue: defaultOpen,\n });\n const [activeIndex, setActiveIndex] = useState(-1);\n useEffect(() => {\n inputRef.current?.setCustomValidity(\n required && selectedValue === \"\" ? selectionRequiredMessage : \"\",\n );\n }, [required, selectedValue, selectionRequiredMessage]);\n const normalizedQuery = query.trim().toLocaleLowerCase();\n const filteredItems = useMemo(\n () =>\n items.filter((item) => {\n if (normalizedQuery.length === 0) return true;\n const searchable = [item.label, ...(item.keywords ?? [])]\n .join(\" \")\n .toLocaleLowerCase();\n return searchable.includes(normalizedQuery);\n }),\n [items, normalizedQuery],\n );\n\n const setOpen = (next: boolean, reason: ComboboxOpenChangeReason) => {\n if (next === open) return;\n setOpenState(next);\n onOpenChange?.(next, reason);\n if (!next) setActiveIndex(-1);\n };\n const firstEnabled = () => filteredItems.findIndex((item) => !item.disabled);\n const lastEnabled = () => {\n for (let index = filteredItems.length - 1; index >= 0; index -= 1) {\n if (!filteredItems[index]?.disabled) return index;\n }\n return -1;\n };\n const selectItem = (item: ComboboxItem) => {\n if (item.disabled) return;\n setSelectedValue(item.value);\n setQuery(item.label);\n setOpen(false, \"selection\");\n queueMicrotask(() => {\n const input = inputRef.current;\n if (!input || document.activeElement === input) return;\n suppressFocusOpenRef.current = true;\n input.focus();\n queueMicrotask(() => {\n suppressFocusOpenRef.current = false;\n });\n });\n };\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (\n loading &&\n [\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\", \"Enter\"].includes(event.key)\n ) {\n event.preventDefault();\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n if (!open) {\n setOpen(true, \"keyboard\");\n setActiveIndex(\n event.key === \"ArrowDown\" ? firstEnabled() : lastEnabled(),\n );\n return;\n }\n setActiveIndex((current) =>\n nextEnabled(filteredItems, current, event.key === \"ArrowDown\" ? 1 : -1),\n );\n } else if (open && event.key === \"Home\") {\n event.preventDefault();\n setActiveIndex(firstEnabled());\n } else if (open && event.key === \"End\") {\n event.preventDefault();\n setActiveIndex(lastEnabled());\n } else if (open && event.key === \"Enter\" && activeIndex >= 0) {\n event.preventDefault();\n const item = filteredItems[activeIndex];\n if (item) selectItem(item);\n } else if (open && event.key === \"Escape\") {\n event.preventDefault();\n setOpen(false, \"escape\");\n } else if (open && event.key === \"Tab\") {\n setOpen(false, \"blur\");\n }\n };\n const activeItem = activeIndex >= 0 ? filteredItems[activeIndex] : undefined;\n\n return (\n <Field\n controlId={controlId}\n label={label}\n description={description}\n error={error}\n required={required}\n disabled={disabled}\n className={classNames(\"hjm-combobox\", fieldClassName)}\n {...(layoutStyle === undefined ? {} : { layoutStyle })}\n data-size={size}\n data-density={density}\n data-state={disabled ? \"disabled\" : open ? \"open\" : \"closed\"}\n >\n {(controlProps) => (\n <div\n ref={rootRef}\n className=\"hjm-combobox__anchor\"\n onBlur={(event) => {\n if (\n !event.currentTarget.contains(event.relatedTarget) &&\n !listboxRef.current?.contains(event.relatedTarget)\n ) setOpen(false, \"blur\");\n }}\n >\n <div className=\"hjm-field__control hjm-combobox__control\">\n <input\n {...props}\n {...controlProps}\n ref={composeRefs(forwardedRef, inputRef)}\n className={classNames(\"hjm-field__input hjm-combobox__input\", className)}\n value={query}\n role=\"combobox\"\n autoComplete={autoComplete}\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-expanded={open}\n aria-activedescendant={\n open && activeItem ? `${controlId}-option-${activeIndex}` : undefined\n }\n onFocus={(event) => {\n onFocus?.(event);\n if (\n !event.defaultPrevented &&\n openOnFocus &&\n !suppressFocusOpenRef.current\n ) setOpen(true, \"focus\");\n }}\n onBlur={onBlur}\n onChange={(event) => {\n setQuery(event.target.value);\n setSelectedValue(\"\");\n setOpen(true, \"input\");\n setActiveIndex(-1);\n }}\n onKeyDown={handleKeyDown}\n />\n {loading ? <span className=\"hjm-combobox__spinner\" aria-hidden=\"true\" /> : null}\n <span className=\"hjm-select__indicator\" aria-hidden=\"true\">⌄</span>\n </div>\n {name ? <input type=\"hidden\" name={name} value={selectedValue} /> : null}\n {open ? (\n <AnchoredPortal\n anchorRef={inputRef}\n ssrFallback=\"inline\"\n {...(portalContainer === undefined ? {} : { container: portalContainer })}\n >\n <div\n ref={setListboxRef}\n id={listboxId}\n role=\"listbox\"\n className=\"hjm-combobox__listbox\"\n data-density={density}\n aria-label={typeof label === \"string\" ? label : undefined}\n aria-busy={loading || undefined}\n data-placement={popupPosition.placement}\n data-align={popupPosition.align}\n style={popupPosition.style}\n >\n {loading ? (\n <div className=\"hjm-combobox__message\" role=\"status\"><span className=\"hjm-visually-hidden\">{loadingMessage}</span></div>\n ) : filteredItems.length === 0 ? (\n <div className=\"hjm-combobox__message\">{emptyMessage}</div>\n ) : (\n filteredItems.map((item, index) => (\n <div\n key={item.value}\n id={`${controlId}-option-${index}`}\n role=\"option\"\n aria-selected={item.value === selectedValue}\n aria-disabled={item.disabled || undefined}\n className=\"hjm-combobox__option\"\n data-state={\n item.disabled\n ? \"disabled\"\n : index === activeIndex\n ? \"active\"\n : item.value === selectedValue\n ? \"selected\"\n : \"idle\"\n }\n onMouseDown={(event) => event.preventDefault()}\n onMouseMove={() => {\n if (!item.disabled) setActiveIndex(index);\n }}\n onClick={() => selectItem(item)}\n >\n {item.label}\n </div>\n ))\n )}\n </div>\n </AnchoredPortal>\n ) : null}\n </div>\n )}\n </Field>\n );\n },\n);\n\nexport type FormSubmitHandler = (\n event: FormEvent<HTMLFormElement>,\n) => void | Promise<void>;\n\nexport type FormProps = Omit<FormHTMLAttributes<HTMLFormElement>, \"onSubmit\"> &\n Readonly<{\n onSubmit: FormSubmitHandler;\n busy?: boolean;\n formError?: ReactNode;\n actions?: ReactNode;\n density?: FormDensity;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Form = forwardRef<HTMLFormElement, FormProps>(function Form(\n {\n onSubmit,\n busy = false,\n formError,\n actions,\n density = formRecipe.defaults.density,\n className,\n children,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n const effectiveBusy = busy || submitting;\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (effectiveBusy || submittingRef.current) return;\n let result: void | Promise<void>;\n try {\n result = onSubmit(event);\n } catch (error) {\n throw error;\n }\n if (result && typeof result.then === \"function\") {\n submittingRef.current = true;\n setSubmitting(true);\n void Promise.resolve(result)\n .catch(() => undefined)\n .finally(() => {\n submittingRef.current = false;\n setSubmitting(false);\n });\n }\n };\n\n return (\n <form\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-form\", className)}\n data-density={density}\n data-state={effectiveBusy ? \"busy\" : formError ? \"error\" : \"idle\"}\n aria-busy={effectiveBusy || undefined}\n onSubmit={handleSubmit}\n >\n <fieldset className=\"hjm-form__fieldset\" disabled={effectiveBusy}>\n <div className=\"hjm-form__fields\">{children}</div>\n {formError ? (\n <div className=\"hjm-form__error\" role=\"alert\">{formError}</div>\n ) : null}\n {actions ? <div className=\"hjm-form__actions\">{actions}</div> : null}\n </fieldset>\n </form>\n );\n});\n"]}
1
+ {"version":3,"file":"advanced-forms.js","sourceRoot":"","sources":["../src/advanced-forms.tsx"],"names":[],"mappings":"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","sourcesContent":["import { layer } from \"@hjmds/design-contracts/foundations\";\nimport {\n comboboxRecipe,\n selectRecipe,\n type SelectDensity,\n type SelectSize,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n formRecipe,\n type FormDensity,\n} from \"@hjmds/design-contracts/components/form\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type FormEvent,\n type FormHTMLAttributes,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n type SelectHTMLAttributes,\n} from \"react\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { Field } from \"./forms.js\";\nimport { classNames, composeRefs, useControllableState } from \"./internal.js\";\nimport { AnchoredPortal, useAnchoredPopup } from \"./portal.js\";\n\nfunction useControlId(id: string | undefined, prefix: string): string {\n const generated = useId().replaceAll(\":\", \"\");\n return id ?? `hjm-${prefix}-${generated}`;\n}\n\nexport type SelectOption = Readonly<{\n value: string;\n label: string;\n disabled?: boolean;\n}>;\n\nfunction validateOptions(options: readonly SelectOption[], component: string): void {\n if (options.length === 0) throw new TypeError(`${component} requires at least one option`);\n const values = new Set<string>();\n for (const option of options) {\n if (option.value.trim().length === 0) {\n throw new TypeError(`${component} option value must not be empty`);\n }\n if (option.label.trim().length === 0) {\n throw new TypeError(`${component} option label must not be empty`);\n }\n if (values.has(option.value)) {\n throw new TypeError(`Duplicate ${component} option value: ${option.value}`);\n }\n values.add(option.value);\n }\n}\n\nexport type NativeSelectProps = Omit<\n SelectHTMLAttributes<HTMLSelectElement>,\n \"children\" | \"defaultValue\" | \"onChange\" | \"size\" | \"value\"\n> &\n Readonly<{\n label: ReactNode;\n description?: ReactNode;\n error?: ReactNode;\n options: readonly SelectOption[];\n placeholder?: string;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n size?: SelectSize;\n density?: SelectDensity;\n fieldClassName?: string;\n /**\n * Canonical layout-only placement on the field frame. `style` keeps going to\n * the native control, where it always went, so existing callers do not move.\n */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** A native select keeps browser keyboard, form, autofill, and mobile picker behavior. */\nexport const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(function NativeSelect(\n {\n id,\n label,\n description,\n error,\n options,\n placeholder,\n value: valueProp,\n defaultValue = \"\",\n onValueChange,\n size = selectRecipe.defaults.size,\n density = selectRecipe.defaults.density,\n fieldClassName,\n className,\n layoutStyle,\n disabled = false,\n required = false,\n ...props\n },\n ref,\n) {\n validateOptions(options, \"Select\");\n const controlId = useControlId(id, \"select\");\n const [storedValue, setValue] = useControllableState({\n ...(valueProp === undefined ? {} : { value: valueProp }),\n defaultValue,\n ...(onValueChange === undefined ? {} : { onChange: onValueChange }),\n });\n const initialized = useRef(false);\n const available = storedValue === \"\" || options.some(option => option.value === storedValue && !option.disabled);\n if ((!initialized.current || valueProp !== undefined) && !available) {\n throw new RangeError(`Select value must identify an enabled option: ${storedValue}`);\n }\n initialized.current = true;\n // Defaults are validated once. Later list changes must reconcile an internal\n // selection instead of crashing a form while its options are being refreshed.\n const value = valueProp === undefined && !available\n ? placeholder !== undefined ? \"\" : options.find(option => !option.disabled)?.value ?? \"\"\n : storedValue;\n useEffect(() => {\n if (valueProp === undefined && value !== storedValue) setValue(value);\n }, [storedValue, value, valueProp, setValue]);\n\n return (\n <Field\n controlId={controlId}\n label={label}\n description={description}\n error={error}\n required={required}\n disabled={disabled}\n className={classNames(\"hjm-select\", fieldClassName)}\n {...(layoutStyle === undefined ? {} : { layoutStyle })}\n data-size={size}\n data-density={density}\n >\n {(controlProps) => (\n <div className=\"hjm-field__control hjm-select__control\">\n <select\n {...props}\n {...controlProps}\n ref={ref}\n value={value}\n className={classNames(\"hjm-field__input hjm-select__native\", className)}\n onChange={(event: ChangeEvent<HTMLSelectElement>) => setValue(event.target.value)}\n >\n {placeholder !== undefined ? (\n <option value=\"\" disabled={required}>\n {placeholder}\n </option>\n ) : null}\n {options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n <span className=\"hjm-select__indicator\" aria-hidden=\"true\">⌄</span>\n </div>\n )}\n </Field>\n );\n});\n\nexport type ComboboxItem = Readonly<{\n value: string;\n label: string;\n keywords?: readonly string[];\n disabled?: boolean;\n}>;\n\nexport type ComboboxOpenChangeReason =\n | \"focus\"\n | \"input\"\n | \"keyboard\"\n | \"selection\"\n | \"escape\"\n | \"blur\";\n\nexport type ComboboxProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"children\" | \"defaultValue\" | \"onChange\" | \"role\" | \"size\" | \"value\"\n> &\n Readonly<{\n label: ReactNode;\n description?: ReactNode;\n error?: ReactNode;\n items: readonly ComboboxItem[];\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n inputValue?: string;\n defaultInputValue?: string;\n onInputValueChange?: (value: string) => void;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean, reason: ComboboxOpenChangeReason) => void;\n /** Localized content rendered when filtering returns no items. */\n emptyMessage: ReactNode;\n loading?: boolean;\n /** Localized content announced while options are loading. */\n loadingMessage: ReactNode;\n /** Localized native-validation message for an empty required selection. */\n selectionRequiredMessage: string;\n openOnFocus?: boolean;\n size?: SelectSize;\n density?: SelectDensity;\n /** Logical listbox alignment against the input; automatically mirrors in RTL. */\n align?: \"start\" | \"end\";\n fieldClassName?: string;\n portalContainer?: HTMLElement;\n /**\n * Canonical layout-only placement on the field frame. `style` keeps going to\n * the input, where it always went, so existing callers do not move.\n */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nfunction nextEnabled(\n items: readonly ComboboxItem[],\n current: number,\n direction: 1 | -1,\n): number {\n if (items.length === 0) return -1;\n for (let offset = 1; offset <= items.length; offset += 1) {\n const candidate = (current + direction * offset + items.length) % items.length;\n if (!items[candidate]?.disabled) return candidate;\n }\n return -1;\n}\n\nexport const Combobox = forwardRef<HTMLInputElement, ComboboxProps>(\n function Combobox(\n {\n id,\n name,\n label,\n description,\n error,\n items,\n value: valueProp,\n defaultValue = \"\",\n onValueChange,\n inputValue: inputValueProp,\n defaultInputValue,\n onInputValueChange,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n emptyMessage,\n loading = false,\n loadingMessage,\n selectionRequiredMessage,\n openOnFocus = true,\n size = comboboxRecipe.defaults.size,\n density = comboboxRecipe.defaults.density,\n align = \"start\",\n fieldClassName,\n portalContainer,\n className,\n layoutStyle,\n disabled = false,\n readOnly = false,\n required = false,\n autoComplete = \"off\",\n onFocus,\n onBlur,\n onKeyDown,\n ...props\n },\n forwardedRef,\n ) {\n validateOptions(items, \"Combobox\");\n const controlId = useControlId(id, \"combobox\");\n const listboxId = `${controlId}-listbox`;\n const rootRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const suppressFocusOpenRef = useRef(false);\n const listboxRef = useRef<HTMLDivElement>(null);\n const [listboxNode, setListboxNode] = useState<HTMLDivElement | null>(null);\n const popupPosition = useAnchoredPopup(inputRef, listboxNode, {\n align,\n // comboboxRecipe.popover (= selectRecipe.popover), same correction as Select (2026-10-06).\n gap: comboboxRecipe.popover.sideOffset,\n viewportPadding: comboboxRecipe.popover.collisionPadding,\n matchAnchorWidth: true,\n zIndex: layer.dropdown,\n });\n const setListboxRef = useCallback((node: HTMLDivElement | null) => {\n listboxRef.current = node;\n setListboxNode(node);\n }, []);\n const [selectedValue, setSelectedValue] = useControllableState({\n ...(valueProp === undefined ? {} : { value: valueProp }),\n defaultValue,\n ...(onValueChange === undefined ? {} : { onChange: onValueChange }),\n });\n const selectedItem = items.find((item) => item.value === selectedValue);\n if (selectedValue !== \"\" && (!selectedItem || selectedItem.disabled)) {\n throw new RangeError(\n `Combobox value must identify an enabled option: ${selectedValue}`,\n );\n }\n if (required && selectionRequiredMessage.trim().length === 0) {\n throw new TypeError(\"Combobox selectionRequiredMessage must not be empty\");\n }\n const [query, setQuery] = useControllableState({\n ...(inputValueProp === undefined ? {} : { value: inputValueProp }),\n defaultValue: defaultInputValue ?? selectedItem?.label ?? \"\",\n ...(onInputValueChange === undefined ? {} : { onChange: onInputValueChange }),\n });\n const [open, setOpenState] = useControllableState({\n ...(openProp === undefined ? {} : { value: openProp }),\n defaultValue: defaultOpen,\n });\n const [activeIndex, setActiveIndex] = useState(-1);\n useEffect(() => {\n inputRef.current?.setCustomValidity(\n required && selectedValue === \"\" ? selectionRequiredMessage : \"\",\n );\n }, [required, selectedValue, selectionRequiredMessage]);\n const normalizedQuery = query.trim().toLocaleLowerCase();\n const filteredItems = useMemo(\n () =>\n items.filter((item) => {\n if (normalizedQuery.length === 0) return true;\n const searchable = [item.label, ...(item.keywords ?? [])]\n .join(\" \")\n .toLocaleLowerCase();\n return searchable.includes(normalizedQuery);\n }),\n [items, normalizedQuery],\n );\n\n const setOpen = (next: boolean, reason: ComboboxOpenChangeReason) => {\n if (next === open) return;\n setOpenState(next);\n onOpenChange?.(next, reason);\n if (!next) setActiveIndex(-1);\n };\n const firstEnabled = () => filteredItems.findIndex((item) => !item.disabled);\n const lastEnabled = () => {\n for (let index = filteredItems.length - 1; index >= 0; index -= 1) {\n if (!filteredItems[index]?.disabled) return index;\n }\n return -1;\n };\n const selectItem = (item: ComboboxItem) => {\n if (item.disabled || disabled || readOnly || loading) return;\n setSelectedValue(item.value);\n setQuery(item.label);\n setOpen(false, \"selection\");\n queueMicrotask(() => {\n const input = inputRef.current;\n if (!input || document.activeElement === input) return;\n suppressFocusOpenRef.current = true;\n input.focus();\n queueMicrotask(() => {\n suppressFocusOpenRef.current = false;\n });\n });\n };\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || disabled || readOnly || event.nativeEvent.isComposing || event.keyCode === 229) return;\n if (\n loading &&\n [\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\", \"Enter\"].includes(event.key)\n ) {\n event.preventDefault();\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n if (!open) {\n setOpen(true, \"keyboard\");\n setActiveIndex(\n event.key === \"ArrowDown\" ? firstEnabled() : lastEnabled(),\n );\n return;\n }\n setActiveIndex((current) =>\n nextEnabled(filteredItems, current, event.key === \"ArrowDown\" ? 1 : -1),\n );\n } else if (open && event.key === \"Home\") {\n event.preventDefault();\n setActiveIndex(firstEnabled());\n } else if (open && event.key === \"End\") {\n event.preventDefault();\n setActiveIndex(lastEnabled());\n } else if (open && event.key === \"Enter\" && activeIndex >= 0) {\n event.preventDefault();\n const item = filteredItems[activeIndex];\n if (item) selectItem(item);\n } else if (open && event.key === \"Escape\") {\n event.preventDefault();\n setOpen(false, \"escape\");\n } else if (open && event.key === \"Tab\") {\n setOpen(false, \"blur\");\n }\n };\n const activeItem = activeIndex >= 0 ? filteredItems[activeIndex] : undefined;\n\n return (\n <Field\n controlId={controlId}\n label={label}\n description={description}\n error={error}\n required={required}\n disabled={disabled}\n className={classNames(\"hjm-combobox\", fieldClassName)}\n {...(layoutStyle === undefined ? {} : { layoutStyle })}\n data-size={size}\n data-density={density}\n data-state={disabled ? \"disabled\" : open ? \"open\" : \"closed\"}\n >\n {(controlProps) => (\n <div\n ref={rootRef}\n className=\"hjm-combobox__anchor\"\n onBlur={(event) => {\n if (\n !event.currentTarget.contains(event.relatedTarget) &&\n !listboxRef.current?.contains(event.relatedTarget)\n ) setOpen(false, \"blur\");\n }}\n >\n <div className=\"hjm-field__control hjm-combobox__control\">\n <input\n {...props}\n {...controlProps}\n ref={composeRefs(forwardedRef, inputRef)}\n className={classNames(\"hjm-field__input hjm-combobox__input\", className)}\n value={query}\n readOnly={readOnly}\n role=\"combobox\"\n autoComplete={autoComplete}\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-expanded={open}\n aria-activedescendant={\n open && activeItem ? `${controlId}-option-${activeIndex}` : undefined\n }\n onFocus={(event) => {\n onFocus?.(event);\n if (\n !event.defaultPrevented &&\n !disabled && !readOnly && openOnFocus &&\n !suppressFocusOpenRef.current\n ) setOpen(true, \"focus\");\n }}\n onBlur={onBlur}\n onChange={(event) => {\n if (disabled || readOnly) return;\n setQuery(event.target.value);\n setSelectedValue(\"\");\n setOpen(true, \"input\");\n setActiveIndex(-1);\n }}\n onKeyDown={handleKeyDown}\n />\n {loading ? <span className=\"hjm-combobox__spinner\" aria-hidden=\"true\" /> : null}\n <span className=\"hjm-select__indicator\" aria-hidden=\"true\">⌄</span>\n </div>\n {name ? <input type=\"hidden\" name={name} value={selectedValue} /> : null}\n {open ? (\n <AnchoredPortal\n anchorRef={inputRef}\n ssrFallback=\"inline\"\n {...(portalContainer === undefined ? {} : { container: portalContainer })}\n >\n <div\n ref={setListboxRef}\n id={listboxId}\n role=\"listbox\"\n className=\"hjm-combobox__listbox\"\n data-density={density}\n aria-label={typeof label === \"string\" ? label : undefined}\n aria-busy={loading || undefined}\n data-placement={popupPosition.placement}\n data-align={popupPosition.align}\n style={popupPosition.style}\n >\n {loading ? (\n <div className=\"hjm-combobox__message\" role=\"status\"><span className=\"hjm-visually-hidden\">{loadingMessage}</span></div>\n ) : filteredItems.length === 0 ? (\n <div className=\"hjm-combobox__message\">{emptyMessage}</div>\n ) : (\n filteredItems.map((item, index) => (\n <div\n key={item.value}\n id={`${controlId}-option-${index}`}\n role=\"option\"\n aria-selected={item.value === selectedValue}\n aria-disabled={item.disabled || undefined}\n className=\"hjm-combobox__option\"\n data-state={\n item.disabled\n ? \"disabled\"\n : index === activeIndex\n ? \"active\"\n : item.value === selectedValue\n ? \"selected\"\n : \"idle\"\n }\n onMouseDown={(event) => event.preventDefault()}\n onMouseMove={() => {\n if (!item.disabled) setActiveIndex(index);\n }}\n onClick={() => selectItem(item)}\n >\n {item.label}\n </div>\n ))\n )}\n </div>\n </AnchoredPortal>\n ) : null}\n </div>\n )}\n </Field>\n );\n },\n);\n\nexport type FormSubmitHandler = (\n event: FormEvent<HTMLFormElement>,\n) => void | Promise<void>;\n\nexport type FormProps = Omit<FormHTMLAttributes<HTMLFormElement>, \"onSubmit\"> &\n Readonly<{\n onSubmit: FormSubmitHandler;\n busy?: boolean;\n formError?: ReactNode;\n actions?: ReactNode;\n density?: FormDensity;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Form = forwardRef<HTMLFormElement, FormProps>(function Form(\n {\n onSubmit,\n busy = false,\n formError,\n actions,\n density = formRecipe.defaults.density,\n className,\n children,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n const effectiveBusy = busy || submitting;\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (effectiveBusy || submittingRef.current) return;\n let result: void | Promise<void>;\n try {\n result = onSubmit(event);\n } catch (error) {\n throw error;\n }\n if (result && typeof result.then === \"function\") {\n submittingRef.current = true;\n setSubmitting(true);\n void Promise.resolve(result)\n .catch(() => undefined)\n .finally(() => {\n submittingRef.current = false;\n setSubmitting(false);\n });\n }\n };\n\n return (\n <form\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-form\", className)}\n data-density={density}\n data-state={effectiveBusy ? \"busy\" : formError ? \"error\" : \"idle\"}\n aria-busy={effectiveBusy || undefined}\n onSubmit={handleSubmit}\n >\n <fieldset className=\"hjm-form__fieldset\" disabled={effectiveBusy}>\n <div className=\"hjm-form__fields\">{children}</div>\n {formError ? (\n <div className=\"hjm-form__error\" role=\"alert\">{formError}</div>\n ) : null}\n {actions ? <div className=\"hjm-form__actions\">{actions}</div> : null}\n </fieldset>\n </form>\n );\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"agreement.d.ts","sourceRoot":"","sources":["../src/agreement.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,8CAA8C,CAAC;AAGtD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,cAAc,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAChE,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,iBAAiB,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACpC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACpD,4EAA4E;IAC5E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACpD,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC;IAC5B,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAUH,eAAO,MAAM,SAAS,EAoHhB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,EAC/B,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;CAAE,KAC5D,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"agreement.d.ts","sourceRoot":"","sources":["../src/agreement.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,8CAA8C,CAAC;AAGtD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,cAAc,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAChE,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,iBAAiB,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACpC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACpD,4EAA4E;IAC5E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACpD,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC;IAC5B,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAUH,eAAO,MAAM,SAAS,EAwHhB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,EAC/B,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;CAAE,KAC5D,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC"}
package/dist/agreement.js CHANGED
@@ -16,22 +16,28 @@ export const Agreement = forwardRef(function Agreement({ descriptor, checkedIds:
16
16
  const checked = useMemo(() => reconcileAgreementSelection(descriptor, rawChecked), [descriptor, rawChecked]);
17
17
  const state = resolveAgreementState(descriptor, checked);
18
18
  const id = `${useId().replaceAll(":", "")}-agreement`;
19
- // Report the initial state once on mount. Until 2026-10-06 only user toggles reported, so
20
- // `defaultCheckedIds`/`checkedIds` that already satisfied every required item never produced a
21
- // first `satisfied: true` and a submit button wired to this callback stayed disabled. Mount-only
22
- // (not on every derived change) keeps the callback count to "initial + one per toggle"; StrictMode
23
- // may repeat the same snapshot, which is idempotent for a consumer that stores it.
24
- const initialStateRef = useRef(state);
25
- const onStateChangeRef = useRef(onStateChange);
26
- onStateChangeRef.current = onStateChange;
19
+ // Persist removed consent IDs so reinserting a row cannot silently consent again.
27
20
  useEffect(() => {
28
- onStateChangeRef.current?.(initialStateRef.current);
29
- }, []);
21
+ if (controlledChecked === undefined && checked !== rawChecked)
22
+ setChecked(checked);
23
+ }, [checked, controlledChecked, rawChecked, setChecked]);
24
+ // Report accepted state, including external value/required-item changes. A rejected
25
+ // controlled request must not enable the product's submit button optimistically.
26
+ const reported = useRef(undefined);
27
+ useEffect(() => {
28
+ const previous = reported.current;
29
+ if (previous && previous.state.all === state.all && previous.state.satisfied === state.satisfied
30
+ && previous.state.missingRequiredIds.length === state.missingRequiredIds.length
31
+ && previous.state.missingRequiredIds.every((id, index) => id === state.missingRequiredIds[index])
32
+ && previous.checked.size === checked.size && [...checked].every(id => previous.checked.has(id)))
33
+ return;
34
+ reported.current = { checked, state };
35
+ onStateChange?.(state);
36
+ });
30
37
  const commit = (next) => {
31
38
  if (descriptor.disabled)
32
39
  return;
33
40
  setChecked(next);
34
- onStateChange?.(resolveAgreementState(descriptor, next));
35
41
  };
36
42
  return (_jsxs("div", { ref: forwardedRef, role: "group", "aria-label": descriptor.accessibilityLabel, style: layoutStyle, className: classNames("hjm-agreement", className), children: [_jsxs("button", { type: "button", role: "checkbox", "aria-checked": state.all === "mixed" ? "mixed" : String(state.all === true), "aria-disabled": descriptor.disabled || undefined, className: "hjm-agreement__all", onClick: () => commit(toggleAgreementAll(descriptor, checked)), children: [_jsx(Mark, { state: state.all }), _jsx("span", { children: descriptor.allLabel })] }), _jsx("div", { className: "hjm-agreement__list", children: descriptor.items.map((item) => {
37
43
  const itemChecked = checked.has(item.id);
@@ -1 +1 @@
1
- {"version":3,"file":"agreement.js","sourceRoot":"","sources":["../src/agreement.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n reconcileAgreementSelection,\n resolveAgreementState,\n toggleAgreementAll,\n toggleAgreementItem,\n validateAgreementDescriptor,\n type AgreementDescriptor,\n type AgreementState,\n} from \"@hjmds/design-contracts/components/agreement\";\nimport { forwardRef, useEffect, useId, useMemo, useRef } from \"react\";\nimport { classNames, useControllableState } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type AgreementProps<Id extends string = string> = Readonly<{\n descriptor: AgreementDescriptor<Id>;\n checkedIds?: ReadonlySet<Id>;\n defaultCheckedIds?: ReadonlySet<Id>;\n onCheckedIdsChange?: (ids: ReadonlySet<Id>) => void;\n /** Fires the derived state on every change, for a submit button to read. */\n onStateChange?: (state: AgreementState<Id>) => void;\n /** Called when an item's full text is requested and it carries no href. */\n onDetail?: (id: Id) => void;\n /** Localized suffix marking a required row, supplied by the product. */\n requiredLabel: string;\n /** Localized suffix marking an optional row, supplied by the product. */\n optionalLabel: string;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nfunction Mark({ state }: { state: boolean | \"mixed\" }) {\n return (\n <span aria-hidden=\"true\" className=\"hjm-agreement__mark\" data-state={String(state)}>\n {state === false ? null : <span className=\"hjm-agreement__ink\" />}\n </span>\n );\n}\n\nexport const Agreement = forwardRef(function Agreement<Id extends string = string>(\n {\n descriptor,\n checkedIds: controlledChecked,\n defaultCheckedIds,\n onCheckedIdsChange,\n onStateChange,\n onDetail,\n requiredLabel,\n optionalLabel,\n className,\n layoutStyle,\n }: AgreementProps<Id>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n validateAgreementDescriptor(descriptor);\n const [rawChecked, setChecked] = useControllableState<ReadonlySet<Id>>({\n ...(controlledChecked === undefined ? {} : { value: controlledChecked }),\n defaultValue: defaultCheckedIds ?? new Set<Id>(),\n ...(onCheckedIdsChange === undefined ? {} : { onChange: onCheckedIdsChange }),\n });\n // An item that left the list must not keep an orphan consent behind it.\n const checked = useMemo(\n () => reconcileAgreementSelection(descriptor, rawChecked),\n [descriptor, rawChecked],\n );\n const state = resolveAgreementState(descriptor, checked);\n const id = `${useId().replaceAll(\":\", \"\")}-agreement`;\n\n // Report the initial state once on mount. Until 2026-10-06 only user toggles reported, so\n // `defaultCheckedIds`/`checkedIds` that already satisfied every required item never produced a\n // first `satisfied: true` and a submit button wired to this callback stayed disabled. Mount-only\n // (not on every derived change) keeps the callback count to \"initial + one per toggle\"; StrictMode\n // may repeat the same snapshot, which is idempotent for a consumer that stores it.\n const initialStateRef = useRef(state);\n const onStateChangeRef = useRef(onStateChange);\n onStateChangeRef.current = onStateChange;\n useEffect(() => {\n onStateChangeRef.current?.(initialStateRef.current);\n }, []);\n const commit = (next: ReadonlySet<Id>) => {\n if (descriptor.disabled) return;\n setChecked(next);\n onStateChange?.(resolveAgreementState(descriptor, next));\n };\n\n return (\n <div\n ref={forwardedRef}\n role=\"group\"\n aria-label={descriptor.accessibilityLabel}\n style={layoutStyle}\n className={classNames(\"hjm-agreement\", className)}\n >\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={state.all === \"mixed\" ? \"mixed\" : String(state.all === true) as \"true\" | \"false\"}\n // Keep an already focused consent control reachable while a request locks it.\n aria-disabled={descriptor.disabled || undefined}\n className=\"hjm-agreement__all\"\n onClick={() => commit(toggleAgreementAll(descriptor, checked))}\n >\n <Mark state={state.all} />\n <span>{descriptor.allLabel}</span>\n </button>\n <div className=\"hjm-agreement__list\">\n {descriptor.items.map((item) => {\n const itemChecked = checked.has(item.id);\n return (\n <div key={item.id} className=\"hjm-agreement__item\" data-disabled={item.disabled || undefined}>\n <button\n type=\"button\"\n role=\"checkbox\"\n id={`${id}-${item.id}`}\n aria-checked={itemChecked}\n aria-disabled={descriptor.disabled || item.disabled || undefined}\n aria-describedby={item.description ? `${id}-${item.id}-description` : undefined}\n className=\"hjm-agreement__toggle\"\n onClick={() => { if (!descriptor.disabled && !item.disabled) commit(toggleAgreementItem(descriptor, checked, item.id)); }}\n >\n <Mark state={itemChecked} />\n <span className=\"hjm-agreement__copy\">\n {/*\n Required/optional rides inside the control's own name: a\n visual-only marker would leave a screen reader unable to\n tell which rows block the submit button.\n */}\n <span>{item.label}</span>\n <span className=\"hjm-agreement__required\" data-required={item.required || undefined}>\n {item.required ? requiredLabel : optionalLabel}\n </span>\n </span>\n </button>\n {item.description ? (\n <p id={`${id}-${item.id}-description`} className=\"hjm-agreement__description\">{item.description}</p>\n ) : null}\n {/*\n A separate tab stop that never toggles consent — opening the\n text and agreeing to it are different acts.\n */}\n {item.detail ? (\n item.detail.href ? (\n <a className=\"hjm-agreement__detail\" href={item.detail.href}>{item.detail.label}</a>\n ) : (\n <button type=\"button\" className=\"hjm-agreement__detail\" onClick={() => onDetail?.(item.id)}>\n {item.detail.label}\n </button>\n )\n ) : null}\n </div>\n );\n })}\n </div>\n </div>\n );\n}) as <Id extends string = string>(\n props: AgreementProps<Id> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n\n"]}
1
+ {"version":3,"file":"agreement.js","sourceRoot":"","sources":["../src/agreement.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,2BAA2B,GAG5B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAqBjE,SAAS,IAAI,CAAC,EAAE,KAAK,EAAgC;IACnD,OAAO,CACL,8BAAkB,MAAM,EAAC,SAAS,EAAC,qBAAqB,gBAAa,MAAM,CAAC,KAAK,CAAC,YAC/E,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,oBAAoB,GAAG,GAC5D,CACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,SAAS,CACpD,EACE,UAAU,EACV,UAAU,EAAE,iBAAiB,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,aAAa,EACb,aAAa,EACb,SAAS,EACT,WAAW,GACQ,EACrB,YAAuC;IAEvC,2BAA2B,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,oBAAoB,CAAkB;QACrE,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;QACxE,YAAY,EAAE,iBAAiB,IAAI,IAAI,GAAG,EAAM;QAChD,GAAG,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;KAC9E,CAAC,CAAC;IACH,wEAAwE;IACxE,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,2BAA2B,CAAC,UAAU,EAAE,UAAU,CAAC,EACzD,CAAC,UAAU,EAAE,UAAU,CAAC,CACzB,CAAC;IACF,MAAM,KAAK,GAAG,qBAAqB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACzD,MAAM,EAAE,GAAG,GAAG,KAAK,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC;IAEtD,kFAAkF;IAClF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,iBAAiB,KAAK,SAAS,IAAI,OAAO,KAAK,UAAU;YAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACrF,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IACzD,oFAAoF;IACpF,iFAAiF;IACjF,MAAM,QAAQ,GAAG,MAAM,CAAsE,SAAS,CAAC,CAAC;IACxG,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC;QAClC,IAAI,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;eAC3F,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,KAAK,KAAK,CAAC,kBAAkB,CAAC,MAAM;eAC5E,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;eAC9F,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAAE,OAAO;QAC1G,QAAQ,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACtC,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,CAAC,IAAqB,EAAE,EAAE;QACvC,IAAI,UAAU,CAAC,QAAQ;YAAE,OAAO;QAChC,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO,CACL,eACE,GAAG,EAAE,YAAY,EACjB,IAAI,EAAC,OAAO,gBACA,UAAU,CAAC,kBAAkB,EACzC,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,UAAU,CAAC,eAAe,EAAE,SAAS,CAAC,aAEjD,kBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,UAAU,kBACD,KAAK,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,CAAqB,mBAE/E,UAAU,CAAC,QAAQ,IAAI,SAAS,EAC/C,SAAS,EAAC,oBAAoB,EAC9B,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,aAE9D,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,GAAG,GAAI,EAC1B,yBAAO,UAAU,CAAC,QAAQ,GAAQ,IAC3B,EACT,cAAK,SAAS,EAAC,qBAAqB,YACjC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;oBAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACzC,OAAO,CACL,eAAmB,SAAS,EAAC,qBAAqB,mBAAgB,IAAI,CAAC,QAAQ,IAAI,SAAS,aAC1F,kBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,UAAU,EACf,EAAE,EAAE,GAAG,EAAE,IAAI,IAAI,CAAC,EAAE,EAAE,kBACR,WAAW,mBACV,UAAU,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,IAAI,SAAS,sBAC9C,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS,EAC/E,SAAS,EAAC,uBAAuB,EACjC,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ;oCAAE,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAEzH,KAAC,IAAI,IAAC,KAAK,EAAE,WAAW,GAAI,EAC5B,gBAAM,SAAS,EAAC,qBAAqB,aAMnC,yBAAO,IAAI,CAAC,KAAK,GAAQ,EACzB,eAAM,SAAS,EAAC,yBAAyB,mBAAgB,IAAI,CAAC,QAAQ,IAAI,SAAS,YAChF,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,GACzC,IACF,IACA,EACR,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAClB,YAAG,EAAE,EAAE,GAAG,EAAE,IAAI,IAAI,CAAC,EAAE,cAAc,EAAE,SAAS,EAAC,4BAA4B,YAAE,IAAI,CAAC,WAAW,GAAK,CACrG,CAAC,CAAC,CAAC,IAAI,EAKP,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CACjB,YAAG,SAAS,EAAC,uBAAuB,EAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,YAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAK,CACrF,CAAC,CAAC,CAAC,CACF,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,uBAAuB,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,YACvF,IAAI,CAAC,MAAM,CAAC,KAAK,GACX,CACV,CACF,CAAC,CAAC,CAAC,IAAI,KAvCA,IAAI,CAAC,EAAE,CAwCX,CACP,CAAC;gBACJ,CAAC,CAAC,GACE,IACF,CACP,CAAC;AACJ,CAAC,CAE6B,CAAC","sourcesContent":["import {\n reconcileAgreementSelection,\n resolveAgreementState,\n toggleAgreementAll,\n toggleAgreementItem,\n validateAgreementDescriptor,\n type AgreementDescriptor,\n type AgreementState,\n} from \"@hjmds/design-contracts/components/agreement\";\nimport { forwardRef, useEffect, useId, useMemo, useRef } from \"react\";\nimport { classNames, useControllableState } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type AgreementProps<Id extends string = string> = Readonly<{\n descriptor: AgreementDescriptor<Id>;\n checkedIds?: ReadonlySet<Id>;\n defaultCheckedIds?: ReadonlySet<Id>;\n onCheckedIdsChange?: (ids: ReadonlySet<Id>) => void;\n /** Fires the derived state on every change, for a submit button to read. */\n onStateChange?: (state: AgreementState<Id>) => void;\n /** Called when an item's full text is requested and it carries no href. */\n onDetail?: (id: Id) => void;\n /** Localized suffix marking a required row, supplied by the product. */\n requiredLabel: string;\n /** Localized suffix marking an optional row, supplied by the product. */\n optionalLabel: string;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nfunction Mark({ state }: { state: boolean | \"mixed\" }) {\n return (\n <span aria-hidden=\"true\" className=\"hjm-agreement__mark\" data-state={String(state)}>\n {state === false ? null : <span className=\"hjm-agreement__ink\" />}\n </span>\n );\n}\n\nexport const Agreement = forwardRef(function Agreement<Id extends string = string>(\n {\n descriptor,\n checkedIds: controlledChecked,\n defaultCheckedIds,\n onCheckedIdsChange,\n onStateChange,\n onDetail,\n requiredLabel,\n optionalLabel,\n className,\n layoutStyle,\n }: AgreementProps<Id>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n validateAgreementDescriptor(descriptor);\n const [rawChecked, setChecked] = useControllableState<ReadonlySet<Id>>({\n ...(controlledChecked === undefined ? {} : { value: controlledChecked }),\n defaultValue: defaultCheckedIds ?? new Set<Id>(),\n ...(onCheckedIdsChange === undefined ? {} : { onChange: onCheckedIdsChange }),\n });\n // An item that left the list must not keep an orphan consent behind it.\n const checked = useMemo(\n () => reconcileAgreementSelection(descriptor, rawChecked),\n [descriptor, rawChecked],\n );\n const state = resolveAgreementState(descriptor, checked);\n const id = `${useId().replaceAll(\":\", \"\")}-agreement`;\n\n // Persist removed consent IDs so reinserting a row cannot silently consent again.\n useEffect(() => {\n if (controlledChecked === undefined && checked !== rawChecked) setChecked(checked);\n }, [checked, controlledChecked, rawChecked, setChecked]);\n // Report accepted state, including external value/required-item changes. A rejected\n // controlled request must not enable the product's submit button optimistically.\n const reported = useRef<{ checked: ReadonlySet<Id>; state: AgreementState<Id> } | undefined>(undefined);\n useEffect(() => {\n const previous = reported.current;\n if (previous && previous.state.all === state.all && previous.state.satisfied === state.satisfied\n && previous.state.missingRequiredIds.length === state.missingRequiredIds.length\n && previous.state.missingRequiredIds.every((id, index) => id === state.missingRequiredIds[index])\n && previous.checked.size === checked.size && [...checked].every(id => previous.checked.has(id))) return;\n reported.current = { checked, state };\n onStateChange?.(state);\n });\n const commit = (next: ReadonlySet<Id>) => {\n if (descriptor.disabled) return;\n setChecked(next);\n };\n\n return (\n <div\n ref={forwardedRef}\n role=\"group\"\n aria-label={descriptor.accessibilityLabel}\n style={layoutStyle}\n className={classNames(\"hjm-agreement\", className)}\n >\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={state.all === \"mixed\" ? \"mixed\" : String(state.all === true) as \"true\" | \"false\"}\n // Keep an already focused consent control reachable while a request locks it.\n aria-disabled={descriptor.disabled || undefined}\n className=\"hjm-agreement__all\"\n onClick={() => commit(toggleAgreementAll(descriptor, checked))}\n >\n <Mark state={state.all} />\n <span>{descriptor.allLabel}</span>\n </button>\n <div className=\"hjm-agreement__list\">\n {descriptor.items.map((item) => {\n const itemChecked = checked.has(item.id);\n return (\n <div key={item.id} className=\"hjm-agreement__item\" data-disabled={item.disabled || undefined}>\n <button\n type=\"button\"\n role=\"checkbox\"\n id={`${id}-${item.id}`}\n aria-checked={itemChecked}\n aria-disabled={descriptor.disabled || item.disabled || undefined}\n aria-describedby={item.description ? `${id}-${item.id}-description` : undefined}\n className=\"hjm-agreement__toggle\"\n onClick={() => { if (!descriptor.disabled && !item.disabled) commit(toggleAgreementItem(descriptor, checked, item.id)); }}\n >\n <Mark state={itemChecked} />\n <span className=\"hjm-agreement__copy\">\n {/*\n Required/optional rides inside the control's own name: a\n visual-only marker would leave a screen reader unable to\n tell which rows block the submit button.\n */}\n <span>{item.label}</span>\n <span className=\"hjm-agreement__required\" data-required={item.required || undefined}>\n {item.required ? requiredLabel : optionalLabel}\n </span>\n </span>\n </button>\n {item.description ? (\n <p id={`${id}-${item.id}-description`} className=\"hjm-agreement__description\">{item.description}</p>\n ) : null}\n {/*\n A separate tab stop that never toggles consent — opening the\n text and agreeing to it are different acts.\n */}\n {item.detail ? (\n item.detail.href ? (\n <a className=\"hjm-agreement__detail\" href={item.detail.href}>{item.detail.label}</a>\n ) : (\n <button type=\"button\" className=\"hjm-agreement__detail\" onClick={() => onDetail?.(item.id)}>\n {item.detail.label}\n </button>\n )\n ) : null}\n </div>\n );\n })}\n </div>\n </div>\n );\n}) as <Id extends string = string>(\n props: AgreementProps<Id> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-screen.d.ts","sourceRoot":"","sources":["../src/auth-screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAExE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,GAC/E,oBAAoB,GACpB,QAAQ,CAAC;IACP,8EAA8E;IAC9E,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,+EAA+E;IAC/E,IAAI,EAAE,SAAS,CAAC;IAChB,sFAAsF;IACtF,IAAI,EAAE,SAAS,CAAC;IAChB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;IAtBzB,8EAA8E;SACzE,MAAM,GAAG,SAAS;IACvB,+EAA+E;UACzE,SAAS;IACf,sFAAsF;UAChF,SAAS;IACf,2FAA2F;mBAC5E,MAAM;IACrB,4FAA4F;eACjF,OAAO;IAClB,qEAAqE;aAC5D,SAAS;gBACN,MAAM;IAClB,gGAAgG;kBAClF,uBAAuB;gDAoDxC,CAAC"}
1
+ {"version":3,"file":"auth-screen.d.ts","sourceRoot":"","sources":["../src/auth-screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAuC,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjG,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,GAC/E,oBAAoB,GACpB,QAAQ,CAAC;IACP,8EAA8E;IAC9E,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,+EAA+E;IAC/E,IAAI,EAAE,SAAS,CAAC;IAChB,sFAAsF;IACtF,IAAI,EAAE,SAAS,CAAC;IAChB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;IAtBzB,8EAA8E;SACzE,MAAM,GAAG,SAAS;IACvB,+EAA+E;UACzE,SAAS;IACf,sFAAsF;UAChF,SAAS;IACf,2FAA2F;mBAC5E,MAAM;IACrB,4FAA4F;eACjF,OAAO;IAClB,qEAAqE;aAC5D,SAAS;gBACN,MAAM;IAClB,gGAAgG;kBAClF,uBAAuB;gDAkExC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { resolveAuthScreenDescriptor, } from "@hjmds/design-contracts/components/auth-screen";
3
- import { forwardRef } from "react";
3
+ import { forwardRef, useLayoutEffect, useRef } from "react";
4
4
  import { classNames } from "./internal.js";
5
5
  /**
6
6
  * Two regions: hero + main stay one vertically centred block, the footer sits at
@@ -14,6 +14,18 @@ export const AuthScreenLayout = forwardRef(function AuthScreenLayout({ hero, mai
14
14
  });
15
15
  const showFooter = resolved.hasFooter && footer !== undefined && footer !== null;
16
16
  const pending = pendingLabel !== undefined;
17
+ const actionsRef = useRef(null);
18
+ const focusedAction = useRef(null);
19
+ const wasPending = useRef(pending);
20
+ useLayoutEffect(() => {
21
+ // Inert loading content sends keyboard focus to body. Resume at the same
22
+ // action after failure/cancellation, unless the user moved somewhere else.
23
+ const target = focusedAction.current;
24
+ if (wasPending.current && !pending && document.activeElement === document.body && target?.isConnected && actionsRef.current?.contains(target)) {
25
+ target.focus({ preventScroll: true });
26
+ }
27
+ wasPending.current = pending;
28
+ }, [pending]);
17
29
  if (pending && !pendingLabel.trim())
18
30
  throw new TypeError("AuthScreen pendingLabel must not be empty");
19
31
  return (_jsxs(Element, { ...props, ref: forwardedRef, className: classNames("hjm-auth-screen", className), "data-density": resolved.density, style: {
@@ -25,6 +37,7 @@ export const AuthScreenLayout = forwardRef(function AuthScreenLayout({ hero, mai
25
37
  ["--hjm-auth-screen-padding-block"]: `${resolved.paddingBlock}px`,
26
38
  ...props.style,
27
39
  ...layoutStyle,
28
- }, children: [_jsxs("div", { className: "hjm-auth-screen__block", children: [_jsx("div", { className: "hjm-auth-screen__hero", children: hero }), _jsxs("div", { className: "hjm-auth-screen__main", "data-card": mainCard || undefined, "aria-busy": pending || undefined, children: [_jsx("div", { className: "hjm-auth-screen__actions", inert: pending, "aria-hidden": pending || undefined, style: pending ? { visibility: "hidden" } : undefined, children: main }), pending ? _jsx("div", { className: "hjm-auth-screen__pending", role: "status", "aria-label": pendingLabel, children: _jsx("span", { className: "hjm-auth-provider-button__spinner", "aria-hidden": "true" }) }) : null] })] }), showFooter ? _jsx("div", { className: "hjm-auth-screen__footer", children: footer }) : null] }));
40
+ }, children: [_jsxs("div", { className: "hjm-auth-screen__block", children: [_jsx("div", { className: "hjm-auth-screen__hero", children: hero }), _jsxs("div", { className: "hjm-auth-screen__main", "data-card": mainCard || undefined, "aria-busy": pending || undefined, children: [_jsx("div", { ref: actionsRef, className: "hjm-auth-screen__actions", inert: pending, "aria-hidden": pending || undefined, onFocusCapture: event => { focusedAction.current = event.target; }, onBlurCapture: event => { if (!pending && !event.currentTarget.contains(event.relatedTarget))
41
+ focusedAction.current = null; }, style: pending ? { visibility: "hidden" } : undefined, children: main }), pending ? _jsx("div", { className: "hjm-auth-screen__pending", role: "status", "aria-label": pendingLabel, children: _jsx("span", { className: "hjm-auth-provider-button__spinner", "aria-hidden": "true" }) }) : null] })] }), showFooter ? _jsx("div", { className: "hjm-auth-screen__footer", children: footer }) : null] }));
29
42
  });
30
43
  //# sourceMappingURL=auth-screen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-screen.js","sourceRoot":"","sources":["../src/auth-screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,2BAA2B,GAE5B,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,UAAU,EAAuC,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAuB3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CACxC,SAAS,gBAAgB,CACvB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,GAAG,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAClI,YAAY;IAEZ,MAAM,QAAQ,GAAG,2BAA2B,CAAC;QAC3C,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QAC7C,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;KAClD,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC;IACjF,MAAM,OAAO,GAAG,YAAY,KAAK,SAAS,CAAC;IAC3C,IAAI,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;IACtG,OAAO,CACL,MAAC,OAAO,OACF,KAAK,EACT,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,UAAU,CAAC,iBAAiB,EAAE,SAAS,CAAC,kBACrC,QAAQ,CAAC,OAAO,EAC9B,KAAK,EAAE;YACL,CAAC,6BAAuC,CAAC,EAAE,GAAG,QAAQ,CAAC,QAAQ,IAAI;YACnE,CAAC,4BAAsC,CAAC,EAAE,GAAG,QAAQ,CAAC,OAAO,IAAI;YACjE,CAAC,4BAAsC,CAAC,EAAE,GAAG,QAAQ,CAAC,OAAO,IAAI;YACjE,CAAC,8BAAwC,CAAC,EAAE,GAAG,QAAQ,CAAC,SAAS,IAAI;YACrE,CAAC,kCAA4C,CAAC,EAAE,GAAG,QAAQ,CAAC,aAAa,IAAI;YAC7E,CAAC,iCAA2C,CAAC,EAAE,GAAG,QAAQ,CAAC,YAAY,IAAI;YAC3E,GAAG,KAAK,CAAC,KAAK;YACd,GAAG,WAAW;SACf,aAED,eAAK,SAAS,EAAC,wBAAwB,aACrC,cAAK,SAAS,EAAC,uBAAuB,YAAE,IAAI,GAAO,EACnD,eAAK,SAAS,EAAC,uBAAuB,eAAY,QAAQ,IAAI,SAAS,eAAa,OAAO,IAAI,SAAS,aAEtG,cAAK,SAAS,EAAC,0BAA0B,EAAC,KAAK,EAAE,OAAO,iBAAe,OAAO,IAAI,SAAS,EACzF,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,YAAG,IAAI,GAAO,EACpE,OAAO,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,0BAA0B,EAAC,IAAI,EAAC,QAAQ,gBAAa,YAAY,YACzF,eAAM,SAAS,EAAC,mCAAmC,iBAAa,MAAM,GAAG,GACrE,CAAC,CAAC,CAAC,IAAI,IACT,IACF,EACL,UAAU,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,yBAAyB,YAAE,MAAM,GAAO,CAAC,CAAC,CAAC,IAAI,IACpE,CACX,CAAC;AACJ,CAAC,CACF,CAAC","sourcesContent":["import {\n resolveAuthScreenDescriptor,\n type AuthScreenDescriptor,\n} from \"@hjmds/design-contracts/components/auth-screen\";\nimport { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type AuthScreenLayoutProps = Omit<HTMLAttributes<HTMLElement>, \"children\"> &\n AuthScreenDescriptor &\n Readonly<{\n /** Use section inside a product shell that already owns the main landmark. */\n as?: \"main\" | \"section\";\n /** Product mark, title and description. The product owns every string here. */\n hero: ReactNode;\n /** The primary action block — provider buttons, or a product's own sign-in bundle. */\n main: ReactNode;\n /** Product-localized progress label; presence replaces actions with one centred loader. */\n pendingLabel?: string;\n /** Let the layout own the action card; omit when the product already supplies a surface. */\n mainCard?: boolean;\n /** Consent notice and policy links. Omit with `hasFooter: false`. */\n footer?: ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/**\n * Two regions: hero + main stay one vertically centred block, the footer sits at\n * the bottom. The measurements come from the resolved descriptor as custom\n * properties so the stylesheet keeps one source of truth with the contract.\n */\nexport const AuthScreenLayout = forwardRef<HTMLElement, AuthScreenLayoutProps>(\n function AuthScreenLayout(\n { hero, main, footer, density, hasFooter, pendingLabel, mainCard = false, className, as: Element = \"main\", layoutStyle, ...props },\n forwardedRef,\n ) {\n const resolved = resolveAuthScreenDescriptor({\n ...(density === undefined ? {} : { density }),\n ...(hasFooter === undefined ? {} : { hasFooter }),\n });\n const showFooter = resolved.hasFooter && footer !== undefined && footer !== null;\n const pending = pendingLabel !== undefined;\n if (pending && !pendingLabel.trim()) throw new TypeError(\"AuthScreen pendingLabel must not be empty\");\n return (\n <Element\n {...props}\n ref={forwardedRef}\n className={classNames(\"hjm-auth-screen\", className)}\n data-density={resolved.density}\n style={{\n [\"--hjm-auth-screen-max-width\" as string]: `${resolved.maxWidth}px`,\n [\"--hjm-auth-screen-hero-gap\" as string]: `${resolved.heroGap}px`,\n [\"--hjm-auth-screen-main-gap\" as string]: `${resolved.mainGap}px`,\n [\"--hjm-auth-screen-footer-gap\" as string]: `${resolved.footerGap}px`,\n [\"--hjm-auth-screen-padding-inline\" as string]: `${resolved.paddingInline}px`,\n [\"--hjm-auth-screen-padding-block\" as string]: `${resolved.paddingBlock}px`,\n ...props.style,\n ...layoutStyle,\n }}\n >\n <div className=\"hjm-auth-screen__block\">\n <div className=\"hjm-auth-screen__hero\">{hero}</div>\n <div className=\"hjm-auth-screen__main\" data-card={mainCard || undefined} aria-busy={pending || undefined}>\n {/* Keep the action block in flow so the card never collapses; inert also removes keyboard access. */}\n <div className=\"hjm-auth-screen__actions\" inert={pending} aria-hidden={pending || undefined}\n style={pending ? { visibility: \"hidden\" } : undefined}>{main}</div>\n {pending ? <div className=\"hjm-auth-screen__pending\" role=\"status\" aria-label={pendingLabel}>\n <span className=\"hjm-auth-provider-button__spinner\" aria-hidden=\"true\" />\n </div> : null}\n </div>\n </div>\n {showFooter ? <div className=\"hjm-auth-screen__footer\">{footer}</div> : null}\n </Element>\n );\n },\n);\n"]}
1
+ {"version":3,"file":"auth-screen.js","sourceRoot":"","sources":["../src/auth-screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n resolveAuthScreenDescriptor,\n type AuthScreenDescriptor,\n} from \"@hjmds/design-contracts/components/auth-screen\";\nimport { forwardRef, useLayoutEffect, useRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type AuthScreenLayoutProps = Omit<HTMLAttributes<HTMLElement>, \"children\"> &\n AuthScreenDescriptor &\n Readonly<{\n /** Use section inside a product shell that already owns the main landmark. */\n as?: \"main\" | \"section\";\n /** Product mark, title and description. The product owns every string here. */\n hero: ReactNode;\n /** The primary action block — provider buttons, or a product's own sign-in bundle. */\n main: ReactNode;\n /** Product-localized progress label; presence replaces actions with one centred loader. */\n pendingLabel?: string;\n /** Let the layout own the action card; omit when the product already supplies a surface. */\n mainCard?: boolean;\n /** Consent notice and policy links. Omit with `hasFooter: false`. */\n footer?: ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/**\n * Two regions: hero + main stay one vertically centred block, the footer sits at\n * the bottom. The measurements come from the resolved descriptor as custom\n * properties so the stylesheet keeps one source of truth with the contract.\n */\nexport const AuthScreenLayout = forwardRef<HTMLElement, AuthScreenLayoutProps>(\n function AuthScreenLayout(\n { hero, main, footer, density, hasFooter, pendingLabel, mainCard = false, className, as: Element = \"main\", layoutStyle, ...props },\n forwardedRef,\n ) {\n const resolved = resolveAuthScreenDescriptor({\n ...(density === undefined ? {} : { density }),\n ...(hasFooter === undefined ? {} : { hasFooter }),\n });\n const showFooter = resolved.hasFooter && footer !== undefined && footer !== null;\n const pending = pendingLabel !== undefined;\n const actionsRef = useRef<HTMLDivElement>(null);\n const focusedAction = useRef<HTMLElement | null>(null);\n const wasPending = useRef(pending);\n useLayoutEffect(() => {\n // Inert loading content sends keyboard focus to body. Resume at the same\n // action after failure/cancellation, unless the user moved somewhere else.\n const target = focusedAction.current;\n if (wasPending.current && !pending && document.activeElement === document.body && target?.isConnected && actionsRef.current?.contains(target)) {\n target.focus({ preventScroll: true });\n }\n wasPending.current = pending;\n }, [pending]);\n if (pending && !pendingLabel.trim()) throw new TypeError(\"AuthScreen pendingLabel must not be empty\");\n return (\n <Element\n {...props}\n ref={forwardedRef}\n className={classNames(\"hjm-auth-screen\", className)}\n data-density={resolved.density}\n style={{\n [\"--hjm-auth-screen-max-width\" as string]: `${resolved.maxWidth}px`,\n [\"--hjm-auth-screen-hero-gap\" as string]: `${resolved.heroGap}px`,\n [\"--hjm-auth-screen-main-gap\" as string]: `${resolved.mainGap}px`,\n [\"--hjm-auth-screen-footer-gap\" as string]: `${resolved.footerGap}px`,\n [\"--hjm-auth-screen-padding-inline\" as string]: `${resolved.paddingInline}px`,\n [\"--hjm-auth-screen-padding-block\" as string]: `${resolved.paddingBlock}px`,\n ...props.style,\n ...layoutStyle,\n }}\n >\n <div className=\"hjm-auth-screen__block\">\n <div className=\"hjm-auth-screen__hero\">{hero}</div>\n <div className=\"hjm-auth-screen__main\" data-card={mainCard || undefined} aria-busy={pending || undefined}>\n {/* Keep the action block in flow so the card never collapses; inert also removes keyboard access. */}\n <div ref={actionsRef} className=\"hjm-auth-screen__actions\" inert={pending} aria-hidden={pending || undefined}\n onFocusCapture={event => { focusedAction.current = event.target; }}\n onBlurCapture={event => { if (!pending && !event.currentTarget.contains(event.relatedTarget)) focusedAction.current = null; }}\n style={pending ? { visibility: \"hidden\" } : undefined}>{main}</div>\n {pending ? <div className=\"hjm-auth-screen__pending\" role=\"status\" aria-label={pendingLabel}>\n <span className=\"hjm-auth-provider-button__spinner\" aria-hidden=\"true\" />\n </div> : null}\n </div>\n </div>\n {showFooter ? <div className=\"hjm-auth-screen__footer\">{footer}</div> : null}\n </Element>\n );\n },\n);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"avatar-blobatar-motion.d.ts","sourceRoot":"","sources":["../src/avatar-blobatar-motion.tsx"],"names":[],"mappings":"AAAA,OAAM,EAA2B,KAAK,SAAS,EAAC,MAAI,OAAO,CAAC;AAAqH,OAAM,qBAAqB,CAAC;AAC7M,OAAM,EAAuB,KAAK,qBAAqB,EAAC,KAAK,qBAAqB,EAAC,MAAI,yCAAyC,CAAC;AAOjI,4EAA4E;AAC5E,wBAAgB,8BAA8B,CAAC,OAAO,EAAC,qBAAqB,GAAE,CAAC,OAAO,EAAC,qBAAqB,KAAG,SAAS,CAA0F"}
1
+ {"version":3,"file":"avatar-blobatar-motion.d.ts","sourceRoot":"","sources":["../src/avatar-blobatar-motion.tsx"],"names":[],"mappings":"AAAA,OAAM,EAA2B,KAAK,SAAS,EAAC,MAAI,OAAO,CAAC;AAAqH,OAAM,qBAAqB,CAAC;AAC7M,OAAM,EAAuB,KAAK,qBAAqB,EAAC,KAAK,qBAAqB,EAAC,MAAI,yCAAyC,CAAC;AAcjI,4EAA4E;AAC5E,wBAAgB,8BAA8B,CAAC,OAAO,EAAC,qBAAqB,GAAE,CAAC,OAAO,EAAC,qBAAqB,KAAG,SAAS,CAA0F"}
@@ -12,8 +12,16 @@ function Artwork({ size, options }) {
12
12
  const host = useRef(null);
13
13
  const [visible, setVisible] = useState(false);
14
14
  const [foreground, setForeground] = useState(false);
15
- useEffect(() => { const update = () => setForeground(!document.hidden); update(); document.addEventListener('visibilitychange', update); const observer = new IntersectionObserver(entries => setVisible(entries.some(e => e.isIntersecting))); if (host.current)
16
- observer.observe(host.current); return () => { observer.disconnect(); document.removeEventListener('visibilitychange', update); }; }, []);
15
+ useEffect(() => {
16
+ const update = () => setForeground(!document.hidden);
17
+ update();
18
+ document.addEventListener('visibilitychange', update);
19
+ // Without viewport observation, keep decorative artwork static instead of failing the avatar.
20
+ const observer = typeof IntersectionObserver === 'undefined' ? undefined : new IntersectionObserver(entries => setVisible(entries.some(entry => entry.isIntersecting)));
21
+ if (host.current)
22
+ observer?.observe(host.current);
23
+ return () => { observer?.disconnect(); document.removeEventListener('visibilitychange', update); };
24
+ }, []);
17
25
  const active = spec.active && spec.visible && visible && foreground && !environment.reducedMotion;
18
26
  return _jsx("span", { ref: host, "aria-hidden": "true", style: { display: 'block' }, children: _jsx(Blobatar, { name: spec.seed, size: size, normalize: false, expression: expressions[spec.expression], animate: active ? 'always' : false, alt: "", "aria-hidden": "true" }) });
19
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"avatar-blobatar-motion.js","sourceRoot":"","sources":["../src/avatar-blobatar-motion.tsx"],"names":[],"mappings":";AAAA,OAAM,EAAC,SAAS,EAAC,MAAM,EAAC,QAAQ,EAAgB,MAAI,OAAO,CAAC;AAAA,OAAM,EAAC,QAAQ,EAAC,MAAI,iBAAiB,CAAC;AAAA,OAAM,EAAC,IAAI,EAAC,KAAK,EAAC,GAAG,EAAC,SAAS,EAAC,IAAI,EAAC,MAAM,EAAC,QAAQ,EAAC,MAAI,qBAAqB,CAAC;AAAA,OAAM,qBAAqB,CAAC;AAC7M,OAAM,EAAC,qBAAqB,EAAuD,MAAI,yCAAyC,CAAC;AAAA,OAAM,EAAC,WAAW,EAAC,MAAI,eAAe,CAAC;AACxK,MAAM,WAAW,GAAC,EAAC,IAAI,EAAC,KAAK,EAAC,GAAG,EAAC,SAAS,EAAC,IAAI,EAAC,MAAM,EAAC,QAAQ,EAAC,CAAC;AAClE,SAAS,OAAO,CAAC,EAAC,IAAI,EAAC,OAAO,EAA6C;IAAE,MAAM,IAAI,GAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAAA,MAAK,EAAC,WAAW,EAAC,GAAC,WAAW,EAAE,CAAC;IAAA,MAAM,IAAI,GAAC,MAAM,CAAkB,IAAI,CAAC,CAAC;IAAA,MAAK,CAAC,OAAO,EAAC,UAAU,CAAC,GAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAAA,MAAK,CAAC,UAAU,EAAC,aAAa,CAAC,GAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1R,SAAS,CAAC,GAAE,EAAE,GAAC,MAAM,MAAM,GAAC,GAAE,EAAE,CAAA,aAAa,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA,MAAM,EAAE,CAAC,CAAA,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAC,MAAM,CAAC,CAAC,CAAA,MAAM,QAAQ,GAAC,IAAI,oBAAoB,CAAC,OAAO,CAAA,EAAE,CAAA,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA,IAAG,IAAI,CAAC,OAAO;QAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA,OAAM,GAAE,EAAE,GAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAC,MAAM,CAAC,CAAC,CAAA,CAAC,CAAC,CAAA,CAAC,EAAC,EAAE,CAAC,CAAC;IAC9W,MAAM,MAAM,GAAC,IAAI,CAAC,MAAM,IAAE,IAAI,CAAC,OAAO,IAAE,OAAO,IAAE,UAAU,IAAE,CAAC,WAAW,CAAC,aAAa,CAAC;IACxF,OAAO,eAAM,GAAG,EAAE,IAAI,iBAAc,MAAM,EAAC,KAAK,EAAE,EAAC,OAAO,EAAC,OAAO,EAAC,YAAE,KAAC,QAAQ,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,CAAA,CAAC,CAAA,QAAQ,CAAA,CAAC,CAAA,KAAK,EAAE,GAAG,EAAC,EAAE,iBAAa,MAAM,GAAE,GAAO,CAAC;AAC5O,CAAC;AACD,4EAA4E;AAC5E,MAAM,UAAU,8BAA8B,CAAC,OAA6B,IAA6C,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAA,OAAM,CAAC,EAAC,IAAI,EAAC,EAAC,EAAE,CAAA,KAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,CAAA,CAAC","sourcesContent":["import{useEffect,useRef,useState,type ReactNode}from'react';import{Blobatar}from'@blobatar/react';import{idle,happy,sad,surprised,wink,sleepy,thinking}from'blobatar/expression';import'blobatar/motion.css';\nimport{resolveBlobatarMotion,type BlobatarMotionOptions,type AvatarFallbackContext}from'@hjmds/design-contracts/avatar-fallback';import{useHjmTheme}from'./provider.js';\nconst expressions={idle,happy,sad,surprised,wink,sleepy,thinking};\nfunction Artwork({size,options}:{size:number;options:BlobatarMotionOptions}){const spec=resolveBlobatarMotion(options);const{environment}=useHjmTheme();const host=useRef<HTMLSpanElement>(null);const[visible,setVisible]=useState(false);const[foreground,setForeground]=useState(false);\n useEffect(()=>{const update=()=>setForeground(!document.hidden);update();document.addEventListener('visibilitychange',update);const observer=new IntersectionObserver(entries=>setVisible(entries.some(e=>e.isIntersecting)));if(host.current)observer.observe(host.current);return()=>{observer.disconnect();document.removeEventListener('visibilitychange',update);};},[]);\n const active=spec.active&&spec.visible&&visible&&foreground&&!environment.reducedMotion;\n return <span ref={host} aria-hidden=\"true\" style={{display:'block'}}><Blobatar name={spec.seed} size={size} normalize={false} expression={expressions[spec.expression]} animate={active?'always':false} alt=\"\" aria-hidden=\"true\"/></span>;\n}\n/** Optional animated entry. Static avatar imports never load motion CSS. */\nexport function createAnimatedBlobatarFallback(options:BlobatarMotionOptions):(context:AvatarFallbackContext)=>ReactNode{resolveBlobatarMotion(options);return({size})=><Artwork size={size} options={options}/>;}\n"]}
1
+ {"version":3,"file":"avatar-blobatar-motion.js","sourceRoot":"","sources":["../src/avatar-blobatar-motion.tsx"],"names":[],"mappings":";AAAA,OAAM,EAAC,SAAS,EAAC,MAAM,EAAC,QAAQ,EAAgB,MAAI,OAAO,CAAC;AAAA,OAAM,EAAC,QAAQ,EAAC,MAAI,iBAAiB,CAAC;AAAA,OAAM,EAAC,IAAI,EAAC,KAAK,EAAC,GAAG,EAAC,SAAS,EAAC,IAAI,EAAC,MAAM,EAAC,QAAQ,EAAC,MAAI,qBAAqB,CAAC;AAAA,OAAM,qBAAqB,CAAC;AAC7M,OAAM,EAAC,qBAAqB,EAAuD,MAAI,yCAAyC,CAAC;AAAA,OAAM,EAAC,WAAW,EAAC,MAAI,eAAe,CAAC;AACxK,MAAM,WAAW,GAAC,EAAC,IAAI,EAAC,KAAK,EAAC,GAAG,EAAC,SAAS,EAAC,IAAI,EAAC,MAAM,EAAC,QAAQ,EAAC,CAAC;AAClE,SAAS,OAAO,CAAC,EAAC,IAAI,EAAC,OAAO,EAA6C;IAAE,MAAM,IAAI,GAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAAA,MAAK,EAAC,WAAW,EAAC,GAAC,WAAW,EAAE,CAAC;IAAA,MAAM,IAAI,GAAC,MAAM,CAAkB,IAAI,CAAC,CAAC;IAAA,MAAK,CAAC,OAAO,EAAC,UAAU,CAAC,GAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAAA,MAAK,CAAC,UAAU,EAAC,aAAa,CAAC,GAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1R,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QAChE,8FAA8F;QAC9F,MAAM,QAAQ,GAAG,OAAO,oBAAoB,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QACxK,IAAI,IAAI,CAAC,OAAO;YAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACrG,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,MAAM,MAAM,GAAC,IAAI,CAAC,MAAM,IAAE,IAAI,CAAC,OAAO,IAAE,OAAO,IAAE,UAAU,IAAE,CAAC,WAAW,CAAC,aAAa,CAAC;IACxF,OAAO,eAAM,GAAG,EAAE,IAAI,iBAAc,MAAM,EAAC,KAAK,EAAE,EAAC,OAAO,EAAC,OAAO,EAAC,YAAE,KAAC,QAAQ,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,CAAA,CAAC,CAAA,QAAQ,CAAA,CAAC,CAAA,KAAK,EAAE,GAAG,EAAC,EAAE,iBAAa,MAAM,GAAE,GAAO,CAAC;AAC5O,CAAC;AACD,4EAA4E;AAC5E,MAAM,UAAU,8BAA8B,CAAC,OAA6B,IAA6C,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAA,OAAM,CAAC,EAAC,IAAI,EAAC,EAAC,EAAE,CAAA,KAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,CAAA,CAAC","sourcesContent":["import{useEffect,useRef,useState,type ReactNode}from'react';import{Blobatar}from'@blobatar/react';import{idle,happy,sad,surprised,wink,sleepy,thinking}from'blobatar/expression';import'blobatar/motion.css';\nimport{resolveBlobatarMotion,type BlobatarMotionOptions,type AvatarFallbackContext}from'@hjmds/design-contracts/avatar-fallback';import{useHjmTheme}from'./provider.js';\nconst expressions={idle,happy,sad,surprised,wink,sleepy,thinking};\nfunction Artwork({size,options}:{size:number;options:BlobatarMotionOptions}){const spec=resolveBlobatarMotion(options);const{environment}=useHjmTheme();const host=useRef<HTMLSpanElement>(null);const[visible,setVisible]=useState(false);const[foreground,setForeground]=useState(false);\n useEffect(() => {\n const update = () => setForeground(!document.hidden);\n update(); document.addEventListener('visibilitychange', update);\n // Without viewport observation, keep decorative artwork static instead of failing the avatar.\n const observer = typeof IntersectionObserver === 'undefined' ? undefined : new IntersectionObserver(entries => setVisible(entries.some(entry => entry.isIntersecting)));\n if (host.current) observer?.observe(host.current);\n return () => { observer?.disconnect(); document.removeEventListener('visibilitychange', update); };\n }, []);\n const active=spec.active&&spec.visible&&visible&&foreground&&!environment.reducedMotion;\n return <span ref={host} aria-hidden=\"true\" style={{display:'block'}}><Blobatar name={spec.seed} size={size} normalize={false} expression={expressions[spec.expression]} animate={active?'always':false} alt=\"\" aria-hidden=\"true\"/></span>;\n}\n/** Optional animated entry. Static avatar imports never load motion CSS. */\nexport function createAnimatedBlobatarFallback(options:BlobatarMotionOptions):(context:AvatarFallbackContext)=>ReactNode{resolveBlobatarMotion(options);return({size})=><Artwork size={size} options={options}/>;}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bottom-navigation.d.ts","sourceRoot":"","sources":["../src/bottom-navigation.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bottom-navigation.d.ts","sourceRoot":"","sources":["../src/bottom-navigation.tsx"],"names":[],"mappings":"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"}
@@ -71,7 +71,7 @@ function BottomNavigationInner({ descriptor, configuration = {}, getHref, render
71
71
  const iconSize = iconRecipe.sizes[density.icon];
72
72
  if (hidden)
73
73
  return null;
74
- return (_jsx("nav", { ...props, ref: ref, "aria-label": resolved.accessibilityLabel, className: classNames("hjm-bottom-navigation", className), "data-expanded-labels": (theme?.environment.textScale ?? 1) >= 1.5 || resolved.items.length > 4 ? "true" : "false", "data-density": presentation.density, "data-distribution": presentation.distribution, "data-keyboard-behavior": presentation.keyboardBehavior, "data-labels": presentation.labels, "data-presentation": presentation.presentation, dir: presentation.direction, style: {
74
+ return (_jsx("nav", { ...props, ref: ref, "aria-label": resolved.accessibilityLabel, className: classNames("hjm-bottom-navigation", className), "data-expanded-labels": (theme?.environment.textScale ?? 1) >= 1.5 || resolved.items.length > 4 ? "true" : "false", "data-density": presentation.density, "data-distribution": presentation.distribution, "data-keyboard-behavior": presentation.keyboardBehavior, "data-labels": presentation.labels, "data-selection": presentation.selection, "data-presentation": presentation.presentation, dir: presentation.direction, style: {
75
75
  "--hjm-bottom-navigation-center-gap": `${centerGap}px`,
76
76
  "--hjm-bottom-navigation-columns": resolved.items.length,
77
77
  "--hjm-bottom-navigation-half-columns": resolved.items.length / 2,
@@ -1 +1 @@
1
- {"version":3,"file":"bottom-navigation.js","sourceRoot":"","sources":["../src/bottom-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n resolveBottomNavigationActivation,\n resolveBottomNavigationConfiguration,\n resolveBottomNavigationDescriptor,\n type BottomNavigationActivation,\n type BottomNavigationConfiguration,\n type BottomNavigationDescriptor,\n type ResolvedBottomNavigationItemDescriptor,\n} from \"@hjmds/design-contracts/components/bottom-navigation\";\nimport {\n bottomNavigationRecipe,\n iconRecipe,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useEffect,\n useState,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type ForwardedRef,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\n\nconst virtualKeyboardMinimumOcclusion = 120;\n\nexport type BottomNavigationIconRenderProps<\n Key extends string = string,\n IconName extends string = string,\n> = Readonly<{\n item: ResolvedBottomNavigationItemDescriptor<Key, IconName>;\n name: IconName;\n selected: boolean;\n color: \"currentColor\";\n size: number;\n strokeWidth: number;\n scale: number;\n}>;\n\nexport type BottomNavigationLinkRenderProps = AnchorHTMLAttributes<HTMLAnchorElement> &\n Readonly<{\n href: string;\n children: ReactNode;\n \"data-state\": \"idle\" | \"selected\";\n }>;\n\nexport type BottomNavigationProps<\n Key extends string = string,\n IconName extends string = string,\n> = Omit<\n HTMLAttributes<HTMLElement>,\n \"aria-label\" | \"aria-labelledby\" | \"children\" | \"dir\" | \"onChange\" | \"role\"\n> &\n Readonly<{\n descriptor: BottomNavigationDescriptor<Key, IconName>;\n configuration?: BottomNavigationConfiguration;\n getHref: (item: ResolvedBottomNavigationItemDescriptor<Key, IconName>) => string;\n renderIcon: (props: BottomNavigationIconRenderProps<Key, IconName>) => ReactNode;\n /** Framework navigation adapter, for example Next.js Link. */\n renderLink?: (props: BottomNavigationLinkRenderProps) => ReactElement;\n primaryAction?: ReactNode;\n onActivate?: (activation: BottomNavigationActivation<Key>) => void;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport function isUnmodifiedPrimaryBottomNavigationClick(\n event: Pick<\n MouseEvent<HTMLAnchorElement>,\n \"altKey\" | \"button\" | \"ctrlKey\" | \"defaultPrevented\" | \"metaKey\" | \"shiftKey\"\n >,\n): boolean {\n return (\n !event.defaultPrevented &&\n event.button === 0 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.shiftKey &&\n !event.altKey\n );\n}\n\nexport function shouldHideBottomNavigationForKeyboard(input: Readonly<{\n behavior: \"hide\" | \"remain\";\n layoutViewportHeight: number;\n visualViewportHeight: number;\n visualViewportOffsetTop?: number;\n visualViewportScale?: number;\n}>): boolean {\n if (input.behavior !== \"hide\") return false;\n if ((input.visualViewportScale ?? 1) !== 1) return false;\n const visibleBottom =\n input.visualViewportHeight + (input.visualViewportOffsetTop ?? 0);\n return layoutViewportHeightIsValid(input.layoutViewportHeight) &&\n input.layoutViewportHeight - visibleBottom >= virtualKeyboardMinimumOcclusion;\n}\n\nfunction layoutViewportHeightIsValid(value: number): boolean {\n return Number.isFinite(value) && value >= 0;\n}\n\nexport function getBottomNavigationGridColumn(\n index: number,\n itemCount: number,\n distribution: \"equal\" | \"center-gap\",\n): number | undefined {\n if (distribution !== \"center-gap\") return undefined;\n const middle = itemCount / 2;\n return index < middle ? index + 1 : index + 2;\n}\n\nfunction useKeyboardHidden(behavior: \"hide\" | \"remain\"): boolean {\n const [hidden, setHidden] = useState(false);\n useEffect(() => {\n const viewport = window.visualViewport;\n if (!viewport) return;\n const update = () => {\n setHidden(\n shouldHideBottomNavigationForKeyboard({\n behavior,\n layoutViewportHeight: window.innerHeight,\n visualViewportHeight: viewport.height,\n visualViewportOffsetTop: viewport.offsetTop,\n visualViewportScale: viewport.scale,\n }),\n );\n };\n update();\n viewport.addEventListener(\"resize\", update);\n viewport.addEventListener(\"scroll\", update);\n return () => {\n viewport.removeEventListener(\"resize\", update);\n viewport.removeEventListener(\"scroll\", update);\n };\n }, [behavior]);\n return hidden;\n}\n\nfunction BottomNavigationInner<\n Key extends string = string,\n IconName extends string = string,\n>(\n {\n descriptor,\n configuration = {},\n getHref,\n renderIcon,\n renderLink,\n primaryAction,\n onActivate,\n className,\n style,\n layoutStyle,\n ...props\n }: BottomNavigationProps<Key, IconName>,\n ref: ForwardedRef<HTMLElement>,\n) {\n const resolved = resolveBottomNavigationDescriptor(descriptor);\n const theme = useOptionalHjmTheme();\n const direction = configuration.direction ?? theme?.environment.direction;\n const presentation = resolveBottomNavigationConfiguration(\n {\n ...configuration,\n ...(direction === undefined ? {} : { direction }),\n },\n resolved.items.length,\n );\n const hidden = useKeyboardHidden(presentation.keyboardBehavior);\n const density = bottomNavigationRecipe.density[presentation.density];\n const presentationRecipe =\n bottomNavigationRecipe.presentations[presentation.presentation];\n const centerGap =\n bottomNavigationRecipe.distributions[presentation.distribution].centerGap;\n const iconSize = iconRecipe.sizes[density.icon];\n\n if (hidden) return null;\n\n return (\n <nav\n {...props}\n ref={ref}\n aria-label={resolved.accessibilityLabel}\n className={classNames(\"hjm-bottom-navigation\", className)}\n data-expanded-labels={(theme?.environment.textScale ?? 1) >= 1.5 || resolved.items.length > 4 ? \"true\" : \"false\"}\n data-density={presentation.density}\n data-distribution={presentation.distribution}\n data-keyboard-behavior={presentation.keyboardBehavior}\n data-labels={presentation.labels}\n data-presentation={presentation.presentation}\n dir={presentation.direction}\n style={{\n \"--hjm-bottom-navigation-center-gap\": `${centerGap}px`,\n \"--hjm-bottom-navigation-columns\": resolved.items.length,\n \"--hjm-bottom-navigation-half-columns\": resolved.items.length / 2,\n \"--hjm-bottom-navigation-item-gap\": `${density.gap}px`,\n \"--hjm-bottom-navigation-item-min-height\": `${density.itemMinHeight}px`,\n \"--hjm-bottom-navigation-item-min-width\": `${density.itemMinWidth}px`,\n \"--hjm-bottom-navigation-item-padding\": `${density.padding}px`,\n \"--hjm-bottom-navigation-max-width\": presentationRecipe.maxWidth\n ? `${presentationRecipe.maxWidth}px`\n : \"none\",\n \"--hjm-bottom-navigation-outer-inline\": `${presentationRecipe.outerPaddingHorizontal}px`,\n \"--hjm-bottom-navigation-outer-top\": `${presentationRecipe.outerPaddingTop}px`,\n ...style,\n ...layoutStyle,\n } as CSSProperties}\n >\n <div className=\"hjm-bottom-navigation__surface\">\n <ul className=\"hjm-bottom-navigation__list\">\n {resolved.items.map((item, index) => {\n const selected = item.id === resolved.selectedKey;\n const content = (\n <>\n <span\n aria-hidden=\"true\"\n className=\"hjm-bottom-navigation__indicator\"\n data-state={selected ? \"selected\" : \"idle\"}\n >\n {renderIcon({\n item,\n name: item.icon.name,\n selected,\n color: \"currentColor\",\n size: iconSize,\n strokeWidth: selected\n ? bottomNavigationRecipe.icon.selectedEmphasis.strokeWidth.selected\n : bottomNavigationRecipe.icon.selectedEmphasis.strokeWidth.idle,\n scale: selected\n ? bottomNavigationRecipe.icon.selectedEmphasis.scale.selected\n : bottomNavigationRecipe.icon.selectedEmphasis.scale.idle,\n })}\n {item.badge ? (\n <span aria-hidden=\"true\" className=\"hjm-bottom-navigation__badge\">\n {item.badge.visibleLabel}\n </span>\n ) : null}\n </span>\n {/* Hidden labels are not rendered: the item link already carries\n resolvedAccessibilityLabel, so a visually-hidden copy would only duplicate it. */}\n {presentation.labels === \"visible\" ? (\n <span className=\"hjm-bottom-navigation__label\">{item.label}</span>\n ) : null}\n </>\n );\n const itemStyle = {\n gridColumn: getBottomNavigationGridColumn(\n index,\n resolved.items.length,\n presentation.distribution,\n ),\n };\n if (item.disabled) {\n return (\n <li key={item.id} style={itemStyle} data-selected=\"false\">\n <span\n aria-disabled=\"true\"\n aria-label={item.resolvedAccessibilityLabel}\n className=\"hjm-bottom-navigation__item\"\n data-state=\"disabled\"\n role=\"link\"\n >\n {content}\n </span>\n </li>\n );\n }\n const href = getHref(item);\n if (!href.trim()) {\n throw new TypeError(`BottomNavigation href must not be empty: ${item.id}`);\n }\n const linkProps: BottomNavigationLinkRenderProps = {\n \"aria-current\": selected ? \"page\" : undefined,\n \"aria-label\": item.resolvedAccessibilityLabel,\n className: \"hjm-bottom-navigation__item\",\n \"data-state\": selected ? \"selected\" : \"idle\",\n href,\n onClick: (event) => {\n if (!isUnmodifiedPrimaryBottomNavigationClick(event)) return;\n const activation = resolveBottomNavigationActivation(descriptor, item.id);\n if (activation) onActivate?.(activation);\n },\n children: content,\n };\n return (\n <li key={item.id} style={itemStyle} data-selected={selected}>\n {renderLink ? renderLink(linkProps) : <a {...linkProps} />}\n </li>\n );\n })}\n </ul>\n {primaryAction ? (\n <div className=\"hjm-bottom-navigation__primary-action\">{primaryAction}</div>\n ) : null}\n </div>\n </nav>\n );\n}\n\nexport const BottomNavigation = forwardRef(BottomNavigationInner) as <\n Key extends string = string,\n IconName extends string = string,\n>(\n props: BottomNavigationProps<Key, IconName> & RefAttributes<HTMLElement>,\n) => ReactElement | null;\n"]}
1
+ {"version":3,"file":"bottom-navigation.js","sourceRoot":"","sources":["../src/bottom-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n resolveBottomNavigationActivation,\n resolveBottomNavigationConfiguration,\n resolveBottomNavigationDescriptor,\n type BottomNavigationActivation,\n type BottomNavigationConfiguration,\n type BottomNavigationDescriptor,\n type ResolvedBottomNavigationItemDescriptor,\n} from \"@hjmds/design-contracts/components/bottom-navigation\";\nimport {\n bottomNavigationRecipe,\n iconRecipe,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useEffect,\n useState,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type ForwardedRef,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\n\nconst virtualKeyboardMinimumOcclusion = 120;\n\nexport type BottomNavigationIconRenderProps<\n Key extends string = string,\n IconName extends string = string,\n> = Readonly<{\n item: ResolvedBottomNavigationItemDescriptor<Key, IconName>;\n name: IconName;\n selected: boolean;\n color: \"currentColor\";\n size: number;\n strokeWidth: number;\n scale: number;\n}>;\n\nexport type BottomNavigationLinkRenderProps = AnchorHTMLAttributes<HTMLAnchorElement> &\n Readonly<{\n href: string;\n children: ReactNode;\n \"data-state\": \"idle\" | \"selected\";\n }>;\n\nexport type BottomNavigationProps<\n Key extends string = string,\n IconName extends string = string,\n> = Omit<\n HTMLAttributes<HTMLElement>,\n \"aria-label\" | \"aria-labelledby\" | \"children\" | \"dir\" | \"onChange\" | \"role\"\n> &\n Readonly<{\n descriptor: BottomNavigationDescriptor<Key, IconName>;\n configuration?: BottomNavigationConfiguration;\n getHref: (item: ResolvedBottomNavigationItemDescriptor<Key, IconName>) => string;\n renderIcon: (props: BottomNavigationIconRenderProps<Key, IconName>) => ReactNode;\n /** Framework navigation adapter, for example Next.js Link. */\n renderLink?: (props: BottomNavigationLinkRenderProps) => ReactElement;\n primaryAction?: ReactNode;\n onActivate?: (activation: BottomNavigationActivation<Key>) => void;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport function isUnmodifiedPrimaryBottomNavigationClick(\n event: Pick<\n MouseEvent<HTMLAnchorElement>,\n \"altKey\" | \"button\" | \"ctrlKey\" | \"defaultPrevented\" | \"metaKey\" | \"shiftKey\"\n >,\n): boolean {\n return (\n !event.defaultPrevented &&\n event.button === 0 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.shiftKey &&\n !event.altKey\n );\n}\n\nexport function shouldHideBottomNavigationForKeyboard(input: Readonly<{\n behavior: \"hide\" | \"remain\";\n layoutViewportHeight: number;\n visualViewportHeight: number;\n visualViewportOffsetTop?: number;\n visualViewportScale?: number;\n}>): boolean {\n if (input.behavior !== \"hide\") return false;\n if ((input.visualViewportScale ?? 1) !== 1) return false;\n const visibleBottom =\n input.visualViewportHeight + (input.visualViewportOffsetTop ?? 0);\n return layoutViewportHeightIsValid(input.layoutViewportHeight) &&\n input.layoutViewportHeight - visibleBottom >= virtualKeyboardMinimumOcclusion;\n}\n\nfunction layoutViewportHeightIsValid(value: number): boolean {\n return Number.isFinite(value) && value >= 0;\n}\n\nexport function getBottomNavigationGridColumn(\n index: number,\n itemCount: number,\n distribution: \"equal\" | \"center-gap\",\n): number | undefined {\n if (distribution !== \"center-gap\") return undefined;\n const middle = itemCount / 2;\n return index < middle ? index + 1 : index + 2;\n}\n\nfunction useKeyboardHidden(behavior: \"hide\" | \"remain\"): boolean {\n const [hidden, setHidden] = useState(false);\n useEffect(() => {\n const viewport = window.visualViewport;\n if (!viewport) return;\n const update = () => {\n setHidden(\n shouldHideBottomNavigationForKeyboard({\n behavior,\n layoutViewportHeight: window.innerHeight,\n visualViewportHeight: viewport.height,\n visualViewportOffsetTop: viewport.offsetTop,\n visualViewportScale: viewport.scale,\n }),\n );\n };\n update();\n viewport.addEventListener(\"resize\", update);\n viewport.addEventListener(\"scroll\", update);\n return () => {\n viewport.removeEventListener(\"resize\", update);\n viewport.removeEventListener(\"scroll\", update);\n };\n }, [behavior]);\n return hidden;\n}\n\nfunction BottomNavigationInner<\n Key extends string = string,\n IconName extends string = string,\n>(\n {\n descriptor,\n configuration = {},\n getHref,\n renderIcon,\n renderLink,\n primaryAction,\n onActivate,\n className,\n style,\n layoutStyle,\n ...props\n }: BottomNavigationProps<Key, IconName>,\n ref: ForwardedRef<HTMLElement>,\n) {\n const resolved = resolveBottomNavigationDescriptor(descriptor);\n const theme = useOptionalHjmTheme();\n const direction = configuration.direction ?? theme?.environment.direction;\n const presentation = resolveBottomNavigationConfiguration(\n {\n ...configuration,\n ...(direction === undefined ? {} : { direction }),\n },\n resolved.items.length,\n );\n const hidden = useKeyboardHidden(presentation.keyboardBehavior);\n const density = bottomNavigationRecipe.density[presentation.density];\n const presentationRecipe =\n bottomNavigationRecipe.presentations[presentation.presentation];\n const centerGap =\n bottomNavigationRecipe.distributions[presentation.distribution].centerGap;\n const iconSize = iconRecipe.sizes[density.icon];\n\n if (hidden) return null;\n\n return (\n <nav\n {...props}\n ref={ref}\n aria-label={resolved.accessibilityLabel}\n className={classNames(\"hjm-bottom-navigation\", className)}\n data-expanded-labels={(theme?.environment.textScale ?? 1) >= 1.5 || resolved.items.length > 4 ? \"true\" : \"false\"}\n data-density={presentation.density}\n data-distribution={presentation.distribution}\n data-keyboard-behavior={presentation.keyboardBehavior}\n data-labels={presentation.labels}\n data-selection={presentation.selection}\n data-presentation={presentation.presentation}\n dir={presentation.direction}\n style={{\n \"--hjm-bottom-navigation-center-gap\": `${centerGap}px`,\n \"--hjm-bottom-navigation-columns\": resolved.items.length,\n \"--hjm-bottom-navigation-half-columns\": resolved.items.length / 2,\n \"--hjm-bottom-navigation-item-gap\": `${density.gap}px`,\n \"--hjm-bottom-navigation-item-min-height\": `${density.itemMinHeight}px`,\n \"--hjm-bottom-navigation-item-min-width\": `${density.itemMinWidth}px`,\n \"--hjm-bottom-navigation-item-padding\": `${density.padding}px`,\n \"--hjm-bottom-navigation-max-width\": presentationRecipe.maxWidth\n ? `${presentationRecipe.maxWidth}px`\n : \"none\",\n \"--hjm-bottom-navigation-outer-inline\": `${presentationRecipe.outerPaddingHorizontal}px`,\n \"--hjm-bottom-navigation-outer-top\": `${presentationRecipe.outerPaddingTop}px`,\n ...style,\n ...layoutStyle,\n } as CSSProperties}\n >\n <div className=\"hjm-bottom-navigation__surface\">\n <ul className=\"hjm-bottom-navigation__list\">\n {resolved.items.map((item, index) => {\n const selected = item.id === resolved.selectedKey;\n const content = (\n <>\n <span\n aria-hidden=\"true\"\n className=\"hjm-bottom-navigation__indicator\"\n data-state={selected ? \"selected\" : \"idle\"}\n >\n {renderIcon({\n item,\n name: item.icon.name,\n selected,\n color: \"currentColor\",\n size: iconSize,\n strokeWidth: selected\n ? bottomNavigationRecipe.icon.selectedEmphasis.strokeWidth.selected\n : bottomNavigationRecipe.icon.selectedEmphasis.strokeWidth.idle,\n scale: selected\n ? bottomNavigationRecipe.icon.selectedEmphasis.scale.selected\n : bottomNavigationRecipe.icon.selectedEmphasis.scale.idle,\n })}\n {item.badge ? (\n <span aria-hidden=\"true\" className=\"hjm-bottom-navigation__badge\">\n {item.badge.visibleLabel}\n </span>\n ) : null}\n </span>\n {/* Hidden labels are not rendered: the item link already carries\n resolvedAccessibilityLabel, so a visually-hidden copy would only duplicate it. */}\n {presentation.labels === \"visible\" ? (\n <span className=\"hjm-bottom-navigation__label\">{item.label}</span>\n ) : null}\n </>\n );\n const itemStyle = {\n gridColumn: getBottomNavigationGridColumn(\n index,\n resolved.items.length,\n presentation.distribution,\n ),\n };\n if (item.disabled) {\n return (\n <li key={item.id} style={itemStyle} data-selected=\"false\">\n <span\n aria-disabled=\"true\"\n aria-label={item.resolvedAccessibilityLabel}\n className=\"hjm-bottom-navigation__item\"\n data-state=\"disabled\"\n role=\"link\"\n >\n {content}\n </span>\n </li>\n );\n }\n const href = getHref(item);\n if (!href.trim()) {\n throw new TypeError(`BottomNavigation href must not be empty: ${item.id}`);\n }\n const linkProps: BottomNavigationLinkRenderProps = {\n \"aria-current\": selected ? \"page\" : undefined,\n \"aria-label\": item.resolvedAccessibilityLabel,\n className: \"hjm-bottom-navigation__item\",\n \"data-state\": selected ? \"selected\" : \"idle\",\n href,\n onClick: (event) => {\n if (!isUnmodifiedPrimaryBottomNavigationClick(event)) return;\n const activation = resolveBottomNavigationActivation(descriptor, item.id);\n if (activation) onActivate?.(activation);\n },\n children: content,\n };\n return (\n <li key={item.id} style={itemStyle} data-selected={selected}>\n {renderLink ? renderLink(linkProps) : <a {...linkProps} />}\n </li>\n );\n })}\n </ul>\n {primaryAction ? (\n <div className=\"hjm-bottom-navigation__primary-action\">{primaryAction}</div>\n ) : null}\n </div>\n </nav>\n );\n}\n\nexport const BottomNavigation = forwardRef(BottomNavigationInner) as <\n Key extends string = string,\n IconName extends string = string,\n>(\n props: BottomNavigationProps<Key, IconName> & RefAttributes<HTMLElement>,\n) => ReactElement | null;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../src/calendar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+E,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC9H,OAAO,EAGL,KAAK,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,wBAAwB,EACzE,KAAK,6BAA6B,EAAE,KAAK,wBAAwB,EAClE,MAAM,6CAA6C,CAAC;AAGrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC7E,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC;AACzE,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,wBAAwB,CAAC;IAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAA;CAAE,CAAC,CAAC;AAC1H,MAAM,MAAM,aAAa,CAAC,OAAO,GAAG,OAAO,IAAI,QAAQ,CAAC;IACtD,UAAU,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,qBAAqB,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC9D,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,iGAAiG;IACjG,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,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1B,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,wFAAwF;AACxF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAC7F,oBAAoB,EAAE,iBAAiB,EAAE,IAAe,EAAE,SAAiB,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,+BA6EnI"}
1
+ {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../src/calendar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+E,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC9H,OAAO,EAGL,KAAK,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,wBAAwB,EACzE,KAAK,6BAA6B,EAAE,KAAK,wBAAwB,EAClE,MAAM,6CAA6C,CAAC;AAGrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC7E,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC;AACzE,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,wBAAwB,CAAC;IAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAA;CAAE,CAAC,CAAC;AAC1H,MAAM,MAAM,aAAa,CAAC,OAAO,GAAG,OAAO,IAAI,QAAQ,CAAC;IACtD,UAAU,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,qBAAqB,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC9D,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,iGAAiG;IACjG,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,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1B,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,wFAAwF;AACxF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAC7F,oBAAoB,EAAE,iBAAiB,EAAE,IAAe,EAAE,SAAiB,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,+BAmFnI"}
package/dist/calendar.js CHANGED
@@ -51,8 +51,16 @@ export function Calendar({ descriptor, composeAccessibleName, previousMonth, nex
51
51
  "--hjm-calendar-disabled-opacity": recipe.day.disabledOpacity,
52
52
  "--hjm-calendar-outside-opacity": recipe.day.outsideFocusedMonthOpacity }, children: [_jsxs("div", { className: "hjm-calendar__header", children: [previousMonth ? _jsx("button", { type: "button", "aria-label": previousMonth.label, disabled: !descriptor.onFocusedMonthChange, onClick: () => descriptor.onFocusedMonthChange?.(previousMonth.month, "previous"), children: _jsx("span", { "aria-hidden": "true", children: theme?.environment.direction === "rtl" ? "›" : "‹" }) }) : _jsx("span", {}), _jsx("strong", { id: titleId, "aria-live": "polite", "aria-atomic": "true", children: descriptor.monthLabel }), nextMonth ? _jsx("button", { type: "button", "aria-label": nextMonth.label, disabled: !descriptor.onFocusedMonthChange, onClick: () => descriptor.onFocusedMonthChange?.(nextMonth.month, "next"), children: _jsx("span", { "aria-hidden": "true", children: theme?.environment.direction === "rtl" ? "‹" : "›" }) }) : _jsx("span", {})] }), _jsx("div", { className: "hjm-calendar__viewport", children: _jsxs("div", { role: "grid", "aria-labelledby": titleId, className: "hjm-calendar__grid", children: [_jsx("div", { role: "row", className: "hjm-calendar__week", children: descriptor.grid.weekdayLabels.map((label, index) => _jsx("span", { role: "columnheader", className: "hjm-calendar__weekday", children: label }, index)) }), Array.from({ length: cells.length / 7 }, (_, row) => _jsx("div", { role: "row", className: "hjm-calendar__week", children: cells.slice(row * 7, row * 7 + 7).map((cell, column) => "filler" in cell
53
53
  ? _jsx("span", { role: "gridcell", "aria-hidden": "true" }, `filler-${column}`)
54
- : _jsxs("button", { type: "button", role: "gridcell", className: "hjm-calendar__day", "data-date": cell.date, "data-focus-date": cell.date === active || undefined, "data-today": cell.isToday || undefined, "data-selected": cell.isSelected || undefined, "data-disabled": !cell.selectable || undefined, "data-outside": cell.outsideFocusedMonth || undefined, "aria-label": cell.accessibleName, "aria-selected": cell.isSelected, "aria-disabled": !cell.selectable || undefined, "aria-current": cell.isToday ? "date" : undefined, tabIndex: cell.date === active ? 0 : -1, onFocus: () => setFocused(cell.date), onClick: () => { if (cell.selectable)
55
- setSelected(cell.date); }, onKeyDown: (event) => {
54
+ : _jsxs("button", { type: "button", role: "gridcell", className: "hjm-calendar__day", "data-date": cell.date, "data-focus-date": cell.date === active || undefined, "data-today": cell.isToday || undefined, "data-selected": cell.isSelected || undefined, "data-disabled": !cell.selectable || undefined, "data-outside": cell.outsideFocusedMonth || undefined, "aria-label": cell.accessibleName, "aria-selected": cell.isSelected, "aria-disabled": !cell.selectable || undefined, "aria-current": cell.isToday ? "date" : undefined, tabIndex: cell.date === active ? 0 : -1, onFocus: () => setFocused(cell.date), onClick: () => {
55
+ if (!cell.selectable)
56
+ return;
57
+ // Range completion and DatePicker confirmation still need activation
58
+ // when the date already equals Calendar's single selected value.
59
+ if (cell.date === selected)
60
+ descriptor.onSelectionChange?.(cell.date);
61
+ else
62
+ setSelected(cell.date);
63
+ }, onKeyDown: (event) => {
56
64
  if (event.altKey || event.ctrlKey || event.metaKey)
57
65
  return;
58
66
  const intent = getCalendarNavigationIntent(event.key, theme?.environment.direction ?? "ltr");