@hjmds/react 1.10.0 → 1.12.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 (156) hide show
  1. package/README.md +14 -0
  2. package/THIRD_PARTY_NOTICES.md +78 -0
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +1 -1
  5. package/dist/actions.js.map +1 -1
  6. package/dist/activity-heatmap.d.ts +10 -0
  7. package/dist/activity-heatmap.d.ts.map +1 -0
  8. package/dist/activity-heatmap.js +6 -0
  9. package/dist/activity-heatmap.js.map +1 -0
  10. package/dist/advanced-display.d.ts +3 -0
  11. package/dist/advanced-display.d.ts.map +1 -1
  12. package/dist/advanced-display.js +9 -7
  13. package/dist/advanced-display.js.map +1 -1
  14. package/dist/advanced-forms.js +1 -1
  15. package/dist/advanced-forms.js.map +1 -1
  16. package/dist/auth-screen.d.ts +8 -0
  17. package/dist/auth-screen.d.ts.map +1 -1
  18. package/dist/auth-screen.js +5 -2
  19. package/dist/auth-screen.js.map +1 -1
  20. package/dist/avatar-blobatar-motion.d.ts +6 -0
  21. package/dist/avatar-blobatar-motion.d.ts.map +1 -0
  22. package/dist/avatar-blobatar-motion.js +22 -0
  23. package/dist/avatar-blobatar-motion.js.map +1 -0
  24. package/dist/avatar-blobatar.d.ts +6 -0
  25. package/dist/avatar-blobatar.d.ts.map +1 -0
  26. package/dist/avatar-blobatar.js +10 -0
  27. package/dist/avatar-blobatar.js.map +1 -0
  28. package/dist/bottom-navigation.d.ts.map +1 -1
  29. package/dist/bottom-navigation.js +3 -3
  30. package/dist/bottom-navigation.js.map +1 -1
  31. package/dist/carousel-motion.d.ts +4 -1
  32. package/dist/carousel-motion.d.ts.map +1 -1
  33. package/dist/carousel-motion.js +12 -3
  34. package/dist/carousel-motion.js.map +1 -1
  35. package/dist/code-block.d.ts +8 -0
  36. package/dist/code-block.d.ts.map +1 -0
  37. package/dist/code-block.js +6 -0
  38. package/dist/code-block.js.map +1 -0
  39. package/dist/content-transition.d.ts +5 -2
  40. package/dist/content-transition.d.ts.map +1 -1
  41. package/dist/content-transition.js +6 -4
  42. package/dist/content-transition.js.map +1 -1
  43. package/dist/context-menu.d.ts.map +1 -1
  44. package/dist/context-menu.js +10 -11
  45. package/dist/context-menu.js.map +1 -1
  46. package/dist/data-table.d.ts.map +1 -1
  47. package/dist/data-table.js +2 -1
  48. package/dist/data-table.js.map +1 -1
  49. package/dist/duration-field.d.ts +11 -0
  50. package/dist/duration-field.d.ts.map +1 -0
  51. package/dist/duration-field.js +9 -0
  52. package/dist/duration-field.js.map +1 -0
  53. package/dist/effect-surface.d.ts +10 -0
  54. package/dist/effect-surface.d.ts.map +1 -0
  55. package/dist/effect-surface.js +57 -0
  56. package/dist/effect-surface.js.map +1 -0
  57. package/dist/evidence.d.ts +1 -1
  58. package/dist/evidence.js +1 -1
  59. package/dist/evidence.js.map +1 -1
  60. package/dist/feedback.js +1 -1
  61. package/dist/feedback.js.map +1 -1
  62. package/dist/folder-preview.d.ts +12 -0
  63. package/dist/folder-preview.d.ts.map +1 -0
  64. package/dist/folder-preview.js +7 -0
  65. package/dist/folder-preview.js.map +1 -0
  66. package/dist/forms.d.ts +3 -1
  67. package/dist/forms.d.ts.map +1 -1
  68. package/dist/forms.js +5 -3
  69. package/dist/forms.js.map +1 -1
  70. package/dist/gravity-letters.d.ts +8 -0
  71. package/dist/gravity-letters.d.ts.map +1 -0
  72. package/dist/gravity-letters.js +24 -0
  73. package/dist/gravity-letters.js.map +1 -0
  74. package/dist/grid-reveal.d.ts +9 -0
  75. package/dist/grid-reveal.d.ts.map +1 -0
  76. package/dist/grid-reveal.js +21 -0
  77. package/dist/grid-reveal.js.map +1 -0
  78. package/dist/icon-lucide.d.ts +11 -0
  79. package/dist/icon-lucide.d.ts.map +1 -0
  80. package/dist/icon-lucide.js +11 -0
  81. package/dist/icon-lucide.js.map +1 -0
  82. package/dist/inline-confirm.d.ts +14 -0
  83. package/dist/inline-confirm.d.ts.map +1 -0
  84. package/dist/inline-confirm.js +37 -0
  85. package/dist/inline-confirm.js.map +1 -0
  86. package/dist/menu-morph.d.ts.map +1 -1
  87. package/dist/menu-morph.js +9 -6
  88. package/dist/menu-morph.js.map +1 -1
  89. package/dist/menu-typeahead.d.ts +13 -0
  90. package/dist/menu-typeahead.d.ts.map +1 -0
  91. package/dist/menu-typeahead.js +17 -0
  92. package/dist/menu-typeahead.js.map +1 -0
  93. package/dist/navigation-bar.d.ts +10 -0
  94. package/dist/navigation-bar.d.ts.map +1 -0
  95. package/dist/navigation-bar.js +10 -0
  96. package/dist/navigation-bar.js.map +1 -0
  97. package/dist/navigation.d.ts +3 -3
  98. package/dist/navigation.d.ts.map +1 -1
  99. package/dist/navigation.js +63 -22
  100. package/dist/navigation.js.map +1 -1
  101. package/dist/notification-bell.d.ts +11 -0
  102. package/dist/notification-bell.d.ts.map +1 -0
  103. package/dist/notification-bell.js +27 -0
  104. package/dist/notification-bell.js.map +1 -0
  105. package/dist/overlays.d.ts +0 -2
  106. package/dist/overlays.d.ts.map +1 -1
  107. package/dist/overlays.js +5 -18
  108. package/dist/overlays.js.map +1 -1
  109. package/dist/provider-button.d.ts.map +1 -1
  110. package/dist/provider-button.js +2 -2
  111. package/dist/provider-button.js.map +1 -1
  112. package/dist/reaction-picker.d.ts +11 -0
  113. package/dist/reaction-picker.d.ts.map +1 -0
  114. package/dist/reaction-picker.js +9 -0
  115. package/dist/reaction-picker.js.map +1 -0
  116. package/dist/scroll-progress.d.ts +10 -0
  117. package/dist/scroll-progress.d.ts.map +1 -0
  118. package/dist/scroll-progress.js +34 -0
  119. package/dist/scroll-progress.js.map +1 -0
  120. package/dist/select.d.ts +0 -1
  121. package/dist/select.d.ts.map +1 -1
  122. package/dist/select.js +2 -4
  123. package/dist/select.js.map +1 -1
  124. package/dist/sidebar.d.ts +3 -0
  125. package/dist/sidebar.d.ts.map +1 -1
  126. package/dist/sidebar.js +23 -4
  127. package/dist/sidebar.js.map +1 -1
  128. package/dist/step-player.d.ts +24 -0
  129. package/dist/step-player.d.ts.map +1 -0
  130. package/dist/step-player.js +16 -0
  131. package/dist/step-player.js.map +1 -0
  132. package/dist/styles.css +94 -1
  133. package/dist/styles.layered.css +94 -1
  134. package/dist/supplemental-display.d.ts +10 -2
  135. package/dist/supplemental-display.d.ts.map +1 -1
  136. package/dist/supplemental-display.js +2 -2
  137. package/dist/supplemental-display.js.map +1 -1
  138. package/dist/supplemental-navigation.js +1 -1
  139. package/dist/supplemental-navigation.js.map +1 -1
  140. package/dist/table-sort-button.d.ts +15 -0
  141. package/dist/table-sort-button.d.ts.map +1 -0
  142. package/dist/table-sort-button.js +7 -0
  143. package/dist/table-sort-button.js.map +1 -0
  144. package/dist/task-list.d.ts +16 -0
  145. package/dist/task-list.d.ts.map +1 -0
  146. package/dist/task-list.js +17 -0
  147. package/dist/task-list.js.map +1 -0
  148. package/dist/thinking-orb.d.ts +1 -1
  149. package/dist/thinking-orb.d.ts.map +1 -1
  150. package/dist/thinking-orb.js +4 -4
  151. package/dist/thinking-orb.js.map +1 -1
  152. package/dist/voice-note.d.ts +24 -0
  153. package/dist/voice-note.d.ts.map +1 -0
  154. package/dist/voice-note.js +13 -0
  155. package/dist/voice-note.js.map +1 -0
  156. package/package.json +110 -5
@@ -1 +1 @@
1
- {"version":3,"file":"advanced-forms.js","sourceRoot":"","sources":["../src/advanced-forms.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\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 { 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\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 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 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\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 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 matchAnchorWidth: true,\n zIndex: 800,\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 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\">{loadingMessage}</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 }>;\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 ...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 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 {\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 { 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\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 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 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\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 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 matchAnchorWidth: true,\n zIndex: 800,\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 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 }>;\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 ...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 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"]}
@@ -7,6 +7,10 @@ export type AuthScreenLayoutProps = Omit<HTMLAttributes<HTMLElement>, "children"
7
7
  hero: ReactNode;
8
8
  /** The primary action block — provider buttons, or a product's own sign-in bundle. */
9
9
  main: ReactNode;
10
+ /** Product-localized progress label; presence replaces actions with one centred loader. */
11
+ pendingLabel?: string;
12
+ /** Let the layout own the action card; omit when the product already supplies a surface. */
13
+ mainCard?: boolean;
10
14
  /** Consent notice and policy links. Omit with `hasFooter: false`. */
11
15
  footer?: ReactNode;
12
16
  className?: string;
@@ -26,6 +30,10 @@ export declare const AuthScreenLayout: import("react").ForwardRefExoticComponent
26
30
  hero: ReactNode;
27
31
  /** The primary action block — provider buttons, or a product's own sign-in bundle. */
28
32
  main: ReactNode;
33
+ /** Product-localized progress label; presence replaces actions with one centred loader. */
34
+ pendingLabel?: string;
35
+ /** Let the layout own the action card; omit when the product already supplies a surface. */
36
+ mainCard?: boolean;
29
37
  /** Consent notice and policy links. Omit with `hasFooter: false`. */
30
38
  footer?: ReactNode;
31
39
  className?: string;
@@ -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;AAGxE,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,qEAAqE;IACrE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;IAhBzB,8EAA8E;SACzE,MAAM,GAAG,SAAS;IACvB,+EAA+E;UACzE,SAAS;IACf,sFAAsF;UAChF,SAAS;IACf,qEAAqE;aAC5D,SAAS;gBACN,MAAM;gDA0CrB,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,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxE,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;CACpB,CAAC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;IApBzB,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;gDAmDrB,CAAC"}
@@ -7,12 +7,15 @@ import { classNames } from "./internal.js";
7
7
  * the bottom. The measurements come from the resolved descriptor as custom
8
8
  * properties so the stylesheet keeps one source of truth with the contract.
9
9
  */
10
- export const AuthScreenLayout = forwardRef(function AuthScreenLayout({ hero, main, footer, density, hasFooter, className, as: Element = "main", ...props }, forwardedRef) {
10
+ export const AuthScreenLayout = forwardRef(function AuthScreenLayout({ hero, main, footer, density, hasFooter, pendingLabel, mainCard = false, className, as: Element = "main", ...props }, forwardedRef) {
11
11
  const resolved = resolveAuthScreenDescriptor({
12
12
  ...(density === undefined ? {} : { density }),
13
13
  ...(hasFooter === undefined ? {} : { hasFooter }),
14
14
  });
15
15
  const showFooter = resolved.hasFooter && footer !== undefined && footer !== null;
16
+ const pending = pendingLabel !== undefined;
17
+ if (pending && !pendingLabel.trim())
18
+ throw new TypeError("AuthScreen pendingLabel must not be empty");
16
19
  return (_jsxs(Element, { ...props, ref: forwardedRef, className: classNames("hjm-auth-screen", className), "data-density": resolved.density, style: {
17
20
  ["--hjm-auth-screen-max-width"]: `${resolved.maxWidth}px`,
18
21
  ["--hjm-auth-screen-hero-gap"]: `${resolved.heroGap}px`,
@@ -21,6 +24,6 @@ export const AuthScreenLayout = forwardRef(function AuthScreenLayout({ hero, mai
21
24
  ["--hjm-auth-screen-padding-inline"]: `${resolved.paddingInline}px`,
22
25
  ["--hjm-auth-screen-padding-block"]: `${resolved.paddingBlock}px`,
23
26
  ...props.style,
24
- }, children: [_jsxs("div", { className: "hjm-auth-screen__block", children: [_jsx("div", { className: "hjm-auth-screen__hero", children: hero }), _jsx("div", { className: "hjm-auth-screen__main", children: main })] }), showFooter ? _jsx("div", { className: "hjm-auth-screen__footer", children: footer }) : null] }));
27
+ }, 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] }));
25
28
  });
26
29
  //# 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;AAgB3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CACxC,SAAS,gBAAgB,CACvB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,EACrF,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,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;SACf,aAED,eAAK,SAAS,EAAC,wBAAwB,aACrC,cAAK,SAAS,EAAC,uBAAuB,YAAE,IAAI,GAAO,EACnD,cAAK,SAAS,EAAC,uBAAuB,YAAE,IAAI,GAAO,IAC/C,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\";\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 /** Consent notice and policy links. Omit with `hasFooter: false`. */\n footer?: ReactNode;\n className?: string;\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, className, as: Element = \"main\", ...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 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 }}\n >\n <div className=\"hjm-auth-screen__block\">\n <div className=\"hjm-auth-screen__hero\">{hero}</div>\n <div className=\"hjm-auth-screen__main\">{main}</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":";AAAA,OAAO,EACL,2BAA2B,GAE5B,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,UAAU,EAAuC,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAoB3C;;;;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,GAAG,KAAK,EAAE,EACrH,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;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\";\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 }>;\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\", ...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 }}\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"]}
@@ -0,0 +1,6 @@
1
+ import { type ReactNode } from 'react';
2
+ import 'blobatar/motion.css';
3
+ import { type BlobatarMotionOptions, type AvatarFallbackContext } from '@hjmds/design-contracts/avatar-fallback';
4
+ /** Optional animated entry. Static avatar imports never load motion CSS. */
5
+ export declare function createAnimatedBlobatarFallback(options: BlobatarMotionOptions): (context: AvatarFallbackContext) => ReactNode;
6
+ //# sourceMappingURL=avatar-blobatar-motion.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { Blobatar } from '@blobatar/react';
4
+ import { idle, happy, sad, surprised, wink, sleepy, thinking } from 'blobatar/expression';
5
+ import 'blobatar/motion.css';
6
+ import { resolveBlobatarMotion } from '@hjmds/design-contracts/avatar-fallback';
7
+ import { useHjmTheme } from './provider.js';
8
+ const expressions = { idle, happy, sad, surprised, wink, sleepy, thinking };
9
+ function Artwork({ size, options }) {
10
+ const spec = resolveBlobatarMotion(options);
11
+ const { environment } = useHjmTheme();
12
+ const host = useRef(null);
13
+ const [visible, setVisible] = useState(false);
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); }; }, []);
17
+ const active = spec.active && spec.visible && visible && foreground && !environment.reducedMotion;
18
+ 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
+ }
20
+ /** Optional animated entry. Static avatar imports never load motion CSS. */
21
+ export function createAnimatedBlobatarFallback(options) { resolveBlobatarMotion(options); return ({ size }) => _jsx(Artwork, { size: size, options: options }); }
22
+ //# sourceMappingURL=avatar-blobatar-motion.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,6 @@
1
+ import { type AvatarFallbackContext, type BlobatarFallbackOptions } from "@hjmds/design-contracts/avatar-fallback";
2
+ import type { ReactNode } from "react";
3
+ export type { BlobatarFallbackOptions } from "@hjmds/design-contracts/avatar-fallback";
4
+ /** Optional, local artwork. Avatar owns naming and image-error recovery. */
5
+ export declare function createBlobatarFallback(options: BlobatarFallbackOptions): (context: AvatarFallbackContext) => ReactNode;
6
+ //# sourceMappingURL=avatar-blobatar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-blobatar.d.ts","sourceRoot":"","sources":["../src/avatar-blobatar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,qBAAqB,EAAE,KAAK,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAC5I,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,YAAY,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AACvF,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,CAAC,OAAO,EAAE,qBAAqB,KAAK,SAAS,CAKtH"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Blobatar } from "@blobatar/react";
3
+ import { happy } from "blobatar/expression";
4
+ import { resolveBlobatarFallback } from "@hjmds/design-contracts/avatar-fallback";
5
+ /** Optional, local artwork. Avatar owns naming and image-error recovery. */
6
+ export function createBlobatarFallback(options) {
7
+ const { seed, expression } = resolveBlobatarFallback(options);
8
+ return ({ size }) => _jsx(Blobatar, { name: seed, size: size, normalize: false, animate: false, ...(expression === "happy" ? { expression: happy } : {}), alt: "", "aria-hidden": "true", style: { display: "block" } });
9
+ }
10
+ //# sourceMappingURL=avatar-blobatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-blobatar.js","sourceRoot":"","sources":["../src/avatar-blobatar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAA4D,MAAM,yCAAyC,CAAC;AAG5I,4EAA4E;AAC5E,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC9D,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,KAAC,QAAQ,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,KACjF,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACzD,GAAG,EAAC,EAAE,iBAAa,MAAM,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAI,CAAC;AAC9D,CAAC","sourcesContent":["import { Blobatar } from \"@blobatar/react\";\nimport { happy } from \"blobatar/expression\";\nimport { resolveBlobatarFallback, type AvatarFallbackContext, type BlobatarFallbackOptions } from \"@hjmds/design-contracts/avatar-fallback\";\nimport type { ReactNode } from \"react\";\nexport type { BlobatarFallbackOptions } from \"@hjmds/design-contracts/avatar-fallback\";\n/** Optional, local artwork. Avatar owns naming and image-error recovery. */\nexport function createBlobatarFallback(options: BlobatarFallbackOptions): (context: AvatarFallbackContext) => ReactNode {\n const { seed, expression } = resolveBlobatarFallback(options);\n return ({ size }) => <Blobatar name={seed} size={size} normalize={false} animate={false}\n {...(expression === \"happy\" ? { expression: happy } : {})}\n alt=\"\" aria-hidden=\"true\" style={{ display: \"block\" }} />;\n}\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-density": presentation.density, "data-distribution": presentation.distribution, "data-keyboard-behavior": presentation.keyboardBehavior, "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-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,
@@ -104,7 +104,7 @@ function BottomNavigationInner({ descriptor, configuration = {}, getHref, render
104
104
  gridColumn: getBottomNavigationGridColumn(index, resolved.items.length, presentation.distribution),
105
105
  };
106
106
  if (item.disabled) {
107
- return (_jsx("li", { style: itemStyle, children: _jsx("span", { "aria-disabled": "true", "aria-label": item.resolvedAccessibilityLabel, className: "hjm-bottom-navigation__item", "data-state": "disabled", role: "link", children: content }) }, item.id));
107
+ return (_jsx("li", { style: itemStyle, "data-selected": "false", children: _jsx("span", { "aria-disabled": "true", "aria-label": item.resolvedAccessibilityLabel, className: "hjm-bottom-navigation__item", "data-state": "disabled", role: "link", children: content }) }, item.id));
108
108
  }
109
109
  const href = getHref(item);
110
110
  if (!href.trim()) {
@@ -125,7 +125,7 @@ function BottomNavigationInner({ descriptor, configuration = {}, getHref, render
125
125
  },
126
126
  children: content,
127
127
  };
128
- return (_jsx("li", { style: itemStyle, children: renderLink ? renderLink(linkProps) : _jsx("a", { ...linkProps }) }, item.id));
128
+ return (_jsx("li", { style: itemStyle, "data-selected": selected, children: renderLink ? renderLink(linkProps) : _jsx("a", { ...linkProps }) }, item.id));
129
129
  }) }), primaryAction ? (_jsx("div", { className: "hjm-bottom-navigation__primary-action", children: primaryAction })) : null] }) }));
130
130
  }
131
131
  export const BottomNavigation = forwardRef(BottomNavigationInner);
@@ -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 { 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 }>;\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 ...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-density={presentation.density}\n data-distribution={presentation.distribution}\n data-keyboard-behavior={presentation.keyboardBehavior}\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 } 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 <span className=\"hjm-bottom-navigation__label\">{item.label}</span>\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}>\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}>\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 { 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 }>;\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 ...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-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 } 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 <span className=\"hjm-bottom-navigation__label\">{item.label}</span>\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,9 +1,12 @@
1
1
  import { type ReactNode } from "react";
2
- import { type SortableItem } from "@hjmds/design-contracts/components/interaction-adapters";
2
+ import type { SortableItem } from "@hjmds/design-contracts/components/interaction-adapters";
3
+ import { type ComposeCarouselAccessibleName } from "@hjmds/design-contracts/components/carousel";
3
4
  export type CarouselMotionProps = {
4
5
  slides: readonly SortableItem[];
5
6
  currentKey: string;
6
7
  onCurrentKeyChange(key: string): void;
8
+ /** Optional localized position/name composer shared with the base Carousel. */
9
+ composeAccessibleName?: ComposeCarouselAccessibleName;
7
10
  renderSlide(item: SortableItem): ReactNode;
8
11
  label: string;
9
12
  previousLabel: string;
@@ -1 +1 @@
1
- {"version":3,"file":"carousel-motion.d.ts","sourceRoot":"","sources":["../src/carousel-motion.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpE,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,yDAAyD,CAAC;AAI9G,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3F,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;CACrG,CAAC;AACF,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,+BA+BxD"}
1
+ {"version":3,"file":"carousel-motion.d.ts","sourceRoot":"","sources":["../src/carousel-motion.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yDAAyD,CAAC;AAC5F,OAAO,EAA0D,KAAK,6BAA6B,EAAE,MAAM,6CAA6C,CAAC;AAIzJ,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3F,+EAA+E;IAC/E,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;CACrG,CAAC;AACF,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,+BAwCxD"}
@@ -1,11 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from "react";
3
3
  import useEmblaCarousel from "embla-carousel-react";
4
- import { validateCarousel } from "@hjmds/design-contracts/components/interaction-adapters";
4
+ import { resolveCarouselDescriptor, getCarouselNavigationTarget } from "@hjmds/design-contracts/components/carousel";
5
5
  import { Button } from "./actions.js";
6
6
  import { useHjmTheme } from "./provider.js";
7
7
  export function CarouselMotion(props) {
8
- const index = validateCarousel(props.slides, props.currentKey);
8
+ const descriptor = { slides: props.slides, currentKey: props.currentKey };
9
+ // Share finite keyed selection and names with Carousel; the optional peer owns
10
+ // only swipe/motion. No autoplay is implied by this controlled presentation.
11
+ const resolved = resolveCarouselDescriptor(descriptor, {
12
+ composeAccessibleName: props.composeAccessibleName ?? ((info) => info.label),
13
+ });
14
+ const index = resolved.findIndex(slide => slide.current);
15
+ if (![props.label, props.previousLabel, props.nextLabel].every(label => label.trim())) {
16
+ throw new TypeError("CarouselMotion labels must not be empty");
17
+ }
9
18
  const { environment } = useHjmTheme();
10
19
  // Embla deep-compares options and reInits on change; a live startIndex restarted the engine at the target on
11
20
  // every selection, so navigation snapped instead of animating (2026-09-30 review). Only the first index seeds it.
@@ -30,6 +39,6 @@ export function CarouselMotion(props) {
30
39
  return () => { api.off("select", select); };
31
40
  }, [api]);
32
41
  useEffect(() => { syncing.current = true; api?.scrollTo(index, environment.reducedMotion); syncing.current = false; }, [api, index, environment.reducedMotion]);
33
- return _jsxs("section", { "aria-label": props.label, "aria-roledescription": "carousel", children: [_jsx("div", { ref: viewport, style: { overflow: "hidden" }, children: _jsx("div", { style: { display: "flex", touchAction: "pan-y pinch-zoom" }, children: props.slides.map((slide, i) => _jsx("div", { role: "group", "aria-roledescription": "slide", "aria-label": slide.label, "aria-hidden": i !== index, inert: i !== index, style: { flex: "0 0 100%", minWidth: 0 }, children: props.renderSlide(slide) }, slide.id)) }) }), _jsx(Button, { tone: "ghost", disabled: index === 0, onClick: () => props.onCurrentKeyChange(props.slides[index - 1].id), children: props.previousLabel }), _jsx(Button, { tone: "ghost", disabled: index === props.slides.length - 1, onClick: () => props.onCurrentKeyChange(props.slides[index + 1].id), children: props.nextLabel })] });
42
+ return _jsxs("section", { "aria-label": props.label, "aria-roledescription": "carousel", children: [_jsx("div", { ref: viewport, style: { overflow: "hidden" }, children: _jsx("div", { style: { display: "flex", touchAction: "pan-y pinch-zoom" }, children: props.slides.map((slide, i) => _jsx("div", { role: "group", "aria-roledescription": "slide", "aria-label": resolved[i].accessibleName, "aria-hidden": resolved[i].inert, inert: resolved[i].inert, style: { flex: "0 0 100%", minWidth: 0 }, children: props.renderSlide(slide) }, slide.id)) }) }), _jsx(Button, { tone: "ghost", disabled: index === 0, onClick: () => props.onCurrentKeyChange(getCarouselNavigationTarget(descriptor, "previous")), children: props.previousLabel }), _jsx(Button, { tone: "ghost", disabled: index === props.slides.length - 1, onClick: () => props.onCurrentKeyChange(getCarouselNavigationTarget(descriptor, "next")), children: props.nextLabel })] });
34
43
  }
35
44
  //# sourceMappingURL=carousel-motion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"carousel-motion.js","sourceRoot":"","sources":["../src/carousel-motion.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { validateCarousel, type SortableItem } from \"@hjmds/design-contracts/components/interaction-adapters\";\nimport { Button } from \"./actions.js\";\nimport { useHjmTheme } from \"./provider.js\";\n\nexport type CarouselMotionProps = {\n slides: readonly SortableItem[]; currentKey: string; onCurrentKeyChange(key: string): void;\n renderSlide(item: SortableItem): ReactNode; label: string; previousLabel: string; nextLabel: string;\n};\nexport function CarouselMotion(props: CarouselMotionProps) {\n const index = validateCarousel(props.slides, props.currentKey);\n const { environment } = useHjmTheme();\n // Embla deep-compares options and reInits on change; a live startIndex restarted the engine at the target on\n // every selection, so navigation snapped instead of animating (2026-09-30 review). Only the first index seeds it.\n const [startIndex] = useState(index);\n const [viewport, api] = useEmblaCarousel({ loop: false, direction: environment.direction, startIndex,\n // HJM owns selection; upstream focus scrolling must not independently change slides.\n // Embla's default 25 is a physics duration factor, not an HJM millisecond token.\n watchFocus: false, duration: environment.reducedMotion ? 0 : 25 });\n const latest = useRef(props); latest.current = props;\n const syncing = useRef(false);\n useEffect(() => {\n if (!api) return;\n const select = () => {\n const current = latest.current;\n const item = current.slides[api.selectedScrollSnap()];\n if (!syncing.current && item && item.id !== current.currentKey) current.onCurrentKeyChange(item.id);\n };\n api.on(\"select\", select);\n return () => { api.off(\"select\", select); };\n }, [api]);\n useEffect(() => { syncing.current = true; api?.scrollTo(index, environment.reducedMotion); syncing.current = false; }, [api, index, environment.reducedMotion]);\n return <section aria-label={props.label} aria-roledescription=\"carousel\">\n <div ref={viewport} style={{ overflow: \"hidden\" }}><div style={{ display: \"flex\", touchAction: \"pan-y pinch-zoom\" }}>\n {props.slides.map((slide, i) => <div key={slide.id} role=\"group\" aria-roledescription=\"slide\" aria-label={slide.label} aria-hidden={i !== index} inert={i !== index}\n style={{ flex: \"0 0 100%\", minWidth: 0 }}>{props.renderSlide(slide)}</div>)}\n </div></div>\n <Button tone=\"ghost\" disabled={index === 0} onClick={() => props.onCurrentKeyChange(props.slides[index - 1]!.id)}>{props.previousLabel}</Button>\n <Button tone=\"ghost\" disabled={index === props.slides.length - 1} onClick={() => props.onCurrentKeyChange(props.slides[index + 1]!.id)}>{props.nextLabel}</Button>\n </section>;\n}\n"]}
1
+ {"version":3,"file":"carousel-motion.js","sourceRoot":"","sources":["../src/carousel-motion.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport type { SortableItem } from \"@hjmds/design-contracts/components/interaction-adapters\";\nimport { resolveCarouselDescriptor, getCarouselNavigationTarget, type ComposeCarouselAccessibleName } from \"@hjmds/design-contracts/components/carousel\";\nimport { Button } from \"./actions.js\";\nimport { useHjmTheme } from \"./provider.js\";\n\nexport type CarouselMotionProps = {\n slides: readonly SortableItem[]; currentKey: string; onCurrentKeyChange(key: string): void;\n /** Optional localized position/name composer shared with the base Carousel. */\n composeAccessibleName?: ComposeCarouselAccessibleName;\n renderSlide(item: SortableItem): ReactNode; label: string; previousLabel: string; nextLabel: string;\n};\nexport function CarouselMotion(props: CarouselMotionProps) {\n const descriptor = { slides: props.slides, currentKey: props.currentKey };\n // Share finite keyed selection and names with Carousel; the optional peer owns\n // only swipe/motion. No autoplay is implied by this controlled presentation.\n const resolved = resolveCarouselDescriptor(descriptor, {\n composeAccessibleName: props.composeAccessibleName ?? ((info) => info.label),\n });\n const index = resolved.findIndex(slide => slide.current);\n if (![props.label, props.previousLabel, props.nextLabel].every(label => label.trim())) {\n throw new TypeError(\"CarouselMotion labels must not be empty\");\n }\n const { environment } = useHjmTheme();\n // Embla deep-compares options and reInits on change; a live startIndex restarted the engine at the target on\n // every selection, so navigation snapped instead of animating (2026-09-30 review). Only the first index seeds it.\n const [startIndex] = useState(index);\n const [viewport, api] = useEmblaCarousel({ loop: false, direction: environment.direction, startIndex,\n // HJM owns selection; upstream focus scrolling must not independently change slides.\n // Embla's default 25 is a physics duration factor, not an HJM millisecond token.\n watchFocus: false, duration: environment.reducedMotion ? 0 : 25 });\n const latest = useRef(props); latest.current = props;\n const syncing = useRef(false);\n useEffect(() => {\n if (!api) return;\n const select = () => {\n const current = latest.current;\n const item = current.slides[api.selectedScrollSnap()];\n if (!syncing.current && item && item.id !== current.currentKey) current.onCurrentKeyChange(item.id);\n };\n api.on(\"select\", select);\n return () => { api.off(\"select\", select); };\n }, [api]);\n useEffect(() => { syncing.current = true; api?.scrollTo(index, environment.reducedMotion); syncing.current = false; }, [api, index, environment.reducedMotion]);\n return <section aria-label={props.label} aria-roledescription=\"carousel\">\n <div ref={viewport} style={{ overflow: \"hidden\" }}><div style={{ display: \"flex\", touchAction: \"pan-y pinch-zoom\" }}>\n {props.slides.map((slide, i) => <div key={slide.id} role=\"group\" aria-roledescription=\"slide\" aria-label={resolved[i]!.accessibleName} aria-hidden={resolved[i]!.inert} inert={resolved[i]!.inert}\n style={{ flex: \"0 0 100%\", minWidth: 0 }}>{props.renderSlide(slide)}</div>)}\n </div></div>\n <Button tone=\"ghost\" disabled={index === 0} onClick={() => props.onCurrentKeyChange(getCarouselNavigationTarget(descriptor, \"previous\"))}>{props.previousLabel}</Button>\n <Button tone=\"ghost\" disabled={index === props.slides.length - 1} onClick={() => props.onCurrentKeyChange(getCarouselNavigationTarget(descriptor, \"next\"))}>{props.nextLabel}</Button>\n </section>;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type CodeBlockDescriptor } from '@hjmds/design-contracts/code-block';
3
+ export type CodeBlockProps = CodeBlockDescriptor & Readonly<{
4
+ copyAction?: ReactNode;
5
+ }>;
6
+ /** Token text is rendered as React text, never executable HTML. */
7
+ export declare function CodeBlock({ copyAction, ...descriptor }: CodeBlockProps): import("react").JSX.Element;
8
+ //# sourceMappingURL=code-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../src/code-block.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,EAAkB,KAAK,mBAAmB,EAAC,MAAM,oCAAoC,CAAC;AAC7F,MAAM,MAAM,cAAc,GAAC,mBAAmB,GAAG,QAAQ,CAAC;IAAC,UAAU,CAAC,EAAC,SAAS,CAAA;CAAC,CAAC,CAAC;AAEnF,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,EAAC,UAAU,EAAC,GAAG,UAAU,EAAC,EAAC,cAAc,+BAAwvB"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { resolveCodeBlock } from '@hjmds/design-contracts/code-block';
3
+ const colors = { plain: 'var(--hjm-color-text)', keyword: 'var(--hjm-color-content-brand)', string: 'var(--hjm-color-text)', comment: 'var(--hjm-color-text-muted)', number: 'var(--hjm-color-content-brand)' };
4
+ /** Token text is rendered as React text, never executable HTML. */
5
+ export function CodeBlock({ copyAction, ...descriptor }) { const spec = resolveCodeBlock(descriptor); return _jsxs("section", { "aria-label": spec.label, style: { minWidth: 0, borderRadius: 'var(--hjm-radius-lg)', background: 'var(--hjm-color-surface-alt)', color: 'var(--hjm-color-text)', overflow: 'hidden' }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 'var(--hjm-space-sm)', padding: 'var(--hjm-space-md)' }, children: [_jsx("span", { children: spec.language ?? spec.label }), copyAction] }), _jsx("pre", { tabIndex: 0, "aria-label": spec.label, style: { margin: 0, padding: 'var(--hjm-space-md)', overflowX: 'auto', whiteSpace: spec.wrap ? 'pre-wrap' : 'pre', overflowWrap: spec.wrap ? 'anywhere' : undefined }, children: _jsx("code", { children: spec.tokens.map((token, index) => _jsx("span", { style: { color: colors[token.tone ?? 'plain'] }, children: token.text }, index)) }) })] }); }
6
+ //# sourceMappingURL=code-block.js.map