@hjmds/react 1.14.0 → 1.16.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 (91) hide show
  1. package/README.md +5 -0
  2. package/dist/asset.d.ts.map +1 -1
  3. package/dist/asset.js +4 -1
  4. package/dist/asset.js.map +1 -1
  5. package/dist/clipboard.d.ts.map +1 -1
  6. package/dist/clipboard.js +39 -5
  7. package/dist/clipboard.js.map +1 -1
  8. package/dist/code-block.d.ts.map +1 -1
  9. package/dist/code-block.js +3 -1
  10. package/dist/code-block.js.map +1 -1
  11. package/dist/collapsible.d.ts +4 -0
  12. package/dist/collapsible.d.ts.map +1 -1
  13. package/dist/collapsible.js +4 -4
  14. package/dist/collapsible.js.map +1 -1
  15. package/dist/collection-rail.d.ts +24 -0
  16. package/dist/collection-rail.d.ts.map +1 -0
  17. package/dist/collection-rail.js +109 -0
  18. package/dist/collection-rail.js.map +1 -0
  19. package/dist/command-palette.d.ts.map +1 -1
  20. package/dist/command-palette.js +3 -1
  21. package/dist/command-palette.js.map +1 -1
  22. package/dist/content-transition.d.ts +1 -1
  23. package/dist/content-transition.d.ts.map +1 -1
  24. package/dist/content-transition.js +3 -2
  25. package/dist/content-transition.js.map +1 -1
  26. package/dist/context-menu.d.ts.map +1 -1
  27. package/dist/context-menu.js +3 -1
  28. package/dist/context-menu.js.map +1 -1
  29. package/dist/design-profile.d.ts +18 -0
  30. package/dist/design-profile.d.ts.map +1 -0
  31. package/dist/design-profile.js +27 -0
  32. package/dist/design-profile.js.map +1 -0
  33. package/dist/effect-surface.d.ts.map +1 -1
  34. package/dist/effect-surface.js +4 -3
  35. package/dist/effect-surface.js.map +1 -1
  36. package/dist/evidence.d.ts +1 -1
  37. package/dist/evidence.js +1 -1
  38. package/dist/evidence.js.map +1 -1
  39. package/dist/floating-action-button.d.ts +1 -1
  40. package/dist/floating-action-button.d.ts.map +1 -1
  41. package/dist/floating-action-button.js +4 -1
  42. package/dist/floating-action-button.js.map +1 -1
  43. package/dist/heading.d.ts.map +1 -1
  44. package/dist/heading.js +3 -1
  45. package/dist/heading.js.map +1 -1
  46. package/dist/internal.d.ts +51 -0
  47. package/dist/internal.d.ts.map +1 -1
  48. package/dist/internal.js +7 -1
  49. package/dist/internal.js.map +1 -1
  50. package/dist/layout.d.ts +5 -1
  51. package/dist/layout.d.ts.map +1 -1
  52. package/dist/layout.js +11 -3
  53. package/dist/layout.js.map +1 -1
  54. package/dist/menubar.d.ts.map +1 -1
  55. package/dist/menubar.js +5 -2
  56. package/dist/menubar.js.map +1 -1
  57. package/dist/navigation.d.ts.map +1 -1
  58. package/dist/navigation.js +30 -9
  59. package/dist/navigation.js.map +1 -1
  60. package/dist/popover.d.ts.map +1 -1
  61. package/dist/popover.js +3 -1
  62. package/dist/popover.js.map +1 -1
  63. package/dist/provider.d.ts +4 -0
  64. package/dist/provider.d.ts.map +1 -1
  65. package/dist/provider.js +8 -2
  66. package/dist/provider.js.map +1 -1
  67. package/dist/screens.d.ts +7 -2
  68. package/dist/screens.d.ts.map +1 -1
  69. package/dist/screens.js +20 -7
  70. package/dist/screens.js.map +1 -1
  71. package/dist/selection.d.ts.map +1 -1
  72. package/dist/selection.js +4 -1
  73. package/dist/selection.js.map +1 -1
  74. package/dist/sidebar.d.ts.map +1 -1
  75. package/dist/sidebar.js +2 -1
  76. package/dist/sidebar.js.map +1 -1
  77. package/dist/skip-nav.d.ts.map +1 -1
  78. package/dist/skip-nav.js +2 -1
  79. package/dist/skip-nav.js.map +1 -1
  80. package/dist/styles.css +42 -8
  81. package/dist/styles.layered.css +42 -8
  82. package/dist/theme.d.ts.map +1 -1
  83. package/dist/theme.js +37 -8
  84. package/dist/theme.js.map +1 -1
  85. package/dist/toggle-group.d.ts.map +1 -1
  86. package/dist/toggle-group.js +3 -1
  87. package/dist/toggle-group.js.map +1 -1
  88. package/dist/top.d.ts.map +1 -1
  89. package/dist/top.js +9 -4
  90. package/dist/top.js.map +1 -1
  91. package/package.json +13 -3
@@ -1 +1 @@
1
- {"version":3,"file":"command-palette.js","sourceRoot":"","sources":["../src/command-palette.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n canDismissCommandPalette,\n commandPaletteBehaviorDefaults,\n commandPaletteRecipe,\n validateCommandPaletteDescriptor,\n type CommandPaletteActivateHandler,\n type CommandPaletteActivateReason,\n type CommandPaletteDescriptor,\n type CommandPaletteDismissPolicy,\n type CommandPaletteDismissReason,\n type CommandPaletteOpenChangeDetails,\n type CommandPaletteQueryState,\n type CommandPaletteSource,\n} from \"@hjmds/design-contracts/components/command-palette\";\nimport {\n getCollectionNavigationIntent,\n getCollectionNavigationTarget,\n isComboboxResultCurrent,\n} from \"@hjmds/design-contracts/components/collection\";\nimport type { CommandPaletteItemDescriptor } from \"@hjmds/design-contracts/components/command-palette\";\nimport {\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { classNames, composeRefs } from \"./internal.js\";\nimport { getModalLayer, HjmPortal, renderTrigger, useModalFocus, type OverlayTrigger } from \"./modal.js\";\n\ntype ResultSection<Key extends string> = Readonly<{\n id: string;\n label: string | undefined;\n name: string | undefined;\n items: readonly CommandPaletteItemDescriptor<Key>[];\n}>;\n\n// Local filter = Native Combobox substring rule; why not prefix/contracts:\n// docs/command-palette.md \"2026-10-06\" (comments ship in dist byte budgets).\nfunction resolveResults<Key extends string>(\n source: CommandPaletteSource<Key, string>,\n query: string,\n queryState: CommandPaletteQueryState | undefined,\n emptyMessage: string | undefined,\n) {\n const external = queryState?.filtering === \"external\";\n const needle = query.trim().toLocaleLowerCase();\n const keep = (item: CommandPaletteItemDescriptor<Key>) =>\n external || `${item.label} ${item.textValue}`.toLocaleLowerCase().includes(needle);\n const sections: ResultSection<Key>[] = (source.sections\n ? source.sections.map((section) => ({\n id: section.id,\n label: section.label,\n // validateCollection's precedence.\n name: section.accessibilityLabel?.trim() || section.label?.trim() || undefined,\n items: section.items.filter(keep),\n }))\n : [{ id: \"__all\", label: undefined, name: undefined, items: source.items.filter(keep) }]\n ).filter((section) => section.items.length > 0);\n const items = sections.flatMap((section) => section.items);\n const asyncState = queryState?.asyncState ?? { status: \"idle\" as const };\n const status = asyncState.status !== \"idle\"\n ? { kind: asyncState.status, message: asyncState.message }\n : items.length > 0 || emptyMessage === undefined ? null : { kind: \"empty\" as const, message: emptyMessage };\n return {\n sections,\n items,\n current: !external || isComboboxResultCurrent(queryState.queryValue, queryState.resultQuery),\n status,\n };\n}\n\nexport type CommandPaletteProps<Key extends string = string> = Readonly<{\n descriptor: CommandPaletteDescriptor;\n source: CommandPaletteSource<Key, string>;\n query: string;\n onQueryChange: (query: string) => void;\n onActivate: CommandPaletteActivateHandler<Key>;\n /** Runs after the palette is gone, for a command that opens the next surface. */\n onActivateAfterDismiss?: CommandPaletteActivateHandler<Key>;\n /**\n * Combobox's collection state. Omitted or `filtering: \"local\"` filters\n * `source` by `query` in the renderer (label/textValue substring); pass\n * `filtering: \"external\"` with `queryValue`/`resultQuery` when the product\n * already filtered or ranked the results (server or fuzzy search).\n */\n queryState?: CommandPaletteQueryState;\n dismissPolicy?: Partial<CommandPaletteDismissPolicy>;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean, details: CommandPaletteOpenChangeDetails) => void;\n trigger?: OverlayTrigger;\n renderLeading?: (itemId: Key) => ReactNode;\n portalContainer?: HTMLElement;\n className?: string;\n}>;\n\nexport const CommandPalette = forwardRef(function CommandPalette<Key extends string = string>(\n {\n descriptor,\n source,\n query,\n onQueryChange,\n onActivate,\n onActivateAfterDismiss,\n queryState,\n dismissPolicy,\n open: openProp,\n defaultOpen,\n onOpenChange,\n trigger,\n renderLeading,\n portalContainer,\n className,\n }: CommandPaletteProps<Key>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n validateCommandPaletteDescriptor(descriptor);\n const policy: CommandPaletteDismissPolicy = { ...commandPaletteBehaviorDefaults, ...dismissPolicy };\n const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);\n const open = openProp ?? internalOpen;\n const results = useMemo(\n () => resolveResults<Key>(source, query, queryState, descriptor.emptyMessage),\n [source, query, queryState, descriptor.emptyMessage],\n );\n // Stale external rows stay visible but inert, as in the Native Combobox.\n const enabled = results.current ? results.items.filter((item) => !item.disabled) : [];\n const [activeId, setActiveId] = useState<Key | null>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const id = `${useId().replaceAll(\":\", \"\")}-command-palette`;\n const active = enabled.find((item) => item.id === activeId) ?? enabled[0] ?? null;\n\n useEffect(() => {\n // A new query builds a new result list; the first enabled row becomes active\n // so Enter always has an unambiguous target. Only the query resets it: products\n // often pass `source`/`queryState` as inline objects, and keying on their\n // identity snapped the active row back to the first item on every render\n // (2026-10-06 usage-guide audit). A row that disappears from the results\n // already falls back to the first enabled row through `active` above.\n setActiveId(null);\n }, [query]);\n\n const change = (next: boolean, reason: CommandPaletteOpenChangeDetails[\"reason\"]) => {\n if (openProp === undefined) setInternalOpen(next);\n onOpenChange?.(next, { reason });\n };\n const requestClose = (reason: CommandPaletteDismissReason) => {\n if (!canDismissCommandPalette(reason, policy)) return;\n change(false, reason);\n };\n const activate = (itemId: Key, reason: CommandPaletteActivateReason) => {\n onActivate(itemId, reason);\n // Running a command always closes the palette — `activation` is a dismiss\n // reason no policy can veto — and the follow-up surface opens after that.\n change(false, \"activation\");\n if (onActivateAfterDismiss) queueMicrotask(() => onActivateAfterDismiss(itemId, reason));\n };\n\n useModalFocus({\n active: open,\n contentRef,\n initialFocusRef: inputRef,\n ...(trigger === undefined ? {} : { fallbackReturnRef: triggerRef }),\n onEscape: () => requestClose(\"escape\"),\n });\n\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n const intent = getCollectionNavigationIntent(event.key as never);\n if (intent) {\n const target = getCollectionNavigationTarget({ items: enabled }, active?.id ?? null, intent, true);\n if (target === undefined) return;\n event.preventDefault();\n setActiveId(target as Key);\n return;\n }\n if (event.key === \"Enter\" && active) {\n event.preventDefault();\n activate(active.id as Key, \"keyboard\");\n }\n };\n\n const searchInput = (\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded\n aria-controls={`${id}-results`}\n aria-activedescendant={active ? `${id}-${active.id}` : undefined}\n aria-label={descriptor.accessibilityLabel}\n placeholder={descriptor.searchPlaceholder}\n className=\"hjm-command-palette__search\"\n value={query}\n onChange={(event) => onQueryChange(event.target.value)}\n onKeyDown={onKeyDown}\n />\n );\n\n const renderedTrigger = trigger === undefined\n ? null\n : renderTrigger(trigger, triggerRef, open, id, \"dialog\", () => change(true, \"trigger\"));\n if (!open) return renderedTrigger;\n\n return (\n <>\n {renderedTrigger}\n <HjmPortal {...(portalContainer === undefined ? {} : { container: portalContainer })}>\n <div\n className=\"hjm-overlay hjm-command-palette-positioner\"\n data-kind=\"command-palette\"\n style={{ zIndex: getModalLayer(0) }}\n onMouseDown={(event) => { if (event.target === event.currentTarget) requestClose(\"outside\"); }}\n >\n <div\n ref={composeRefs(contentRef, forwardedRef)}\n id={id}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={descriptor.accessibilityLabel}\n data-hjm-modal-content=\"\"\n className={classNames(\"hjm-command-palette\", className)}\n style={{ maxInlineSize: commandPaletteRecipe.content.maxWidth, maxBlockSize: commandPaletteRecipe.content.maxHeight } as CSSProperties}\n >\n {/*\n Opt-in through descriptor.closeLabel because the renderer must not\n invent untranslated copy. Reuses Dialog's close chrome instead of a\n second close-button style (styles.css is at its byte budget).\n */}\n {descriptor.closeLabel ? (\n <div className=\"hjm-command-palette__search-row\">\n {searchInput}\n <button\n type=\"button\"\n className=\"hjm-dialog__close hjm-command-palette__close\"\n aria-label={descriptor.closeLabel}\n onClick={() => requestClose(\"close-action\")}\n >\n <span aria-hidden=\"true\">×</span>\n </button>\n </div>\n ) : searchInput}\n <div id={`${id}-results`} role=\"listbox\" aria-label={descriptor.accessibilityLabel} className=\"hjm-command-palette__viewport\">\n {results.status === null ? null : (\n // Once for the whole list, never per section.\n <p\n className=\"hjm-command-palette__state\"\n data-kind={results.status.kind}\n role={results.status.kind === \"error\" ? \"alert\" : \"status\"}\n >\n {results.status.message}\n </p>\n )}\n {results.sections.map((section) => (\n <div\n key={section.id}\n className=\"hjm-command-palette__section\"\n {...(section.name === undefined ? { role: \"presentation\" } : { role: \"group\", \"aria-label\": section.name })}\n >\n {section.label ? <p className=\"hjm-command-palette__section-label\" aria-hidden=\"true\">{section.label}</p> : null}\n {section.items.map((item) => {\n const inert = item.disabled === true || !results.current;\n return (\n <div\n key={item.id}\n id={`${id}-${item.id}`}\n role=\"option\"\n aria-selected={item.id === active?.id}\n aria-disabled={inert || undefined}\n className=\"hjm-command-palette__item\"\n data-tone={item.tone}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!inert) activate(item.id as Key, \"pointer\");\n }}\n onMouseEnter={() => { if (!inert) setActiveId(item.id as Key); }}\n >\n {renderLeading?.(item.id as Key)}\n <span className=\"hjm-command-palette__copy\">\n <span>{item.label}</span>\n {item.description ? <span className=\"hjm-command-palette__description\">{item.description}</span> : null}\n </span>\n {item.shortcut ? <kbd className=\"hjm-command-palette__shortcut\">{item.shortcut}</kbd> : null}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n </div>\n </HjmPortal>\n </>\n );\n}) as <Key extends string = string>(\n props: CommandPaletteProps<Key> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n"]}
1
+ {"version":3,"file":"command-palette.js","sourceRoot":"","sources":["../src/command-palette.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n canDismissCommandPalette,\n commandPaletteBehaviorDefaults,\n commandPaletteRecipe,\n validateCommandPaletteDescriptor,\n type CommandPaletteActivateHandler,\n type CommandPaletteActivateReason,\n type CommandPaletteDescriptor,\n type CommandPaletteDismissPolicy,\n type CommandPaletteDismissReason,\n type CommandPaletteOpenChangeDetails,\n type CommandPaletteQueryState,\n type CommandPaletteSource,\n} from \"@hjmds/design-contracts/components/command-palette\";\nimport {\n getCollectionNavigationIntent,\n getCollectionNavigationTarget,\n isComboboxResultCurrent,\n} from \"@hjmds/design-contracts/components/collection\";\nimport type { CommandPaletteItemDescriptor } from \"@hjmds/design-contracts/components/command-palette\";\nimport {\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { classNames, composeRefs } from \"./internal.js\";\nimport { getModalLayer, HjmPortal, renderTrigger, useModalFocus, type OverlayTrigger } from \"./modal.js\";\n\ntype ResultSection<Key extends string> = Readonly<{\n id: string;\n label: string | undefined;\n name: string | undefined;\n items: readonly CommandPaletteItemDescriptor<Key>[];\n}>;\n\n// Local filter = Native Combobox substring rule; why not prefix/contracts:\n// docs/command-palette.md \"2026-10-06\" (comments ship in dist byte budgets).\nfunction resolveResults<Key extends string>(\n source: CommandPaletteSource<Key, string>,\n query: string,\n queryState: CommandPaletteQueryState | undefined,\n emptyMessage: string | undefined,\n) {\n const external = queryState?.filtering === \"external\";\n const needle = query.trim().toLocaleLowerCase();\n const keep = (item: CommandPaletteItemDescriptor<Key>) =>\n external || `${item.label} ${item.textValue}`.toLocaleLowerCase().includes(needle);\n const sections: ResultSection<Key>[] = (source.sections\n ? source.sections.map((section) => ({\n id: section.id,\n label: section.label,\n // validateCollection's precedence.\n name: section.accessibilityLabel?.trim() || section.label?.trim() || undefined,\n items: section.items.filter(keep),\n }))\n : [{ id: \"__all\", label: undefined, name: undefined, items: source.items.filter(keep) }]\n ).filter((section) => section.items.length > 0);\n const items = sections.flatMap((section) => section.items);\n const asyncState = queryState?.asyncState ?? { status: \"idle\" as const };\n const status = asyncState.status !== \"idle\"\n ? { kind: asyncState.status, message: asyncState.message }\n : items.length > 0 || emptyMessage === undefined ? null : { kind: \"empty\" as const, message: emptyMessage };\n return {\n sections,\n items,\n current: !external || isComboboxResultCurrent(queryState.queryValue, queryState.resultQuery),\n status,\n };\n}\n\nexport type CommandPaletteProps<Key extends string = string> = Readonly<{\n descriptor: CommandPaletteDescriptor;\n source: CommandPaletteSource<Key, string>;\n query: string;\n onQueryChange: (query: string) => void;\n onActivate: CommandPaletteActivateHandler<Key>;\n /** Runs after the palette is gone, for a command that opens the next surface. */\n onActivateAfterDismiss?: CommandPaletteActivateHandler<Key>;\n /**\n * Combobox's collection state. Omitted or `filtering: \"local\"` filters\n * `source` by `query` in the renderer (label/textValue substring); pass\n * `filtering: \"external\"` with `queryValue`/`resultQuery` when the product\n * already filtered or ranked the results (server or fuzzy search).\n */\n queryState?: CommandPaletteQueryState;\n dismissPolicy?: Partial<CommandPaletteDismissPolicy>;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean, details: CommandPaletteOpenChangeDetails) => void;\n trigger?: OverlayTrigger;\n renderLeading?: (itemId: Key) => ReactNode;\n portalContainer?: HTMLElement;\n className?: string;\n}>;\n\nexport const CommandPalette = forwardRef(function CommandPalette<Key extends string = string>(\n {\n descriptor,\n source,\n query,\n onQueryChange,\n onActivate,\n onActivateAfterDismiss,\n queryState,\n dismissPolicy,\n open: openProp,\n defaultOpen,\n onOpenChange,\n trigger,\n renderLeading,\n portalContainer,\n className,\n }: CommandPaletteProps<Key>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n validateCommandPaletteDescriptor(descriptor);\n const policy: CommandPaletteDismissPolicy = { ...commandPaletteBehaviorDefaults, ...dismissPolicy };\n const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);\n const open = openProp ?? internalOpen;\n const results = useMemo(\n () => resolveResults<Key>(source, query, queryState, descriptor.emptyMessage),\n [source, query, queryState, descriptor.emptyMessage],\n );\n // Stale external rows stay visible but inert, as in the Native Combobox.\n const enabled = results.current ? results.items.filter((item) => !item.disabled) : [];\n const [activeId, setActiveId] = useState<Key | null>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const id = `${useId().replaceAll(\":\", \"\")}-command-palette`;\n const active = enabled.find((item) => item.id === activeId) ?? enabled[0] ?? null;\n\n useEffect(() => {\n // A new query builds a new result list; the first enabled row becomes active\n // so Enter always has an unambiguous target. Only the query resets it: products\n // often pass `source`/`queryState` as inline objects, and keying on their\n // identity snapped the active row back to the first item on every render\n // (2026-10-06 usage-guide audit). A row that disappears from the results\n // already falls back to the first enabled row through `active` above.\n setActiveId(null);\n }, [query]);\n\n const change = (next: boolean, reason: CommandPaletteOpenChangeDetails[\"reason\"]) => {\n if (openProp === undefined) setInternalOpen(next);\n onOpenChange?.(next, { reason });\n };\n const requestClose = (reason: CommandPaletteDismissReason) => {\n if (!canDismissCommandPalette(reason, policy)) return;\n change(false, reason);\n };\n const activate = (itemId: Key, reason: CommandPaletteActivateReason) => {\n onActivate(itemId, reason);\n // Running a command always closes the palette — `activation` is a dismiss\n // reason no policy can veto — and the follow-up surface opens after that.\n change(false, \"activation\");\n if (onActivateAfterDismiss) queueMicrotask(() => onActivateAfterDismiss(itemId, reason));\n };\n\n useModalFocus({\n active: open,\n contentRef,\n initialFocusRef: inputRef,\n ...(trigger === undefined ? {} : { fallbackReturnRef: triggerRef }),\n onEscape: () => requestClose(\"escape\"),\n });\n\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n const intent = getCollectionNavigationIntent(event.key as never);\n if (intent) {\n const target = getCollectionNavigationTarget({ items: enabled }, active?.id ?? null, intent, true);\n if (target === undefined) return;\n event.preventDefault();\n setActiveId(target as Key);\n return;\n }\n if (event.key === \"Enter\" && active) {\n event.preventDefault();\n activate(active.id as Key, \"keyboard\");\n }\n };\n\n const searchInput = (\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded\n aria-controls={`${id}-results`}\n aria-activedescendant={active ? `${id}-${active.id}` : undefined}\n aria-label={descriptor.accessibilityLabel}\n placeholder={descriptor.searchPlaceholder}\n className=\"hjm-command-palette__search\"\n value={query}\n onChange={(event) => onQueryChange(event.target.value)}\n onKeyDown={onKeyDown}\n />\n );\n\n const renderedTrigger = trigger === undefined\n ? null\n : renderTrigger(trigger, triggerRef, open, id, \"dialog\", () => change(true, \"trigger\"));\n if (!open) return renderedTrigger;\n\n return (\n <>\n {renderedTrigger}\n <HjmPortal {...(portalContainer === undefined ? {} : { container: portalContainer })}>\n <div\n className=\"hjm-overlay hjm-command-palette-positioner\"\n data-kind=\"command-palette\"\n style={{ zIndex: getModalLayer(0) }}\n onMouseDown={(event) => { if (event.target === event.currentTarget) requestClose(\"outside\"); }}\n >\n <div\n ref={composeRefs(contentRef, forwardedRef)}\n id={id}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={descriptor.accessibilityLabel}\n data-hjm-modal-content=\"\"\n className={classNames(\"hjm-command-palette\", className)}\n style={{ maxInlineSize: commandPaletteRecipe.content.maxWidth, maxBlockSize: commandPaletteRecipe.content.maxHeight } as CSSProperties}\n >\n {/*\n Opt-in through descriptor.closeLabel because the renderer must not\n invent untranslated copy. Reuses Dialog's close chrome instead of a\n second close-button style (styles.css is at its byte budget).\n */}\n {descriptor.closeLabel ? (\n <div className=\"hjm-command-palette__search-row\">\n {searchInput}\n <button\n type=\"button\"\n className=\"hjm-dialog__close hjm-command-palette__close\"\n aria-label={descriptor.closeLabel}\n onClick={() => requestClose(\"close-action\")}\n >\n <span aria-hidden=\"true\">×</span>\n </button>\n </div>\n ) : searchInput}\n <div id={`${id}-results`} role=\"listbox\" aria-label={descriptor.accessibilityLabel} className=\"hjm-command-palette__viewport\">\n {results.status === null ? null : (\n // Once for the whole list, never per section.\n <p\n className=\"hjm-command-palette__state\"\n data-kind={results.status.kind}\n role={results.status.kind === \"error\" ? \"alert\" : \"status\"}\n >\n {results.status.message}\n </p>\n )}\n {results.sections.map((section) => (\n <div\n key={section.id}\n className=\"hjm-command-palette__section\"\n {...(section.name === undefined ? { role: \"presentation\" } : { role: \"group\", \"aria-label\": section.name })}\n >\n {section.label ? <p className=\"hjm-command-palette__section-label\" aria-hidden=\"true\">{section.label}</p> : null}\n {section.items.map((item) => {\n // Positioning or filtering can enter a stationary cursor;\n // only mouse movement should override keyboard navigation.\n const inert = item.disabled === true || !results.current;\n return (\n <div\n key={item.id}\n id={`${id}-${item.id}`}\n role=\"option\"\n aria-selected={item.id === active?.id}\n aria-disabled={inert || undefined}\n className=\"hjm-command-palette__item\"\n data-tone={item.tone}\n onMouseDown={(event) => {\n event.preventDefault();\n if (!inert) activate(item.id as Key, \"pointer\");\n }}\n onMouseMove={() => { if (!inert) setActiveId(item.id as Key); }}\n >\n {renderLeading?.(item.id as Key)}\n <span className=\"hjm-command-palette__copy\">\n <span>{item.label}</span>\n {item.description ? <span className=\"hjm-command-palette__description\">{item.description}</span> : null}\n </span>\n {item.shortcut ? <kbd className=\"hjm-command-palette__shortcut\">{item.shortcut}</kbd> : null}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n </div>\n </HjmPortal>\n </>\n );\n}) as <Key extends string = string>(\n props: CommandPaletteProps<Key> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n"]}
@@ -17,7 +17,7 @@ export type ContentTransitionProps = {
17
17
  };
18
18
  /** Motion Primitives' keyed transition pattern, adapted to HJM's single active subtree.
19
19
  * No exiting interactive copy: it would duplicate fields and focus targets. See THIRD_PARTY_NOTICES. */
20
- export declare function ContentTransition({ stateKey, children, motion: preference, preset, focusTarget, animateHeight, enterOnMount, layoutStyle }: ContentTransitionProps): import("react").JSX.Element;
20
+ export declare function ContentTransition({ stateKey, children, motion: preference, preset: suppliedPreset, focusTarget, animateHeight, enterOnMount, layoutStyle }: ContentTransitionProps): import("react").JSX.Element;
21
21
  export type TextTransitionProps = {
22
22
  preset?: ContentTransitionPreset;
23
23
  text: string;
@@ -1 +1 @@
1
- {"version":3,"file":"content-transition.d.ts","sourceRoot":"","sources":["../src/content-transition.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAEpH,OAAO,EAAwC,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG7F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAClE,mFAAmF;IACnF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qEAAqE;IACrE,WAAW,CAAC,EAAE,uBAAuB,CAAC;IACtC,+EAA+E;IAC/E,WAAW,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC7C,CAAC;AACF;wGACwG;AACxG,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAqB,EAAE,MAAe,EAAE,WAAW,EAAE,aAAqB,EAAE,YAAoB,EAAE,WAAW,EAAE,EAAE,sBAAsB,+BAkDtM;AACD,MAAM,MAAM,mBAAmB,GAAG;IAAE,MAAM,CAAC,EAAE,uBAAuB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAAC;AACxJ,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,mBAAmB,+BAEpG"}
1
+ {"version":3,"file":"content-transition.d.ts","sourceRoot":"","sources":["../src/content-transition.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAEpH,OAAO,EAAwC,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG7F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAClE,mFAAmF;IACnF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qEAAqE;IACrE,WAAW,CAAC,EAAE,uBAAuB,CAAC;IACtC,+EAA+E;IAC/E,WAAW,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC7C,CAAC;AACF;wGACwG;AACxG,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAqB,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,aAAqB,EAAE,YAAoB,EAAE,WAAW,EAAE,EAAE,sBAAsB,+BAmD7M;AACD,MAAM,MAAM,mBAAmB,GAAG;IAAE,MAAM,CAAC,EAAE,uBAAuB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAAC;AACxJ,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,mBAAmB,+BAEpG"}
@@ -6,8 +6,9 @@ import { easing, motion as timing } from "@hjmds/design-contracts/foundations";
6
6
  import { useHjmTheme } from "./provider.js";
7
7
  /** Motion Primitives' keyed transition pattern, adapted to HJM's single active subtree.
8
8
  * No exiting interactive copy: it would duplicate fields and focus targets. See THIRD_PARTY_NOTICES. */
9
- export function ContentTransition({ stateKey, children, motion: preference = "system", preset = "fade", focusTarget, animateHeight = false, enterOnMount = false, layoutStyle }) {
10
- const { environment } = useHjmTheme();
9
+ export function ContentTransition({ stateKey, children, motion: preference = "system", preset: suppliedPreset, focusTarget, animateHeight = false, enterOnMount = false, layoutStyle }) {
10
+ const { environment, designProfile } = useHjmTheme();
11
+ const preset = suppliedPreset ?? designProfile?.interactions.contentTransition ?? "fade";
11
12
  const from = resolveContentTransition(preset, environment.direction);
12
13
  const enabled = preference !== "none" && !environment.reducedMotion;
13
14
  const frame = useRef(null);
@@ -1 +1 @@
1
- {"version":3,"file":"content-transition.js","sourceRoot":"","sources":["../src/content-transition.tsx"],"names":[],"mappings":"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","sourcesContent":["import { resolveContentTransition, type ContentTransitionPreset } from \"@hjmds/design-contracts/content-transition\";\nimport { motion } from \"framer-motion\";\nimport { useCallback, useRef, useLayoutEffect, type ReactNode, type RefObject } from \"react\";\nimport { easing, motion as timing } from \"@hjmds/design-contracts/foundations\";\nimport { useHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type ContentTransitionProps = {\n preset?: ContentTransitionPreset;\n stateKey: string; children: ReactNode; motion?: \"system\" | \"none\";\n /** Opt-in measured height transition; never renders a second interactive panel. */\n animateHeight?: boolean;\n /** Animate newly inserted content without changing its stable key or delaying its data. */\n enterOnMount?: boolean;\n /** Layout belongs to the stable outer frame, not the keyed panel. */\n layoutStyle?: HjmCompositionStyleProp;\n /** Host chooses a meaningful focus destination, e.g. the new panel heading. */\n focusTarget?: RefObject<HTMLElement | null>;\n};\n/** Motion Primitives' keyed transition pattern, adapted to HJM's single active subtree.\n * No exiting interactive copy: it would duplicate fields and focus targets. See THIRD_PARTY_NOTICES. */\nexport function ContentTransition({ stateKey, children, motion: preference = \"system\", preset = \"fade\", focusTarget, animateHeight = false, enterOnMount = false, layoutStyle }: ContentTransitionProps) {\n const { environment } = useHjmTheme();\n const from = resolveContentTransition(preset, environment.direction);\n const enabled = preference !== \"none\" && !environment.reducedMotion;\n const frame = useRef<HTMLDivElement>(null);\n const measure = useRef<HTMLDivElement>(null);\n useLayoutEffect(() => {\n const outer = frame.current; const inner = measure.current;\n if (!outer || !inner || !animateHeight || !enabled || typeof ResizeObserver === \"undefined\") return;\n let previous = inner.getBoundingClientRect().height;\n let animation: Animation | undefined;\n const settle = () => { animation?.cancel(); animation = undefined; outer.style.height = \"\"; outer.style.overflow = \"\"; previous = inner.getBoundingClientRect().height; };\n const observer = new ResizeObserver(() => {\n const next = inner.getBoundingClientRect().height;\n if (Math.abs(next - previous) < 0.5) return;\n const fromHeight = animation ? outer.getBoundingClientRect().height : previous;\n animation?.cancel(); previous = next;\n if (document.hidden || typeof outer.animate !== \"function\") { settle(); return; }\n // Measure the unconfined inner flow; transform/layout projection would scale\n // text or duplicate input subtrees. WAAPI affects only the surrounding height.\n outer.style.height = `${next}px`; outer.style.overflow = \"hidden\";\n try {\n const current = outer.animate([{ height: `${fromHeight}px` }, { height: `${next}px` }], { duration: timing.normal, easing: `cubic-bezier(${easing.enter.join(\",\")})` });\n animation = current;\n current.onfinish = () => { if (animation === current) settle(); };\n } catch { settle(); }\n });\n observer.observe(inner);\n const visibility = () => { if (document.hidden) settle(); };\n document.addEventListener(\"visibilitychange\", visibility);\n return () => { observer.disconnect(); document.removeEventListener(\"visibilitychange\", visibility); settle(); };\n }, [animateHeight, enabled]);\n const first = useRef(true);\n const host = useRef<HTMLDivElement>(null);\n const restore = useRef(false);\n const capturePanel = useCallback((node: HTMLDivElement | null) => {\n // The keyed node detaches before DOM removal. Parent effect cleanup runs too\n // late: the browser has already moved focus to body by then.\n if (!node) restore.current = Boolean(host.current?.contains(document.activeElement));\n host.current = node;\n }, []);\n useLayoutEffect(() => {\n if (restore.current) focusTarget?.current?.focus();\n restore.current = false;\n first.current = false;\n }, [stateKey, focusTarget]);\n // Caller placement stays on a separate stable wrapper so measuring and\n // animating the inner flow does not include the product margin or flex placement.\n return <div style={layoutStyle}><div ref={frame}><div ref={measure} style={{ display: \"flow-root\" }}><motion.div ref={capturePanel} key={stateKey} initial={enabled && (enterOnMount || !first.current) ? { opacity: from.opacity, x: from.translateX, y: from.translateY, scale: from.scale } : false}\n animate={{ opacity: 1, x: 0, y: 0, scale: 1 }} transition={{ duration: enabled ? timing.normal / 1000 : 0, ease: [...easing.enter] }}>{children}</motion.div></div></div></div>;\n}\nexport type TextTransitionProps = { preset?: ContentTransitionPreset; text: string; motion?: \"system\" | \"none\"; layoutStyle?: HjmCompositionStyleProp };\n/** Whole-text fade preserves graphemes, text wrapping, selection and a single spoken value. */\nexport function TextTransition({ text, motion: preference, preset, layoutStyle }: TextTransitionProps) {\n return <ContentTransition stateKey={text} {...(preset ? { preset } : {})} {...(preference ? { motion: preference } : {})} {...(layoutStyle ? { layoutStyle } : {})}>{text}</ContentTransition>;\n}\n"]}
1
+ {"version":3,"file":"content-transition.js","sourceRoot":"","sources":["../src/content-transition.tsx"],"names":[],"mappings":"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","sourcesContent":["import { resolveContentTransition, type ContentTransitionPreset } from \"@hjmds/design-contracts/content-transition\";\nimport { motion } from \"framer-motion\";\nimport { useCallback, useRef, useLayoutEffect, type ReactNode, type RefObject } from \"react\";\nimport { easing, motion as timing } from \"@hjmds/design-contracts/foundations\";\nimport { useHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type ContentTransitionProps = {\n preset?: ContentTransitionPreset;\n stateKey: string; children: ReactNode; motion?: \"system\" | \"none\";\n /** Opt-in measured height transition; never renders a second interactive panel. */\n animateHeight?: boolean;\n /** Animate newly inserted content without changing its stable key or delaying its data. */\n enterOnMount?: boolean;\n /** Layout belongs to the stable outer frame, not the keyed panel. */\n layoutStyle?: HjmCompositionStyleProp;\n /** Host chooses a meaningful focus destination, e.g. the new panel heading. */\n focusTarget?: RefObject<HTMLElement | null>;\n};\n/** Motion Primitives' keyed transition pattern, adapted to HJM's single active subtree.\n * No exiting interactive copy: it would duplicate fields and focus targets. See THIRD_PARTY_NOTICES. */\nexport function ContentTransition({ stateKey, children, motion: preference = \"system\", preset: suppliedPreset, focusTarget, animateHeight = false, enterOnMount = false, layoutStyle }: ContentTransitionProps) {\n const { environment, designProfile } = useHjmTheme();\n const preset = suppliedPreset ?? designProfile?.interactions.contentTransition ?? \"fade\";\n const from = resolveContentTransition(preset, environment.direction);\n const enabled = preference !== \"none\" && !environment.reducedMotion;\n const frame = useRef<HTMLDivElement>(null);\n const measure = useRef<HTMLDivElement>(null);\n useLayoutEffect(() => {\n const outer = frame.current; const inner = measure.current;\n if (!outer || !inner || !animateHeight || !enabled || typeof ResizeObserver === \"undefined\") return;\n let previous = inner.getBoundingClientRect().height;\n let animation: Animation | undefined;\n const settle = () => { animation?.cancel(); animation = undefined; outer.style.height = \"\"; outer.style.overflow = \"\"; previous = inner.getBoundingClientRect().height; };\n const observer = new ResizeObserver(() => {\n const next = inner.getBoundingClientRect().height;\n if (Math.abs(next - previous) < 0.5) return;\n const fromHeight = animation ? outer.getBoundingClientRect().height : previous;\n animation?.cancel(); previous = next;\n if (document.hidden || typeof outer.animate !== \"function\") { settle(); return; }\n // Measure the unconfined inner flow; transform/layout projection would scale\n // text or duplicate input subtrees. WAAPI affects only the surrounding height.\n outer.style.height = `${next}px`; outer.style.overflow = \"hidden\";\n try {\n const current = outer.animate([{ height: `${fromHeight}px` }, { height: `${next}px` }], { duration: timing.normal, easing: `cubic-bezier(${easing.enter.join(\",\")})` });\n animation = current;\n current.onfinish = () => { if (animation === current) settle(); };\n } catch { settle(); }\n });\n observer.observe(inner);\n const visibility = () => { if (document.hidden) settle(); };\n document.addEventListener(\"visibilitychange\", visibility);\n return () => { observer.disconnect(); document.removeEventListener(\"visibilitychange\", visibility); settle(); };\n }, [animateHeight, enabled]);\n const first = useRef(true);\n const host = useRef<HTMLDivElement>(null);\n const restore = useRef(false);\n const capturePanel = useCallback((node: HTMLDivElement | null) => {\n // The keyed node detaches before DOM removal. Parent effect cleanup runs too\n // late: the browser has already moved focus to body by then.\n if (!node) restore.current = Boolean(host.current?.contains(document.activeElement));\n host.current = node;\n }, []);\n useLayoutEffect(() => {\n if (restore.current) focusTarget?.current?.focus();\n restore.current = false;\n first.current = false;\n }, [stateKey, focusTarget]);\n // Caller placement stays on a separate stable wrapper so measuring and\n // animating the inner flow does not include the product margin or flex placement.\n return <div style={layoutStyle}><div ref={frame}><div ref={measure} style={{ display: \"flow-root\" }}><motion.div ref={capturePanel} key={stateKey} initial={enabled && (enterOnMount || !first.current) ? { opacity: from.opacity, x: from.translateX, y: from.translateY, scale: from.scale } : false}\n animate={{ opacity: 1, x: 0, y: 0, scale: 1 }} transition={{ duration: enabled ? timing.normal / 1000 : 0, ease: [...easing.enter] }}>{children}</motion.div></div></div></div>;\n}\nexport type TextTransitionProps = { preset?: ContentTransitionPreset; text: string; motion?: \"system\" | \"none\"; layoutStyle?: HjmCompositionStyleProp };\n/** Whole-text fade preserves graphemes, text wrapping, selection and a single spoken value. */\nexport function TextTransition({ text, motion: preference, preset, layoutStyle }: TextTransitionProps) {\n return <ContentTransition stateKey={text} {...(preset ? { preset } : {})} {...(preference ? { motion: preference } : {})} {...(layoutStyle ? { layoutStyle } : {})}>{text}</ContentTransition>;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../src/context-menu.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,yBAAyB,EAE/B,MAAM,iDAAiD,CAAC;AAEzD,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,gBAAgB,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IACnE,iFAAiF;IACjF,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,SAAS,yBAAyB,CAAC,GAAG,CAAC,EAAE,CAAC;IACjD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0GAA0G;IAC1G,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAIH,wBAAgB,WAAW,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,EAAE,EACvD,QAAQ,EACR,KAAK,EACL,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,EAAE,gBAAgB,CAAC,GAAG,CAAC,+BAyKvB"}
1
+ {"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../src/context-menu.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,yBAAyB,EAE/B,MAAM,iDAAiD,CAAC;AAEzD,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,gBAAgB,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IACnE,iFAAiF;IACjF,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,SAAS,yBAAyB,CAAC,GAAG,CAAC,EAAE,CAAC;IACjD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0GAA0G;IAC1G,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAIH,wBAAgB,WAAW,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,EAAE,EACvD,QAAQ,EACR,KAAK,EACL,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,EAAE,gBAAgB,CAAC,GAAG,CAAC,+BA2KvB"}
@@ -123,8 +123,10 @@ export function ContextMenu({ children, items, accessibilityLabel, onAction, cla
123
123
  zIndex: getModalLayer(0),
124
124
  minInlineSize: menuRecipe.minWidth,
125
125
  }, children: items.map((item) => {
126
+ // A newly positioned menu can enter a stationary cursor; that
127
+ // boundary event must not undo the user's keyboard selection.
126
128
  const index = enabled.findIndex((candidate) => candidate.id === item.id);
127
- return (_jsxs("div", { id: index >= 0 ? `${menuId}-item-${index}` : undefined, role: "menuitem", "aria-disabled": item.disabled || undefined, "data-active": index === activeIndex && !item.disabled ? "" : undefined, "data-tone": item.tone, className: "hjm-context-menu__item", onMouseEnter: () => { if (index >= 0)
129
+ return (_jsxs("div", { id: index >= 0 ? `${menuId}-item-${index}` : undefined, role: "menuitem", "aria-disabled": item.disabled || undefined, "data-active": index === activeIndex && !item.disabled ? "" : undefined, "data-tone": item.tone, className: "hjm-context-menu__item", onMouseMove: () => { if (index >= 0)
128
130
  setActiveIndex(index); }, onClick: () => {
129
131
  if (item.disabled)
130
132
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"context-menu.js","sourceRoot":"","sources":["../src/context-menu.tsx"],"names":[],"mappings":"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","sourcesContent":["import { resolveMenuTypeahead } from \"./menu-typeahead.js\";\nimport {\n resolveContextMenuAnchor,\n type ContextMenuAnchor,\n type ContextMenuItemDescriptor,\n type ContextMenuOpenReason,\n} from \"@hjmds/design-contracts/components/context-menu\";\nimport { menuRecipe } from \"@hjmds/design-contracts/recipes\";\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { HjmPortal, getModalLayer } from \"./modal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type ContextMenuProps<Key extends string = string> = Readonly<{\n /** The region the menu belongs to; right-click and long-press are bound here. */\n children: ReactNode;\n items: readonly ContextMenuItemDescriptor<Key>[];\n accessibilityLabel: string;\n onAction: (id: Key) => void;\n className?: string;\n /** Canonical layout-only placement on the in-flow host; the menu popup itself is anchored, not placed. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nconst longPressDelay = 500;\n\nexport function ContextMenu<Key extends string = string>({\n children,\n items,\n accessibilityLabel,\n onAction,\n className,\n layoutStyle,\n}: ContextMenuProps<Key>) {\n const hostRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const [menuMounted, setMenuMounted] = useState(false);\n const returnFocusRef = useRef<HTMLElement | null>(null);\n const menuId = useId();\n const [anchor, setAnchor] = useState<ContextMenuAnchor | null>(null);\n const [activeIndex, setActiveIndex] = useState(0);\n const longPress = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const typeahead = useRef({ value: \"\", time: 0 });\n const enabled = items.filter((item) => !item.disabled);\n\n const open = useCallback((reason: ContextMenuOpenReason, pointer: ContextMenuAnchor | null) => {\n const activeElement = document.activeElement;\n returnFocusRef.current = activeElement instanceof HTMLElement && hostRef.current?.contains(activeElement)\n ? activeElement\n : hostRef.current;\n const rect = hostRef.current?.getBoundingClientRect() ?? null;\n setAnchor(resolveContextMenuAnchor(\n reason,\n pointer,\n rect === null ? null : { left: rect.left, bottom: rect.bottom },\n ));\n setActiveIndex(0);\n typeahead.current = { value: \"\", time: 0 };\n }, []);\n\n const setMenuRef = useCallback((node: HTMLDivElement | null) => {\n menuRef.current = node;\n setMenuMounted(node !== null);\n }, []);\n\n useLayoutEffect(() => {\n if (anchor === null || !menuMounted || menuRef.current === null) return;\n menuRef.current.focus();\n const rect = menuRef.current.getBoundingClientRect();\n const x = Math.min(Math.max(anchor.x, 0), Math.max(window.innerWidth - rect.width, 0));\n const y = Math.min(Math.max(anchor.y, 0), Math.max(window.innerHeight - rect.height, 0));\n // The contract promises viewport coordinates; post-render measurement keeps long labels onscreen, where guessed dimensions could not account for wrapping.\n if (x !== anchor.x || y !== anchor.y) setAnchor({ x, y });\n }, [anchor, menuMounted]);\n\n useEffect(() => {\n if (anchor === null) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setAnchor(null);\n // Focus goes back where the menu was opened from, not to the body.\n returnFocusRef.current?.focus();\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex((previous) => {\n const next = event.key === \"ArrowDown\" ? previous + 1 : previous - 1;\n return (next + enabled.length) % Math.max(enabled.length, 1);\n });\n return;\n }\n if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n setActiveIndex(event.key === \"Home\" ? 0 : Math.max(enabled.length - 1, 0));\n return;\n }\n if (event.key.length === 1 && event.key !== \" \" && !event.ctrlKey && !event.metaKey && !event.altKey) {\n const result = resolveMenuTypeahead(enabled, activeIndex, event.key, typeahead.current, Date.now());\n typeahead.current = result.state;\n if (result.index !== undefined) {\n event.preventDefault();\n setActiveIndex(result.index);\n }\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n const item = enabled[activeIndex];\n if (item) { onAction(item.id as Key); setAnchor(null); returnFocusRef.current?.focus(); }\n return;\n }\n if (event.key === \"Tab\") {\n setAnchor(null);\n }\n };\n const onPointerDown = (event: PointerEvent) => {\n if (!(event.target instanceof Node) || !menuRef.current?.contains(event.target)) {\n setAnchor(null);\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n document.addEventListener(\"pointerdown\", onPointerDown);\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n document.removeEventListener(\"pointerdown\", onPointerDown);\n };\n }, [anchor, activeIndex, enabled, onAction]);\n\n return (\n <div\n ref={hostRef}\n tabIndex={0}\n className={classNames(\"hjm-context-menu-host\", className)}\n style={layoutStyle}\n onContextMenu={(event) => {\n event.preventDefault();\n open(\"pointer\", { x: event.clientX, y: event.clientY });\n }}\n onKeyDown={(event) => {\n // Shift+F10 and the Menu key are how a keyboard opens a context menu;\n // without them the feature does not exist without a pointer.\n if ((event.shiftKey && event.key === \"F10\") || event.key === \"ContextMenu\") {\n event.preventDefault();\n open(\"keyboard\", null);\n }\n }}\n onPointerDown={(event) => {\n if (event.pointerType !== \"touch\") return;\n longPress.current = setTimeout(() => open(\"longPress\", { x: event.clientX, y: event.clientY }), longPressDelay);\n }}\n onPointerUp={() => { if (longPress.current !== undefined) clearTimeout(longPress.current); }}\n onPointerCancel={() => { if (longPress.current !== undefined) clearTimeout(longPress.current); }}\n >\n {children}\n {anchor !== null ? (\n <HjmPortal>\n <div\n role=\"menu\"\n id={menuId}\n ref={setMenuRef}\n tabIndex={-1}\n aria-activedescendant={enabled[activeIndex] ? `${menuId}-item-${activeIndex}` : undefined}\n aria-label={accessibilityLabel}\n className=\"hjm-context-menu\"\n style={{\n top: anchor.y,\n left: anchor.x,\n zIndex: getModalLayer(0),\n minInlineSize: menuRecipe.minWidth,\n } as CSSProperties}\n >\n {items.map((item) => {\n const index = enabled.findIndex((candidate) => candidate.id === item.id);\n return (\n <div\n key={item.id}\n id={index >= 0 ? `${menuId}-item-${index}` : undefined}\n role=\"menuitem\"\n aria-disabled={item.disabled || undefined}\n data-active={index === activeIndex && !item.disabled ? \"\" : undefined}\n data-tone={item.tone}\n className=\"hjm-context-menu__item\"\n onMouseEnter={() => { if (index >= 0) setActiveIndex(index); }}\n onClick={() => {\n if (item.disabled) return;\n onAction(item.id as Key);\n setAnchor(null);\n returnFocusRef.current?.focus();\n }}\n >\n <span>{item.label}</span>\n {item.shortcut ? <kbd className=\"hjm-context-menu__shortcut\">{item.shortcut}</kbd> : null}\n </div>\n );\n })}\n </div>\n </HjmPortal>\n ) : null}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"context-menu.js","sourceRoot":"","sources":["../src/context-menu.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EACL,wBAAwB,GAIzB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EACL,WAAW,EACX,SAAS,EACT,KAAK,EACL,eAAe,EACf,MAAM,EACN,QAAQ,GAGT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AActD,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,MAAM,UAAU,WAAW,CAA8B,EACvD,QAAQ,EACR,KAAK,EACL,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,WAAW,GACW;IACtB,MAAM,OAAO,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,cAAc,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC;IACvB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAA2B,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,MAAM,CAA4C,SAAS,CAAC,CAAC;IAC/E,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,MAA6B,EAAE,OAAiC,EAAE,EAAE;QAC5F,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;QAC7C,cAAc,CAAC,OAAO,GAAG,aAAa,YAAY,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC;YACvG,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QACpB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,qBAAqB,EAAE,IAAI,IAAI,CAAC;QAC9D,SAAS,CAAC,wBAAwB,CAChC,MAAM,EACN,OAAO,EACP,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAChE,CAAC,CAAC;QACH,cAAc,CAAC,CAAC,CAAC,CAAC;QAClB,SAAS,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC7C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,IAA2B,EAAE,EAAE;QAC7D,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QACvB,cAAc,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAChC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,eAAe,CAAC,GAAG,EAAE;QACnB,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI;YAAE,OAAO;QACxE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;QACrD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACvF,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QACzF,2JAA2J;QAC3J,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC;YAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAE1B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAC5B,MAAM,SAAS,GAAG,CAAC,KAAoB,EAAE,EAAE;YACzC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC3B,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChB,mEAAmE;gBACnE,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;gBAChC,OAAO;YACT,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;gBACzD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,cAAc,CAAC,CAAC,QAAQ,EAAE,EAAE;oBAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;oBACrE,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAC/D,CAAC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;gBAChD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,cAAc,CAAC,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC3E,OAAO;YACT,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACrG,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBACpG,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;gBACjC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;gBACD,OAAO;YACT,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;gBAC/C,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;gBAClC,IAAI,IAAI,EAAE,CAAC;oBAAC,QAAQ,CAAC,IAAI,CAAC,EAAS,CAAC,CAAC;oBAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAAC,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;gBAAC,CAAC;gBACzF,OAAO;YACT,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;gBACxB,SAAS,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QACF,MAAM,aAAa,GAAG,CAAC,KAAmB,EAAE,EAAE;YAC5C,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChF,SAAS,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChD,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;QACxD,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACnD,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;QAC7D,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE7C,OAAO,CACL,eACE,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,CAAC,EACX,SAAS,EAAE,UAAU,CAAC,uBAAuB,EAAE,SAAS,CAAC,EACzD,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC,EACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,sEAAsE;YACtE,6DAA6D;YAC7D,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;gBAC3E,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC,EACD,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO;gBAAE,OAAO;YAC1C,SAAS,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC;QAClH,CAAC,EACD,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAC5F,eAAe,EAAE,GAAG,EAAE,GAAG,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAE/F,QAAQ,EACR,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CACjB,KAAC,SAAS,cACR,cACE,IAAI,EAAC,MAAM,EACX,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,CAAC,CAAC,2BACW,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,SAAS,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,gBAC7E,kBAAkB,EAC9B,SAAS,EAAC,kBAAkB,EAC5B,KAAK,EAAE;wBACL,GAAG,EAAE,MAAM,CAAC,CAAC;wBACb,IAAI,EAAE,MAAM,CAAC,CAAC;wBACd,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;wBACxB,aAAa,EAAE,UAAU,CAAC,QAAQ;qBAClB,YAEjB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;wBAClB,8DAA8D;wBAC9D,8DAA8D;wBAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;wBACzE,OAAO,CACL,eAEE,EAAE,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,EACtD,IAAI,EAAC,UAAU,mBACA,IAAI,CAAC,QAAQ,IAAI,SAAS,iBAC5B,KAAK,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,eAC1D,IAAI,CAAC,IAAI,EACpB,SAAS,EAAC,wBAAwB,EAClC,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;gCAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAC7D,OAAO,EAAE,GAAG,EAAE;gCACZ,IAAI,IAAI,CAAC,QAAQ;oCAAE,OAAO;gCAC1B,QAAQ,CAAC,IAAI,CAAC,EAAS,CAAC,CAAC;gCACzB,SAAS,CAAC,IAAI,CAAC,CAAC;gCAChB,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;4BAClC,CAAC,aAED,yBAAO,IAAI,CAAC,KAAK,GAAQ,EACxB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,4BAA4B,YAAE,IAAI,CAAC,QAAQ,GAAO,CAAC,CAAC,CAAC,IAAI,KAhBpF,IAAI,CAAC,EAAE,CAiBR,CACP,CAAC;oBACJ,CAAC,CAAC,GACE,GACI,CACb,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { resolveMenuTypeahead } from \"./menu-typeahead.js\";\nimport {\n resolveContextMenuAnchor,\n type ContextMenuAnchor,\n type ContextMenuItemDescriptor,\n type ContextMenuOpenReason,\n} from \"@hjmds/design-contracts/components/context-menu\";\nimport { menuRecipe } from \"@hjmds/design-contracts/recipes\";\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { HjmPortal, getModalLayer } from \"./modal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type ContextMenuProps<Key extends string = string> = Readonly<{\n /** The region the menu belongs to; right-click and long-press are bound here. */\n children: ReactNode;\n items: readonly ContextMenuItemDescriptor<Key>[];\n accessibilityLabel: string;\n onAction: (id: Key) => void;\n className?: string;\n /** Canonical layout-only placement on the in-flow host; the menu popup itself is anchored, not placed. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nconst longPressDelay = 500;\n\nexport function ContextMenu<Key extends string = string>({\n children,\n items,\n accessibilityLabel,\n onAction,\n className,\n layoutStyle,\n}: ContextMenuProps<Key>) {\n const hostRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const [menuMounted, setMenuMounted] = useState(false);\n const returnFocusRef = useRef<HTMLElement | null>(null);\n const menuId = useId();\n const [anchor, setAnchor] = useState<ContextMenuAnchor | null>(null);\n const [activeIndex, setActiveIndex] = useState(0);\n const longPress = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const typeahead = useRef({ value: \"\", time: 0 });\n const enabled = items.filter((item) => !item.disabled);\n\n const open = useCallback((reason: ContextMenuOpenReason, pointer: ContextMenuAnchor | null) => {\n const activeElement = document.activeElement;\n returnFocusRef.current = activeElement instanceof HTMLElement && hostRef.current?.contains(activeElement)\n ? activeElement\n : hostRef.current;\n const rect = hostRef.current?.getBoundingClientRect() ?? null;\n setAnchor(resolveContextMenuAnchor(\n reason,\n pointer,\n rect === null ? null : { left: rect.left, bottom: rect.bottom },\n ));\n setActiveIndex(0);\n typeahead.current = { value: \"\", time: 0 };\n }, []);\n\n const setMenuRef = useCallback((node: HTMLDivElement | null) => {\n menuRef.current = node;\n setMenuMounted(node !== null);\n }, []);\n\n useLayoutEffect(() => {\n if (anchor === null || !menuMounted || menuRef.current === null) return;\n menuRef.current.focus();\n const rect = menuRef.current.getBoundingClientRect();\n const x = Math.min(Math.max(anchor.x, 0), Math.max(window.innerWidth - rect.width, 0));\n const y = Math.min(Math.max(anchor.y, 0), Math.max(window.innerHeight - rect.height, 0));\n // The contract promises viewport coordinates; post-render measurement keeps long labels onscreen, where guessed dimensions could not account for wrapping.\n if (x !== anchor.x || y !== anchor.y) setAnchor({ x, y });\n }, [anchor, menuMounted]);\n\n useEffect(() => {\n if (anchor === null) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setAnchor(null);\n // Focus goes back where the menu was opened from, not to the body.\n returnFocusRef.current?.focus();\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex((previous) => {\n const next = event.key === \"ArrowDown\" ? previous + 1 : previous - 1;\n return (next + enabled.length) % Math.max(enabled.length, 1);\n });\n return;\n }\n if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n setActiveIndex(event.key === \"Home\" ? 0 : Math.max(enabled.length - 1, 0));\n return;\n }\n if (event.key.length === 1 && event.key !== \" \" && !event.ctrlKey && !event.metaKey && !event.altKey) {\n const result = resolveMenuTypeahead(enabled, activeIndex, event.key, typeahead.current, Date.now());\n typeahead.current = result.state;\n if (result.index !== undefined) {\n event.preventDefault();\n setActiveIndex(result.index);\n }\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n const item = enabled[activeIndex];\n if (item) { onAction(item.id as Key); setAnchor(null); returnFocusRef.current?.focus(); }\n return;\n }\n if (event.key === \"Tab\") {\n setAnchor(null);\n }\n };\n const onPointerDown = (event: PointerEvent) => {\n if (!(event.target instanceof Node) || !menuRef.current?.contains(event.target)) {\n setAnchor(null);\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n document.addEventListener(\"pointerdown\", onPointerDown);\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n document.removeEventListener(\"pointerdown\", onPointerDown);\n };\n }, [anchor, activeIndex, enabled, onAction]);\n\n return (\n <div\n ref={hostRef}\n tabIndex={0}\n className={classNames(\"hjm-context-menu-host\", className)}\n style={layoutStyle}\n onContextMenu={(event) => {\n event.preventDefault();\n open(\"pointer\", { x: event.clientX, y: event.clientY });\n }}\n onKeyDown={(event) => {\n // Shift+F10 and the Menu key are how a keyboard opens a context menu;\n // without them the feature does not exist without a pointer.\n if ((event.shiftKey && event.key === \"F10\") || event.key === \"ContextMenu\") {\n event.preventDefault();\n open(\"keyboard\", null);\n }\n }}\n onPointerDown={(event) => {\n if (event.pointerType !== \"touch\") return;\n longPress.current = setTimeout(() => open(\"longPress\", { x: event.clientX, y: event.clientY }), longPressDelay);\n }}\n onPointerUp={() => { if (longPress.current !== undefined) clearTimeout(longPress.current); }}\n onPointerCancel={() => { if (longPress.current !== undefined) clearTimeout(longPress.current); }}\n >\n {children}\n {anchor !== null ? (\n <HjmPortal>\n <div\n role=\"menu\"\n id={menuId}\n ref={setMenuRef}\n tabIndex={-1}\n aria-activedescendant={enabled[activeIndex] ? `${menuId}-item-${activeIndex}` : undefined}\n aria-label={accessibilityLabel}\n className=\"hjm-context-menu\"\n style={{\n top: anchor.y,\n left: anchor.x,\n zIndex: getModalLayer(0),\n minInlineSize: menuRecipe.minWidth,\n } as CSSProperties}\n >\n {items.map((item) => {\n // A newly positioned menu can enter a stationary cursor; that\n // boundary event must not undo the user's keyboard selection.\n const index = enabled.findIndex((candidate) => candidate.id === item.id);\n return (\n <div\n key={item.id}\n id={index >= 0 ? `${menuId}-item-${index}` : undefined}\n role=\"menuitem\"\n aria-disabled={item.disabled || undefined}\n data-active={index === activeIndex && !item.disabled ? \"\" : undefined}\n data-tone={item.tone}\n className=\"hjm-context-menu__item\"\n onMouseMove={() => { if (index >= 0) setActiveIndex(index); }}\n onClick={() => {\n if (item.disabled) return;\n onAction(item.id as Key);\n setAnchor(null);\n returnFocusRef.current?.focus();\n }}\n >\n <span>{item.label}</span>\n {item.shortcut ? <kbd className=\"hjm-context-menu__shortcut\">{item.shortcut}</kbd> : null}\n </div>\n );\n })}\n </div>\n </HjmPortal>\n ) : null}\n </div>\n );\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { type ReactNode } from "react";
2
+ import { type ScreenLayoutProps } from "./screens.js";
3
+ import type { HjmDesignProfile } from "@hjmds/design-contracts/design-profile";
4
+ export type OverviewScreenProps = Omit<ScreenLayoutProps, "children"> & Readonly<{
5
+ items: readonly Readonly<{
6
+ id: string;
7
+ children: ReactNode;
8
+ }>[];
9
+ toolbar?: ReactNode;
10
+ toolbarLabel: string;
11
+ collection?: HjmDesignProfile["compositions"]["collection"];
12
+ toolbarPresentation?: HjmDesignProfile["compositions"]["toolbar"];
13
+ }>;
14
+ /** Optional collection screen; ScreenLayout still owns loading/error/scrolling.
15
+ * Unlike settings/inbox it owns a profile-selected collection and persistent tools.
16
+ * It never owns product mutations or chooses a different component for each theme. */
17
+ export declare function OverviewScreen({ items, toolbar, toolbarLabel, collection: suppliedCollection, toolbarPresentation: suppliedToolbarPresentation, ...screen }: OverviewScreenProps): import("react").JSX.Element;
18
+ //# sourceMappingURL=design-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-profile.d.ts","sourceRoot":"","sources":["../src/design-profile.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAMpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAE/E,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC;IAC/E,KAAK,EAAE,SAAS,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,EAAE,CAAC;IAChE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC;CACnE,CAAC,CAAC;AAEH;;sFAEsF;AACtF,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,GAAG,MAAM,EAAE,EAAE,mBAAmB,+BAqBhL"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { ScreenLayout } from "./screens.js";
4
+ import { Collapsible } from "./collapsible.js";
5
+ import { EffectSurface } from "./effect-surface.js";
6
+ import { Grid, Stack, Surface } from "./layout.js";
7
+ import { useHjmTheme } from "./provider.js";
8
+ import { resolveDesignProfileCollection } from "@hjmds/design-contracts/design-profile-layout";
9
+ /** Optional collection screen; ScreenLayout still owns loading/error/scrolling.
10
+ * Unlike settings/inbox it owns a profile-selected collection and persistent tools.
11
+ * It never owns product mutations or chooses a different component for each theme. */
12
+ export function OverviewScreen({ items, toolbar, toolbarLabel, collection: suppliedCollection, toolbarPresentation: suppliedToolbarPresentation, ...screen }) {
13
+ const { designProfile } = useHjmTheme();
14
+ const collection = suppliedCollection ?? designProfile?.compositions.collection ?? "rows";
15
+ const toolbarPresentation = suppliedToolbarPresentation ?? designProfile?.compositions.toolbar ?? "inline";
16
+ const [toolsOpen, setToolsOpen] = useState(true);
17
+ if (!toolbarLabel.trim())
18
+ throw new TypeError("Overview tools need a localized label");
19
+ const ids = new Set(items.map(item => item.id));
20
+ if (ids.size !== items.length || items.some(item => !item.id.trim()))
21
+ throw new TypeError("Overview items need unique stable ids");
22
+ // Retain the same effect/grid/surface subtree when the profile changes: optional
23
+ // decoration can disappear without remounting fields, focus or local state.
24
+ const canvas = designProfile?.material.canvas ?? { layers: ["mesh"], intensity: 0, active: false };
25
+ return _jsx(EffectSurface, { descriptor: canvas, layoutStyle: { width: "100%" }, children: _jsx(ScreenLayout, { ...screen, children: _jsxs(Stack, { gap: "xl", children: [toolbar ? _jsx(Collapsible, { trigger: toolbarLabel, open: toolsOpen, onOpenChange: setToolsOpen, presentation: toolbarPresentation === "inline" ? "inline" : "disclosure", keepMounted: true, children: toolbar }) : null, _jsx(Grid, { ...resolveDesignProfileCollection(collection), children: items.map(item => _jsx(Surface, { padding: collection === "rows" ? "md" : "xl", tone: collection === "rows" ? "default" : "raised", bordered: true, radius: "lg", children: _jsx(EffectSurface, { descriptor: designProfile?.material.card ?? { layers: ["mesh"], intensity: 0, active: false }, className: "hjm-profile-card-effect", children: item.children }) }, item.id)) })] }) }) });
26
+ }
27
+ //# sourceMappingURL=design-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-profile.js","sourceRoot":"","sources":["../src/design-profile.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState, type ReactNode } from \"react\";\nimport { ScreenLayout, type ScreenLayoutProps } from \"./screens.js\";\nimport { Collapsible } from \"./collapsible.js\";\nimport { EffectSurface } from \"./effect-surface.js\";\nimport { Grid, Stack, Surface } from \"./layout.js\";\nimport { useHjmTheme } from \"./provider.js\";\nimport { resolveDesignProfileCollection } from \"@hjmds/design-contracts/design-profile-layout\";\nimport type { HjmDesignProfile } from \"@hjmds/design-contracts/design-profile\";\n\nexport type OverviewScreenProps = Omit<ScreenLayoutProps, \"children\"> & Readonly<{\n items: readonly Readonly<{ id: string; children: ReactNode }>[];\n toolbar?: ReactNode;\n toolbarLabel: string;\n collection?: HjmDesignProfile[\"compositions\"][\"collection\"];\n toolbarPresentation?: HjmDesignProfile[\"compositions\"][\"toolbar\"];\n}>;\n\n/** Optional collection screen; ScreenLayout still owns loading/error/scrolling.\n * Unlike settings/inbox it owns a profile-selected collection and persistent tools.\n * It never owns product mutations or chooses a different component for each theme. */\nexport function OverviewScreen({ items, toolbar, toolbarLabel, collection: suppliedCollection, toolbarPresentation: suppliedToolbarPresentation, ...screen }: OverviewScreenProps) {\n const { designProfile } = useHjmTheme();\n const collection = suppliedCollection ?? designProfile?.compositions.collection ?? \"rows\";\n const toolbarPresentation = suppliedToolbarPresentation ?? designProfile?.compositions.toolbar ?? \"inline\";\n const [toolsOpen, setToolsOpen] = useState(true);\n if (!toolbarLabel.trim()) throw new TypeError(\"Overview tools need a localized label\");\n const ids = new Set(items.map(item => item.id));\n if (ids.size !== items.length || items.some(item => !item.id.trim())) throw new TypeError(\"Overview items need unique stable ids\");\n // Retain the same effect/grid/surface subtree when the profile changes: optional\n // decoration can disappear without remounting fields, focus or local state.\n const canvas = designProfile?.material.canvas ?? { layers: [\"mesh\"] as const, intensity: 0, active: false };\n return <EffectSurface descriptor={canvas} layoutStyle={{ width: \"100%\" }}>\n <ScreenLayout {...screen}>\n <Stack gap=\"xl\">\n {toolbar ? <Collapsible trigger={toolbarLabel} open={toolsOpen} onOpenChange={setToolsOpen} presentation={toolbarPresentation === \"inline\" ? \"inline\" : \"disclosure\"} keepMounted>{toolbar}</Collapsible> : null}\n <Grid {...resolveDesignProfileCollection(collection)}>\n {items.map(item => <Surface key={item.id} padding={collection === \"rows\" ? \"md\" : \"xl\"} tone={collection === \"rows\" ? \"default\" : \"raised\"} bordered radius=\"lg\"><EffectSurface descriptor={designProfile?.material.card ?? { layers: [\"mesh\"], intensity: 0, active: false }} className=\"hjm-profile-card-effect\">{item.children}</EffectSurface></Surface>)}\n </Grid>\n </Stack>\n </ScreenLayout>\n </EffectSurface>;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"effect-surface.d.ts","sourceRoot":"","sources":["../src/effect-surface.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EAAwB,KAAK,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAE5G,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IAAE,UAAU,CAAC,EAAE,uBAAuB,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC,gGAAgG;IAAC,WAAW,CAAC,EAAE,uBAAuB,CAAC;CAAE,CAAC,CAAC;AACtQ,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,EAAE,UAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,kBAAkB,+BAgDtG"}
1
+ {"version":3,"file":"effect-surface.d.ts","sourceRoot":"","sources":["../src/effect-surface.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EAAwB,KAAK,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAE5G,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IAAE,UAAU,CAAC,EAAE,uBAAuB,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC,gGAAgG;IAAC,WAAW,CAAC,EAAE,uBAAuB,CAAC;CAAE,CAAC,CAAC;AACtQ,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,EAAE,UAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,kBAAkB,+BAsDtG"}
@@ -11,6 +11,7 @@ export function EffectSurface({ descriptor = {}, children, className, layoutStyl
11
11
  const host = useRef(null);
12
12
  const layer = useRef(null);
13
13
  const [visible, setVisible] = useState(false);
14
+ const hasAtmosphere = effect.layers.some(value => value !== "ruled");
14
15
  useEffect(() => {
15
16
  if (!host.current)
16
17
  return;
@@ -24,7 +25,7 @@ export function EffectSurface({ descriptor = {}, children, className, layoutStyl
24
25
  }, []);
25
26
  useEffect(() => {
26
27
  const node = layer.current;
27
- if (!node || !effect.active || environment.reducedMotion || !visible || typeof node.animate !== "function")
28
+ if (!node || !hasAtmosphere || !effect.active || environment.reducedMotion || !visible || typeof node.animate !== "function")
28
29
  return;
29
30
  // WAAPI stays outside React renders; visibility changes cancel the loop and
30
31
  // expose its static composition rather than scheduling invisible frames.
@@ -50,8 +51,8 @@ export function EffectSurface({ descriptor = {}, children, className, layoutStyl
50
51
  sync();
51
52
  document.addEventListener("visibilitychange", sync);
52
53
  return () => { animation?.cancel(); document.removeEventListener("visibilitychange", sync); };
53
- }, [effect.active, effect.period, environment.reducedMotion, visible]);
54
+ }, [hasAtmosphere, effect.active, effect.period, environment.reducedMotion, visible]);
54
55
  const colors = effect.colors.map(color => resolveColorReference(color, palette));
55
- return _jsxs("div", { ref: host, className: className, "data-hjm-effect-surface": "", style: { ...layoutStyle, position: "relative", isolation: "isolate", overflow: "hidden", background: palette.theme.bg }, children: [_jsxs("svg", { ref: layer, "aria-hidden": "true", focusable: "false", style: { position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none", opacity: effect.intensity }, children: [_jsx("defs", { children: effect.noise && _jsxs(_Fragment, { children: [_jsx("pattern", { id: `${id}-noise-tile`, width: effect.noise.size, height: effect.noise.size, x: effect.noise.offset, patternUnits: "userSpaceOnUse", children: _jsx("image", { href: effect.noise.uri, width: effect.noise.size, height: effect.noise.size }) }), _jsx("mask", { id: `${id}-noise-mask`, x: 0, y: 0, width: "100%", height: "100%", maskUnits: "userSpaceOnUse", children: _jsx("rect", { width: "100%", height: "100%", fill: `url(#${id}-noise-tile)` }) })] }) }), effect.noise && _jsx("rect", { width: "100%", height: "100%", fill: palette.theme.text, mask: `url(#${id}-noise-mask)` }), _jsxs("svg", { width: "100%", height: "100%", viewBox: "0 0 100 100", preserveAspectRatio: "none", children: [_jsxs("defs", { children: [colors.map((color, index) => _jsxs("radialGradient", { id: `${id}-${index}`, children: [_jsx("stop", { offset: "0%", stopColor: color }), _jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0 })] }, index)), _jsx("pattern", { id: `${id}-grain`, width: 4, height: 4, patternUnits: "userSpaceOnUse", children: effect.points.map((point, index) => _jsx("circle", { cx: point.x / 25, cy: point.y / 25, r: point.radius / 10, fill: palette.theme.text, opacity: 0.28 }, index)) })] }), effect.layers.includes("mesh") && effect.anchors.map((anchor, index) => _jsx("ellipse", { cx: anchor.x, cy: anchor.y, rx: 65, ry: 70, fill: `url(#${id}-${index})` }, index)), effect.layers.includes("glow") && _jsx("ellipse", { cx: 50, cy: 10, rx: 70, ry: 95, fill: `url(#${id}-0)` }), effect.layers.includes("grain") && _jsx("rect", { width: 100, height: 100, fill: `url(#${id}-grain)` })] })] }), _jsx("div", { style: { position: "relative" }, children: children })] });
56
+ return _jsxs("div", { ref: host, className: className, "data-hjm-effect-surface": "", style: { ...layoutStyle, position: "relative", isolation: "isolate", overflow: "hidden", background: palette.theme.bg }, children: [_jsxs("svg", { ref: layer, "aria-hidden": "true", focusable: "false", style: { position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none", opacity: effect.intensity }, children: [_jsx("defs", { children: effect.noise && _jsxs(_Fragment, { children: [_jsx("pattern", { id: `${id}-noise-tile`, width: effect.noise.size, height: effect.noise.size, x: effect.noise.offset, patternUnits: "userSpaceOnUse", children: _jsx("image", { href: effect.noise.uri, width: effect.noise.size, height: effect.noise.size }) }), _jsx("mask", { id: `${id}-noise-mask`, x: 0, y: 0, width: "100%", height: "100%", maskUnits: "userSpaceOnUse", children: _jsx("rect", { width: "100%", height: "100%", fill: `url(#${id}-noise-tile)` }) })] }) }), effect.noise && _jsx("rect", { width: "100%", height: "100%", fill: palette.theme.text, mask: `url(#${id}-noise-mask)` }), _jsxs("svg", { width: "100%", height: "100%", viewBox: "0 0 100 100", preserveAspectRatio: "none", children: [_jsxs("defs", { children: [colors.map((color, index) => _jsxs("radialGradient", { id: `${id}-${index}`, children: [_jsx("stop", { offset: "0%", stopColor: color }), _jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0 })] }, index)), _jsx("pattern", { id: `${id}-grain`, width: 4, height: 4, patternUnits: "userSpaceOnUse", children: effect.points.map((point, index) => _jsx("circle", { cx: point.x / 25, cy: point.y / 25, r: point.radius / 10, fill: palette.theme.text, opacity: 0.28 }, index)) })] }), effect.layers.includes("mesh") && effect.anchors.map((anchor, index) => _jsx("ellipse", { cx: anchor.x, cy: anchor.y, rx: 65, ry: 70, fill: `url(#${id}-${index})` }, index)), effect.layers.includes("glow") && _jsx("ellipse", { cx: 50, cy: 10, rx: 70, ry: 95, fill: `url(#${id}-0)` }), effect.layers.includes("grain") && _jsx("rect", { width: 100, height: 100, fill: `url(#${id}-grain)` })] })] }), effect.ruled && _jsxs("svg", { "data-hjm-effect-layer": "ruled", "aria-hidden": "true", focusable: "false", style: { position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none", opacity: effect.intensity }, children: [_jsx("defs", { children: _jsx("pattern", { id: `${id}-ruled`, width: 1, height: effect.ruled.spacing, patternUnits: "userSpaceOnUse", children: _jsx("rect", { y: effect.ruled.spacing - effect.ruled.thickness, width: "100%", height: effect.ruled.thickness, fill: palette.theme.text }) }) }), _jsx("rect", { width: "100%", height: "100%", fill: `url(#${id}-ruled)` })] }), _jsx("div", { style: { position: "relative" }, children: children })] });
56
57
  }
57
58
  //# sourceMappingURL=effect-surface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"effect-surface.js","sourceRoot":"","sources":["../src/effect-surface.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useId, useRef, useState, type ReactNode } from \"react\";\nimport { resolveEffectSurface, type EffectSurfaceDescriptor } from \"@hjmds/design-contracts/effect-surface\";\nimport { resolveColorReference } from \"@hjmds/design-contracts/color-references\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { useHjmTheme } from \"./provider.js\";\nexport type EffectSurfaceProps = Readonly<{ descriptor?: EffectSurfaceDescriptor; children: ReactNode; className?: string; /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */ layoutStyle?: HjmCompositionStyleProp; }>;\n/** Decorative layers never receive pointer events or own the content's name. */\nexport function EffectSurface({ descriptor = {}, children, className, layoutStyle }: EffectSurfaceProps) {\n const { palette, environment } = useHjmTheme();\n const effect = resolveEffectSurface(descriptor);\n const id = useId().replace(/:/g, \"\");\n const host = useRef<HTMLDivElement>(null);\n const layer = useRef<SVGSVGElement>(null);\n const [visible, setVisible] = useState(false);\n useEffect(() => {\n if (!host.current) return;\n if (typeof IntersectionObserver === \"undefined\") { setVisible(true); return; }\n const observer = new IntersectionObserver(([entry]) => setVisible(entry?.isIntersecting ?? false));\n observer.observe(host.current); return () => observer.disconnect();\n }, []);\n useEffect(() => {\n const node = layer.current;\n if (!node || !effect.active || environment.reducedMotion || !visible || typeof node.animate !== \"function\") return;\n // WAAPI stays outside React renders; visibility changes cancel the loop and\n // expose its static composition rather than scheduling invisible frames.\n let animation: Animation | undefined;\n let failed = false;\n const sync = () => { animation?.cancel(); if (document.hidden || failed) return;\n // A host may expose WAAPI but reject animation creation. Keep the static SVG\n // and content instead of propagating a decorative failure to the application.\n try { animation = node.animate([\n { transform: \"scale(1.08) translate(-1%, 0%)\" },\n { transform: \"scale(1.12) translate(1%, 1%)\" },\n { transform: \"scale(1.08) translate(-1%, 0%)\" },\n ], { duration: effect.period * 1000, iterations: Infinity, easing: \"ease-in-out\" }); } catch { failed = true; } };\n sync(); document.addEventListener(\"visibilitychange\", sync);\n return () => { animation?.cancel(); document.removeEventListener(\"visibilitychange\", sync); };\n }, [effect.active, effect.period, environment.reducedMotion, visible]);\n const colors = effect.colors.map(color => resolveColorReference(color, palette));\n return <div ref={host} className={className} data-hjm-effect-surface=\"\" style={{ ...layoutStyle, position: \"relative\", isolation: \"isolate\", overflow: \"hidden\", background: palette.theme.bg }}>\n <svg ref={layer} aria-hidden=\"true\" focusable=\"false\" style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\", pointerEvents: \"none\", opacity: effect.intensity }}>\n {/* Keep noise in CSS-pixel units; the existing geometric layers retain their viewBox. */}\n <defs>{effect.noise && <><pattern id={`${id}-noise-tile`} width={effect.noise.size} height={effect.noise.size} x={effect.noise.offset} patternUnits=\"userSpaceOnUse\"><image href={effect.noise.uri} width={effect.noise.size} height={effect.noise.size} /></pattern><mask id={`${id}-noise-mask`} x={0} y={0} width=\"100%\" height=\"100%\" maskUnits=\"userSpaceOnUse\"><rect width=\"100%\" height=\"100%\" fill={`url(#${id}-noise-tile)`} /></mask></>}</defs>\n {effect.noise && <rect width=\"100%\" height=\"100%\" fill={palette.theme.text} mask={`url(#${id}-noise-mask)`} />}\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\">\n <defs>{colors.map((color, index) => <radialGradient id={`${id}-${index}`} key={index}><stop offset=\"0%\" stopColor={color} /><stop offset=\"100%\" stopColor={color} stopOpacity={0} /></radialGradient>)}\n <pattern id={`${id}-grain`} width={4} height={4} patternUnits=\"userSpaceOnUse\">{effect.points.map((point, index) => <circle key={index} cx={point.x / 25} cy={point.y / 25} r={point.radius / 10} fill={palette.theme.text} opacity={0.28} />)}</pattern>\n </defs>\n {effect.layers.includes(\"mesh\") && effect.anchors.map((anchor, index) => <ellipse key={index} cx={anchor.x} cy={anchor.y} rx={65} ry={70} fill={`url(#${id}-${index})`} />)}\n {effect.layers.includes(\"glow\") && <ellipse cx={50} cy={10} rx={70} ry={95} fill={`url(#${id}-0)`} />}\n {effect.layers.includes(\"grain\") && <rect width={100} height={100} fill={`url(#${id}-grain)`} />}\n </svg>\n </svg>\n <div style={{ position: \"relative\" }}>{children}</div>\n </div>;\n}\n"]}
1
+ {"version":3,"file":"effect-surface.js","sourceRoot":"","sources":["../src/effect-surface.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useId, useRef, useState, type ReactNode } from \"react\";\nimport { resolveEffectSurface, type EffectSurfaceDescriptor } from \"@hjmds/design-contracts/effect-surface\";\nimport { resolveColorReference } from \"@hjmds/design-contracts/color-references\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { useHjmTheme } from \"./provider.js\";\nexport type EffectSurfaceProps = Readonly<{ descriptor?: EffectSurfaceDescriptor; children: ReactNode; className?: string; /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */ layoutStyle?: HjmCompositionStyleProp; }>;\n/** Decorative layers never receive pointer events or own the content's name. */\nexport function EffectSurface({ descriptor = {}, children, className, layoutStyle }: EffectSurfaceProps) {\n const { palette, environment } = useHjmTheme();\n const effect = resolveEffectSurface(descriptor);\n const id = useId().replace(/:/g, \"\");\n const host = useRef<HTMLDivElement>(null);\n const layer = useRef<SVGSVGElement>(null);\n const [visible, setVisible] = useState(false);\n const hasAtmosphere = effect.layers.some(value => value !== \"ruled\");\n useEffect(() => {\n if (!host.current) return;\n if (typeof IntersectionObserver === \"undefined\") { setVisible(true); return; }\n const observer = new IntersectionObserver(([entry]) => setVisible(entry?.isIntersecting ?? false));\n observer.observe(host.current); return () => observer.disconnect();\n }, []);\n useEffect(() => {\n const node = layer.current;\n if (!node || !hasAtmosphere || !effect.active || environment.reducedMotion || !visible || typeof node.animate !== \"function\") return;\n // WAAPI stays outside React renders; visibility changes cancel the loop and\n // expose its static composition rather than scheduling invisible frames.\n let animation: Animation | undefined;\n let failed = false;\n const sync = () => { animation?.cancel(); if (document.hidden || failed) return;\n // A host may expose WAAPI but reject animation creation. Keep the static SVG\n // and content instead of propagating a decorative failure to the application.\n try { animation = node.animate([\n { transform: \"scale(1.08) translate(-1%, 0%)\" },\n { transform: \"scale(1.12) translate(1%, 1%)\" },\n { transform: \"scale(1.08) translate(-1%, 0%)\" },\n ], { duration: effect.period * 1000, iterations: Infinity, easing: \"ease-in-out\" }); } catch { failed = true; } };\n sync(); document.addEventListener(\"visibilitychange\", sync);\n return () => { animation?.cancel(); document.removeEventListener(\"visibilitychange\", sync); };\n }, [hasAtmosphere, effect.active, effect.period, environment.reducedMotion, visible]);\n const colors = effect.colors.map(color => resolveColorReference(color, palette));\n return <div ref={host} className={className} data-hjm-effect-surface=\"\" style={{ ...layoutStyle, position: \"relative\", isolation: \"isolate\", overflow: \"hidden\", background: palette.theme.bg }}>\n <svg ref={layer} aria-hidden=\"true\" focusable=\"false\" style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\", pointerEvents: \"none\", opacity: effect.intensity }}>\n {/* Keep noise in CSS-pixel units; the existing geometric layers retain their viewBox. */}\n <defs>{effect.noise && <><pattern id={`${id}-noise-tile`} width={effect.noise.size} height={effect.noise.size} x={effect.noise.offset} patternUnits=\"userSpaceOnUse\"><image href={effect.noise.uri} width={effect.noise.size} height={effect.noise.size} /></pattern><mask id={`${id}-noise-mask`} x={0} y={0} width=\"100%\" height=\"100%\" maskUnits=\"userSpaceOnUse\"><rect width=\"100%\" height=\"100%\" fill={`url(#${id}-noise-tile)`} /></mask></>}</defs>\n {effect.noise && <rect width=\"100%\" height=\"100%\" fill={palette.theme.text} mask={`url(#${id}-noise-mask)`} />}\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\">\n <defs>{colors.map((color, index) => <radialGradient id={`${id}-${index}`} key={index}><stop offset=\"0%\" stopColor={color} /><stop offset=\"100%\" stopColor={color} stopOpacity={0} /></radialGradient>)}\n <pattern id={`${id}-grain`} width={4} height={4} patternUnits=\"userSpaceOnUse\">{effect.points.map((point, index) => <circle key={index} cx={point.x / 25} cy={point.y / 25} r={point.radius / 10} fill={palette.theme.text} opacity={0.28} />)}</pattern>\n </defs>\n {effect.layers.includes(\"mesh\") && effect.anchors.map((anchor, index) => <ellipse key={index} cx={anchor.x} cy={anchor.y} rx={65} ry={70} fill={`url(#${id}-${index})`} />)}\n {effect.layers.includes(\"glow\") && <ellipse cx={50} cy={10} rx={70} ry={95} fill={`url(#${id}-0)`} />}\n {effect.layers.includes(\"grain\") && <rect width={100} height={100} fill={`url(#${id}-grain)`} />}\n </svg>\n </svg>\n {/* Notebook ruling must not stretch or drift with the atmospheric layers. */}\n {effect.ruled && <svg data-hjm-effect-layer=\"ruled\" aria-hidden=\"true\" focusable=\"false\" style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\", pointerEvents: \"none\", opacity: effect.intensity }}>\n <defs><pattern id={`${id}-ruled`} width={1} height={effect.ruled.spacing} patternUnits=\"userSpaceOnUse\"><rect y={effect.ruled.spacing - effect.ruled.thickness} width=\"100%\" height={effect.ruled.thickness} fill={palette.theme.text} /></pattern></defs>\n <rect width=\"100%\" height=\"100%\" fill={`url(#${id}-ruled)`} />\n </svg>}\n <div style={{ position: \"relative\" }}>{children}</div>\n </div>;\n}\n"]}
@@ -34,7 +34,7 @@ export type ReactRendererEvidenceManifest = Readonly<{
34
34
  export declare const reactRendererEvidence: {
35
35
  readonly schemaVersion: 2;
36
36
  readonly packageName: "@hjmds/react";
37
- readonly packageVersion: "1.14.0";
37
+ readonly packageVersion: "1.16.0";
38
38
  readonly surface: "web";
39
39
  readonly components: readonly [Readonly<{
40
40
  /** Canonical component id from the design-contracts catalog. */
package/dist/evidence.js CHANGED
@@ -155,7 +155,7 @@ function toastClaim() {
155
155
  export const reactRendererEvidence = {
156
156
  schemaVersion: reactRendererEvidenceSchemaVersion,
157
157
  packageName: "@hjmds/react",
158
- packageVersion: "1.14.0",
158
+ packageVersion: "1.16.0",
159
159
  surface: "web",
160
160
  components: [
161
161
  defaultClaim("top-bar", ["TopBar"], "./top-bar"),