@hjmds/react 1.30.0 → 1.32.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 (102) hide show
  1. package/dist/auth-screen.d.ts +18 -3
  2. package/dist/auth-screen.d.ts.map +1 -1
  3. package/dist/auth-screen.js +22 -6
  4. package/dist/auth-screen.js.map +1 -1
  5. package/dist/bottom-cta.d.ts +6 -1
  6. package/dist/bottom-cta.d.ts.map +1 -1
  7. package/dist/bottom-cta.js +1 -1
  8. package/dist/bottom-cta.js.map +1 -1
  9. package/dist/bottom-navigation.d.ts +10 -0
  10. package/dist/bottom-navigation.d.ts.map +1 -1
  11. package/dist/bottom-navigation.js +80 -8
  12. package/dist/bottom-navigation.js.map +1 -1
  13. package/dist/carousel.d.ts +29 -1
  14. package/dist/carousel.d.ts.map +1 -1
  15. package/dist/carousel.js +27 -3
  16. package/dist/carousel.js.map +1 -1
  17. package/dist/display.d.ts +8 -2
  18. package/dist/display.d.ts.map +1 -1
  19. package/dist/display.js +12 -7
  20. package/dist/display.js.map +1 -1
  21. package/dist/evidence.d.ts +1 -1
  22. package/dist/evidence.js +1 -1
  23. package/dist/evidence.js.map +1 -1
  24. package/dist/forms.d.ts.map +1 -1
  25. package/dist/forms.js +2 -1
  26. package/dist/forms.js.map +1 -1
  27. package/dist/image-choice.d.ts +20 -2
  28. package/dist/image-choice.d.ts.map +1 -1
  29. package/dist/image-choice.js +60 -7
  30. package/dist/image-choice.js.map +1 -1
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal/field-error.d.ts +19 -0
  36. package/dist/internal/field-error.d.ts.map +1 -0
  37. package/dist/internal/field-error.js +19 -0
  38. package/dist/internal/field-error.js.map +1 -0
  39. package/dist/internal/initial-focus.d.ts.map +1 -1
  40. package/dist/internal/initial-focus.js +49 -7
  41. package/dist/internal/initial-focus.js.map +1 -1
  42. package/dist/internal/media-album.d.ts +70 -0
  43. package/dist/internal/media-album.d.ts.map +1 -0
  44. package/dist/internal/media-album.js +52 -0
  45. package/dist/internal/media-album.js.map +1 -0
  46. package/dist/internal/message-reactions.d.ts +39 -2
  47. package/dist/internal/message-reactions.d.ts.map +1 -1
  48. package/dist/internal/message-reactions.js +31 -6
  49. package/dist/internal/message-reactions.js.map +1 -1
  50. package/dist/layout.d.ts +19 -3
  51. package/dist/layout.d.ts.map +1 -1
  52. package/dist/layout.js +10 -3
  53. package/dist/layout.js.map +1 -1
  54. package/dist/navigation.d.ts +3 -1
  55. package/dist/navigation.d.ts.map +1 -1
  56. package/dist/navigation.js +4 -2
  57. package/dist/navigation.js.map +1 -1
  58. package/dist/number-field.d.ts.map +1 -1
  59. package/dist/number-field.js +2 -1
  60. package/dist/number-field.js.map +1 -1
  61. package/dist/overlays.d.ts +65 -0
  62. package/dist/overlays.d.ts.map +1 -1
  63. package/dist/overlays.js +36 -3
  64. package/dist/overlays.js.map +1 -1
  65. package/dist/pagination.d.ts +13 -11
  66. package/dist/pagination.d.ts.map +1 -1
  67. package/dist/pagination.js +12 -5
  68. package/dist/pagination.js.map +1 -1
  69. package/dist/public-exports.generated.d.ts +8 -0
  70. package/dist/public-exports.generated.d.ts.map +1 -1
  71. package/dist/public-exports.generated.js +24 -0
  72. package/dist/public-exports.generated.js.map +1 -1
  73. package/dist/screen-flows.d.ts +118 -14
  74. package/dist/screen-flows.d.ts.map +1 -1
  75. package/dist/screen-flows.js +95 -23
  76. package/dist/screen-flows.js.map +1 -1
  77. package/dist/screens.d.ts +69 -10
  78. package/dist/screens.d.ts.map +1 -1
  79. package/dist/screens.js +77 -15
  80. package/dist/screens.js.map +1 -1
  81. package/dist/select.d.ts.map +1 -1
  82. package/dist/select.js +2 -1
  83. package/dist/select.js.map +1 -1
  84. package/dist/selection.d.ts.map +1 -1
  85. package/dist/selection.js +3 -2
  86. package/dist/selection.js.map +1 -1
  87. package/dist/steps.d.ts +11 -1
  88. package/dist/steps.d.ts.map +1 -1
  89. package/dist/steps.js +11 -6
  90. package/dist/steps.js.map +1 -1
  91. package/dist/styles.css +181 -22
  92. package/dist/styles.layered.css +181 -22
  93. package/dist/supplemental-display.d.ts.map +1 -1
  94. package/dist/supplemental-display.js +2 -48
  95. package/dist/supplemental-display.js.map +1 -1
  96. package/dist/theme.d.ts.map +1 -1
  97. package/dist/theme.js +1 -0
  98. package/dist/theme.js.map +1 -1
  99. package/dist/toast.d.ts.map +1 -1
  100. package/dist/toast.js +1 -1
  101. package/dist/toast.js.map +1 -1
  102. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"bottom-navigation.js","sourceRoot":"","sources":["../src/bottom-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n resolveBottomNavigationActivation,\n resolveBottomNavigationConfiguration,\n resolveBottomNavigationDescriptor,\n type BottomNavigationActivation,\n type BottomNavigationConfiguration,\n type BottomNavigationDescriptor,\n type ResolvedBottomNavigationItemDescriptor,\n} from \"@hjmds/design-contracts/components/bottom-navigation\";\nimport {\n bottomNavigationRecipe,\n iconRecipe,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useEffect,\n useState,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type ForwardedRef,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\n\nconst virtualKeyboardMinimumOcclusion = 120;\n\nexport type BottomNavigationIconRenderProps<\n Key extends string = string,\n IconName extends string = string,\n> = Readonly<{\n item: ResolvedBottomNavigationItemDescriptor<Key, IconName>;\n name: IconName;\n selected: boolean;\n color: \"currentColor\";\n size: number;\n strokeWidth: number;\n scale: number;\n}>;\n\nexport type BottomNavigationLinkRenderProps = AnchorHTMLAttributes<HTMLAnchorElement> &\n Readonly<{\n href: string;\n children: ReactNode;\n \"data-state\": \"idle\" | \"selected\";\n }>;\n\nexport type BottomNavigationProps<\n Key extends string = string,\n IconName extends string = string,\n> = Omit<\n HTMLAttributes<HTMLElement>,\n \"aria-label\" | \"aria-labelledby\" | \"children\" | \"dir\" | \"onChange\" | \"role\"\n> &\n Readonly<{\n descriptor: BottomNavigationDescriptor<Key, IconName>;\n configuration?: BottomNavigationConfiguration;\n getHref: (item: ResolvedBottomNavigationItemDescriptor<Key, IconName>) => string;\n renderIcon: (props: BottomNavigationIconRenderProps<Key, IconName>) => ReactNode;\n /** Framework navigation adapter, for example Next.js Link. */\n renderLink?: (props: BottomNavigationLinkRenderProps) => ReactElement;\n primaryAction?: ReactNode;\n onActivate?: (activation: BottomNavigationActivation<Key>) => void;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport function isUnmodifiedPrimaryBottomNavigationClick(\n event: Pick<\n MouseEvent<HTMLAnchorElement>,\n \"altKey\" | \"button\" | \"ctrlKey\" | \"defaultPrevented\" | \"metaKey\" | \"shiftKey\"\n >,\n): boolean {\n return (\n !event.defaultPrevented &&\n event.button === 0 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.shiftKey &&\n !event.altKey\n );\n}\n\nexport function shouldHideBottomNavigationForKeyboard(input: Readonly<{\n behavior: \"hide\" | \"remain\";\n layoutViewportHeight: number;\n visualViewportHeight: number;\n visualViewportOffsetTop?: number;\n visualViewportScale?: number;\n}>): boolean {\n if (input.behavior !== \"hide\") return false;\n if ((input.visualViewportScale ?? 1) !== 1) return false;\n const visibleBottom =\n input.visualViewportHeight + (input.visualViewportOffsetTop ?? 0);\n return layoutViewportHeightIsValid(input.layoutViewportHeight) &&\n input.layoutViewportHeight - visibleBottom >= virtualKeyboardMinimumOcclusion;\n}\n\nfunction layoutViewportHeightIsValid(value: number): boolean {\n return Number.isFinite(value) && value >= 0;\n}\n\nexport function getBottomNavigationGridColumn(\n index: number,\n itemCount: number,\n distribution: \"equal\" | \"center-gap\",\n): number | undefined {\n if (distribution !== \"center-gap\") return undefined;\n const middle = itemCount / 2;\n return index < middle ? index + 1 : index + 2;\n}\n\nfunction useKeyboardHidden(behavior: \"hide\" | \"remain\"): boolean {\n const [hidden, setHidden] = useState(false);\n useEffect(() => {\n const viewport = window.visualViewport;\n if (!viewport) return;\n const update = () => {\n setHidden(\n shouldHideBottomNavigationForKeyboard({\n behavior,\n layoutViewportHeight: window.innerHeight,\n visualViewportHeight: viewport.height,\n visualViewportOffsetTop: viewport.offsetTop,\n visualViewportScale: viewport.scale,\n }),\n );\n };\n update();\n viewport.addEventListener(\"resize\", update);\n viewport.addEventListener(\"scroll\", update);\n return () => {\n viewport.removeEventListener(\"resize\", update);\n viewport.removeEventListener(\"scroll\", update);\n };\n }, [behavior]);\n return hidden;\n}\n\nfunction BottomNavigationInner<\n Key extends string = string,\n IconName extends string = string,\n>(\n {\n descriptor,\n configuration = {},\n getHref,\n renderIcon,\n renderLink,\n primaryAction,\n onActivate,\n className,\n style,\n layoutStyle,\n ...props\n }: BottomNavigationProps<Key, IconName>,\n ref: ForwardedRef<HTMLElement>,\n) {\n const resolved = resolveBottomNavigationDescriptor(descriptor);\n const theme = useOptionalHjmTheme();\n const direction = configuration.direction ?? theme?.environment.direction;\n const presentation = resolveBottomNavigationConfiguration(\n {\n ...configuration,\n ...(direction === undefined ? {} : { direction }),\n },\n resolved.items.length,\n );\n const hidden = useKeyboardHidden(presentation.keyboardBehavior);\n const density = bottomNavigationRecipe.density[presentation.density];\n const presentationRecipe =\n bottomNavigationRecipe.presentations[presentation.presentation];\n const centerGap =\n bottomNavigationRecipe.distributions[presentation.distribution].centerGap;\n const iconSize = iconRecipe.sizes[density.icon];\n\n if (hidden) return null;\n\n return (\n <nav\n {...props}\n ref={ref}\n aria-label={resolved.accessibilityLabel}\n className={classNames(\"hjm-bottom-navigation\", className)}\n data-expanded-labels={(theme?.environment.textScale ?? 1) >= 1.5 || resolved.items.length > 4 ? \"true\" : \"false\"}\n data-density={presentation.density}\n data-distribution={presentation.distribution}\n data-keyboard-behavior={presentation.keyboardBehavior}\n data-labels={presentation.labels}\n data-selection={presentation.selection}\n data-surface={presentation.surface}\n data-presentation={presentation.presentation}\n dir={presentation.direction}\n style={{\n \"--hjm-bottom-navigation-center-gap\": `${centerGap}px`,\n \"--hjm-bottom-navigation-columns\": resolved.items.length,\n \"--hjm-bottom-navigation-half-columns\": resolved.items.length / 2,\n \"--hjm-bottom-navigation-item-gap\": `${density.gap}px`,\n \"--hjm-bottom-navigation-item-min-height\": `${density.itemMinHeight}px`,\n \"--hjm-bottom-navigation-item-min-width\": `${density.itemMinWidth}px`,\n \"--hjm-bottom-navigation-item-padding\": `${density.padding}px`,\n \"--hjm-bottom-navigation-max-width\": presentationRecipe.maxWidth\n ? `${presentationRecipe.maxWidth}px`\n : \"none\",\n \"--hjm-bottom-navigation-content-max-width\": presentationRecipe.contentMaxWidth\n ? `${presentationRecipe.contentMaxWidth}px`\n : \"none\",\n \"--hjm-bottom-navigation-outer-inline\": `${presentationRecipe.outerPaddingHorizontal}px`,\n \"--hjm-bottom-navigation-outer-top\": `${presentationRecipe.outerPaddingTop}px`,\n ...style,\n ...layoutStyle,\n } as CSSProperties}\n >\n <div className=\"hjm-bottom-navigation__surface\">\n <ul className=\"hjm-bottom-navigation__list\">\n {resolved.items.map((item, index) => {\n const selected = item.id === resolved.selectedKey;\n const content = (\n <>\n <span\n aria-hidden=\"true\"\n className=\"hjm-bottom-navigation__indicator\"\n data-state={selected ? \"selected\" : \"idle\"}\n >\n {renderIcon({\n item,\n name: item.icon.name,\n selected,\n color: \"currentColor\",\n size: iconSize,\n strokeWidth: selected\n ? bottomNavigationRecipe.icon.selectedEmphasis.strokeWidth.selected\n : bottomNavigationRecipe.icon.selectedEmphasis.strokeWidth.idle,\n scale: selected\n ? bottomNavigationRecipe.icon.selectedEmphasis.scale.selected\n : bottomNavigationRecipe.icon.selectedEmphasis.scale.idle,\n })}\n {item.badge ? (\n <span aria-hidden=\"true\" className=\"hjm-bottom-navigation__badge\">\n {item.badge.visibleLabel}\n </span>\n ) : null}\n </span>\n {/* Hidden labels are not rendered: the item link already carries\n resolvedAccessibilityLabel, so a visually-hidden copy would only duplicate it. */}\n {presentation.labels === \"visible\" ? (\n <span className=\"hjm-bottom-navigation__label\">{item.label}</span>\n ) : null}\n </>\n );\n const itemStyle = {\n gridColumn: getBottomNavigationGridColumn(\n index,\n resolved.items.length,\n presentation.distribution,\n ),\n };\n if (item.disabled) {\n return (\n <li key={item.id} style={itemStyle} data-selected=\"false\">\n <span\n aria-disabled=\"true\"\n aria-label={item.resolvedAccessibilityLabel}\n className=\"hjm-bottom-navigation__item\"\n data-state=\"disabled\"\n role=\"link\"\n >\n {content}\n </span>\n </li>\n );\n }\n const href = getHref(item);\n if (!href.trim()) {\n throw new TypeError(`BottomNavigation href must not be empty: ${item.id}`);\n }\n const linkProps: BottomNavigationLinkRenderProps = {\n \"aria-current\": selected ? \"page\" : undefined,\n \"aria-label\": item.resolvedAccessibilityLabel,\n className: \"hjm-bottom-navigation__item\",\n \"data-state\": selected ? \"selected\" : \"idle\",\n href,\n onClick: (event) => {\n if (!isUnmodifiedPrimaryBottomNavigationClick(event)) return;\n const activation = resolveBottomNavigationActivation(descriptor, item.id);\n if (activation) onActivate?.(activation);\n },\n children: content,\n };\n return (\n <li key={item.id} style={itemStyle} data-selected={selected}>\n {renderLink ? renderLink(linkProps) : <a {...linkProps} />}\n </li>\n );\n })}\n </ul>\n {primaryAction ? (\n <div className=\"hjm-bottom-navigation__primary-action\">{primaryAction}</div>\n ) : null}\n </div>\n </nav>\n );\n}\n\nexport const BottomNavigation = forwardRef(BottomNavigationInner) as <\n Key extends string = string,\n IconName extends string = string,\n>(\n props: BottomNavigationProps<Key, IconName> & RefAttributes<HTMLElement>,\n) => ReactElement | null;\n"]}
1
+ {"version":3,"file":"bottom-navigation.js","sourceRoot":"","sources":["../src/bottom-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n resolveBottomNavigationActivation,\n resolveBottomNavigationConfiguration,\n resolveBottomNavigationDescriptor,\n validateBottomNavigationProminence,\n type BottomNavigationActivation,\n type BottomNavigationConfiguration,\n type BottomNavigationDescriptor,\n type ResolvedBottomNavigationItemDescriptor,\n} from \"@hjmds/design-contracts/components/bottom-navigation\";\nimport {\n bottomNavigationRecipe,\n iconRecipe,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type ForwardedRef,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\nimport { assignRef, classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\n\nconst virtualKeyboardMinimumOcclusion = 120;\n\n/**\n * Height of the viewport bottom covered by the fixed bar (safe area and a raised center circle included); 0 when\n * there is no bar or it is hidden for the keyboard. The provider also exposes it as `--hjm-bottom-navigation-inset`,\n * which ScreenLayout's last region adds to its bottom padding, so products stop hand-keeping a bottom spacer\n * (2026-10-18; Native shares the same API for its `placement=\"overlay\"` bar).\n */\nconst BottomNavigationInsetContext = createContext(0);\nconst BottomNavigationInsetReporterContext = createContext<((height: number) => void) | null>(null);\n\nexport type BottomNavigationInsetProviderProps = Readonly<{ children: ReactNode }>;\n\n/** Wrap the app shell that holds both the screens and the BottomNavigation. */\nexport function BottomNavigationInsetProvider({ children }: BottomNavigationInsetProviderProps) {\n const [inset, setInset] = useState(0);\n const report = useMemo(() => (height: number) => {\n const next = Number.isFinite(height) && height > 0 ? height : 0;\n setInset(current => current === next ? current : next);\n }, []);\n return (\n <BottomNavigationInsetReporterContext.Provider value={report}>\n <BottomNavigationInsetContext.Provider value={inset}>\n {/* `display: contents` adds no box; the custom property still inherits to every screen below. */}\n <div style={{ display: \"contents\", \"--hjm-bottom-navigation-inset\": `${inset}px` } as CSSProperties}>{children}</div>\n </BottomNavigationInsetContext.Provider>\n </BottomNavigationInsetReporterContext.Provider>\n );\n}\n\n/**\n * Bottom height covered by the BottomNavigation inside the nearest provider; 0 outside one. For layouts that are not\n * a ScreenLayout: inside one the shell already pads by it, so adding it again doubles the space.\n */\nexport function useBottomNavigationInset(): number {\n return useContext(BottomNavigationInsetContext);\n}\n\nexport type BottomNavigationIconRenderProps<\n Key extends string = string,\n IconName extends string = string,\n> = Readonly<{\n item: ResolvedBottomNavigationItemDescriptor<Key, IconName>;\n name: IconName;\n selected: boolean;\n color: \"currentColor\";\n size: number;\n strokeWidth: number;\n scale: number;\n}>;\n\nexport type BottomNavigationLinkRenderProps = AnchorHTMLAttributes<HTMLAnchorElement> &\n Readonly<{\n href: string;\n children: ReactNode;\n \"data-state\": \"idle\" | \"selected\";\n }>;\n\nexport type BottomNavigationProps<\n Key extends string = string,\n IconName extends string = string,\n> = Omit<\n HTMLAttributes<HTMLElement>,\n \"aria-label\" | \"aria-labelledby\" | \"children\" | \"dir\" | \"onChange\" | \"role\"\n> &\n Readonly<{\n descriptor: BottomNavigationDescriptor<Key, IconName>;\n configuration?: BottomNavigationConfiguration;\n getHref: (item: ResolvedBottomNavigationItemDescriptor<Key, IconName>) => string;\n renderIcon: (props: BottomNavigationIconRenderProps<Key, IconName>) => ReactNode;\n /** Framework navigation adapter, for example Next.js Link. */\n renderLink?: (props: BottomNavigationLinkRenderProps) => ReactElement;\n primaryAction?: ReactNode;\n onActivate?: (activation: BottomNavigationActivation<Key>) => void;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport function isUnmodifiedPrimaryBottomNavigationClick(\n event: Pick<\n MouseEvent<HTMLAnchorElement>,\n \"altKey\" | \"button\" | \"ctrlKey\" | \"defaultPrevented\" | \"metaKey\" | \"shiftKey\"\n >,\n): boolean {\n return (\n !event.defaultPrevented &&\n event.button === 0 &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.shiftKey &&\n !event.altKey\n );\n}\n\nexport function shouldHideBottomNavigationForKeyboard(input: Readonly<{\n behavior: \"hide\" | \"remain\";\n layoutViewportHeight: number;\n visualViewportHeight: number;\n visualViewportOffsetTop?: number;\n visualViewportScale?: number;\n}>): boolean {\n if (input.behavior !== \"hide\") return false;\n if ((input.visualViewportScale ?? 1) !== 1) return false;\n const visibleBottom =\n input.visualViewportHeight + (input.visualViewportOffsetTop ?? 0);\n return layoutViewportHeightIsValid(input.layoutViewportHeight) &&\n input.layoutViewportHeight - visibleBottom >= virtualKeyboardMinimumOcclusion;\n}\n\nfunction layoutViewportHeightIsValid(value: number): boolean {\n return Number.isFinite(value) && value >= 0;\n}\n\nexport function getBottomNavigationGridColumn(\n index: number,\n itemCount: number,\n distribution: \"equal\" | \"center-gap\",\n): number | undefined {\n if (distribution !== \"center-gap\") return undefined;\n const middle = itemCount / 2;\n return index < middle ? index + 1 : index + 2;\n}\n\nfunction useKeyboardHidden(behavior: \"hide\" | \"remain\"): boolean {\n const [hidden, setHidden] = useState(false);\n useEffect(() => {\n const viewport = window.visualViewport;\n if (!viewport) return;\n const update = () => {\n setHidden(\n shouldHideBottomNavigationForKeyboard({\n behavior,\n layoutViewportHeight: window.innerHeight,\n visualViewportHeight: viewport.height,\n visualViewportOffsetTop: viewport.offsetTop,\n visualViewportScale: viewport.scale,\n }),\n );\n };\n update();\n viewport.addEventListener(\"resize\", update);\n viewport.addEventListener(\"scroll\", update);\n return () => {\n viewport.removeEventListener(\"resize\", update);\n viewport.removeEventListener(\"scroll\", update);\n };\n }, [behavior]);\n return hidden;\n}\n\nfunction BottomNavigationInner<\n Key extends string = string,\n IconName extends string = string,\n>(\n {\n descriptor,\n configuration = {},\n getHref,\n renderIcon,\n renderLink,\n primaryAction,\n onActivate,\n className,\n style,\n layoutStyle,\n ...props\n }: BottomNavigationProps<Key, IconName>,\n ref: ForwardedRef<HTMLElement>,\n) {\n const resolved = resolveBottomNavigationDescriptor(descriptor);\n const theme = useOptionalHjmTheme();\n const direction = configuration.direction ?? theme?.environment.direction;\n const presentation = resolveBottomNavigationConfiguration(\n {\n ...configuration,\n ...(direction === undefined ? {} : { direction }),\n },\n resolved.items.length,\n );\n validateBottomNavigationProminence(resolved.items, presentation);\n const hidden = useKeyboardHidden(presentation.keyboardBehavior);\n const density = bottomNavigationRecipe.density[presentation.density];\n const presentationRecipe =\n bottomNavigationRecipe.presentations[presentation.presentation];\n const centerGap =\n bottomNavigationRecipe.distributions[presentation.distribution].centerGap;\n const iconSize = presentation.iconSize === \"standard\"\n ? iconRecipe.sizes[density.icon]\n : bottomNavigationRecipe.iconSizes[presentation.iconSize];\n // `shape` reframes the floating surface (radius + inner padding); `standard` keeps the presentation recipe.\n const shapeRecipe = presentation.shape === \"standard\"\n ? null\n : bottomNavigationRecipe.shapes[presentation.shape];\n const liftRecipe = bottomNavigationRecipe.icon.liftEmphasis;\n const prominentRecipe = bottomNavigationRecipe.prominentDestination;\n // Lifting by (diameter - indicator height) keeps the prominent label on the other labels' line; an app-icon\n // slot taller than the indicator minimum raises that height.\n const prominentLift = prominentRecipe.diameter - Math.max(bottomNavigationRecipe.indicator.minHeight, iconSize);\n // The part of the circle above the nav box still covers content, so the reported inset includes it.\n const prominentOverflow = resolved.items.some((item) => item.prominent)\n ? Math.max(0, prominentLift - density.padding - presentationRecipe.outerPaddingTop)\n : 0;\n const navRef = useRef<HTMLElement | null>(null);\n const reportInset = useContext(BottomNavigationInsetReporterContext);\n useEffect(() => {\n const nav = navRef.current;\n if (!reportInset) return;\n if (hidden || !nav) {\n reportInset(0);\n return;\n }\n const update = () => reportInset(nav.getBoundingClientRect().height + prominentOverflow);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(nav);\n return () => {\n observer.disconnect();\n reportInset(0);\n };\n }, [reportInset, hidden, prominentOverflow]);\n\n if (hidden) return null;\n\n return (\n <nav\n {...props}\n ref={(node) => {\n navRef.current = node;\n assignRef(ref, node);\n }}\n aria-label={resolved.accessibilityLabel}\n className={classNames(\"hjm-bottom-navigation\", className)}\n data-expanded-labels={(theme?.environment.textScale ?? 1) >= 1.5 || resolved.items.length > 4 ? \"true\" : \"false\"}\n data-density={presentation.density}\n data-distribution={presentation.distribution}\n data-keyboard-behavior={presentation.keyboardBehavior}\n data-labels={presentation.labels}\n data-selection={presentation.selection}\n data-surface={presentation.surface}\n data-presentation={presentation.presentation}\n data-shape={presentation.shape}\n data-icon-emphasis={presentation.iconEmphasis}\n dir={presentation.direction}\n style={{\n \"--hjm-bottom-navigation-center-gap\": `${centerGap}px`,\n \"--hjm-bottom-navigation-columns\": resolved.items.length,\n \"--hjm-bottom-navigation-half-columns\": resolved.items.length / 2,\n \"--hjm-bottom-navigation-item-gap\": `${density.gap}px`,\n \"--hjm-bottom-navigation-item-min-height\": `${density.itemMinHeight}px`,\n \"--hjm-bottom-navigation-item-min-width\": `${density.itemMinWidth}px`,\n \"--hjm-bottom-navigation-item-padding\": `${density.padding}px`,\n \"--hjm-bottom-navigation-max-width\": presentationRecipe.maxWidth\n ? `${presentationRecipe.maxWidth}px`\n : \"none\",\n \"--hjm-bottom-navigation-content-max-width\": presentationRecipe.contentMaxWidth\n ? `${presentationRecipe.contentMaxWidth}px`\n : \"none\",\n \"--hjm-bottom-navigation-outer-inline\": `${presentationRecipe.outerPaddingHorizontal}px`,\n \"--hjm-bottom-navigation-outer-top\": `${presentationRecipe.outerPaddingTop}px`,\n \"--hjm-bottom-navigation-prominent-diameter\": `${prominentRecipe.diameter}px`,\n \"--hjm-bottom-navigation-prominent-lift\": `${prominentLift}px`,\n ...(shapeRecipe ? {\n \"--hjm-bottom-navigation-shape-radius\": `var(--hjm-radius-${shapeRecipe.radius})`,\n \"--hjm-bottom-navigation-shape-padding\": `${shapeRecipe.surfacePadding}px`,\n } : {}),\n ...(presentation.iconEmphasis === \"lift\" ? {\n \"--hjm-bottom-navigation-lift-offset\": `${liftRecipe.translateY}px`,\n \"--hjm-bottom-navigation-lift-idle-opacity\": liftRecipe.idleOpacity,\n } : {}),\n ...style,\n ...layoutStyle,\n } as CSSProperties}\n >\n <div className=\"hjm-bottom-navigation__surface\">\n <ul className=\"hjm-bottom-navigation__list\">\n {resolved.items.map((item, index) => {\n const selected = item.id === resolved.selectedKey;\n const content = (\n <>\n <span\n aria-hidden=\"true\"\n className=\"hjm-bottom-navigation__indicator\"\n data-state={selected ? \"selected\" : \"idle\"}\n >\n {renderIcon({\n item,\n name: item.icon.name,\n selected,\n color: \"currentColor\",\n size: item.prominent ? iconRecipe.sizes[prominentRecipe.icon] : iconSize,\n strokeWidth: selected\n ? bottomNavigationRecipe.icon.selectedEmphasis.strokeWidth.selected\n : bottomNavigationRecipe.icon.selectedEmphasis.strokeWidth.idle,\n scale: selected\n ? bottomNavigationRecipe.icon.selectedEmphasis.scale.selected\n : bottomNavigationRecipe.icon.selectedEmphasis.scale.idle,\n })}\n {item.badge ? (\n <span aria-hidden=\"true\" className=\"hjm-bottom-navigation__badge\">\n {item.badge.visibleLabel}\n </span>\n ) : null}\n </span>\n {/* Hidden labels are not rendered: the item link already carries\n resolvedAccessibilityLabel, so a visually-hidden copy would only duplicate it. */}\n {presentation.labels === \"visible\" ? (\n <span className=\"hjm-bottom-navigation__label\">{item.label}</span>\n ) : null}\n </>\n );\n const itemStyle = {\n gridColumn: getBottomNavigationGridColumn(\n index,\n resolved.items.length,\n presentation.distribution,\n ),\n };\n if (item.disabled) {\n return (\n <li key={item.id} style={itemStyle} data-selected=\"false\" data-prominent={item.prominent || undefined}>\n <span\n aria-disabled=\"true\"\n aria-label={item.resolvedAccessibilityLabel}\n className=\"hjm-bottom-navigation__item\"\n data-state=\"disabled\"\n role=\"link\"\n >\n {content}\n </span>\n </li>\n );\n }\n const href = getHref(item);\n if (!href.trim()) {\n throw new TypeError(`BottomNavigation href must not be empty: ${item.id}`);\n }\n const linkProps: BottomNavigationLinkRenderProps = {\n \"aria-current\": selected ? \"page\" : undefined,\n \"aria-label\": item.resolvedAccessibilityLabel,\n className: \"hjm-bottom-navigation__item\",\n \"data-state\": selected ? \"selected\" : \"idle\",\n href,\n onClick: (event) => {\n if (!isUnmodifiedPrimaryBottomNavigationClick(event)) return;\n const activation = resolveBottomNavigationActivation(descriptor, item.id);\n if (activation) onActivate?.(activation);\n },\n children: content,\n };\n return (\n <li key={item.id} style={itemStyle} data-selected={selected} data-prominent={item.prominent || undefined}>\n {renderLink ? renderLink(linkProps) : <a {...linkProps} />}\n </li>\n );\n })}\n </ul>\n {primaryAction ? (\n <div className=\"hjm-bottom-navigation__primary-action\">{primaryAction}</div>\n ) : null}\n </div>\n </nav>\n );\n}\n\nexport const BottomNavigation = forwardRef(BottomNavigationInner) as <\n Key extends string = string,\n IconName extends string = string,\n>(\n props: BottomNavigationProps<Key, IconName> & RefAttributes<HTMLElement>,\n) => ReactElement | null;\n"]}
@@ -1,5 +1,5 @@
1
1
  import { type HTMLAttributes, type ReactNode } from "react";
2
- import { type CarouselSlideDescriptor, type CarouselSelection, type CarouselAutoplayConfig, type ComposeCarouselAccessibleName } from "@hjmds/design-contracts/components/carousel";
2
+ import { type CarouselSlideDescriptor, type CarouselSelection, type CarouselAutoplayConfig, type ComposeCarouselAccessibleName, type ComposePageIndicatorAccessibleName } from "@hjmds/design-contracts/components/carousel";
3
3
  import type { HjmCompositionStyleProp } from "./composition-style.js";
4
4
  export type CarouselLabels = Readonly<{
5
5
  previous: string;
@@ -18,6 +18,34 @@ export type CarouselProps = Omit<HTMLAttributes<HTMLDivElement>, "children" | "o
18
18
  /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
19
19
  layoutStyle?: HjmCompositionStyleProp;
20
20
  }>;
21
+ export type PageIndicatorProps = Omit<HTMLAttributes<HTMLDivElement>, "children" | "onChange"> & Readonly<{
22
+ /** Name of the paged region (e.g. "Home pages"); the group's accessible name. */
23
+ label: string;
24
+ count: number;
25
+ /** Zero-based current page; the product pager owns it. */
26
+ currentIndex: number;
27
+ /** Requested page from a dot or an arrow key. It can repeat the current index. */
28
+ onCurrentIndexChange: (index: number) => void;
29
+ composeAccessibleName: ComposePageIndicatorAccessibleName;
30
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
31
+ layoutStyle?: HjmCompositionStyleProp;
32
+ }>;
33
+ /**
34
+ * Carousel's position dots for a product-owned pager (scroll-snap row, virtualized pager). Arrow keys on a dot move
35
+ * one page in reading direction, as in Carousel's controls.
36
+ */
37
+ export declare const PageIndicator: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "children"> & Readonly<{
38
+ /** Name of the paged region (e.g. "Home pages"); the group's accessible name. */
39
+ label: string;
40
+ count: number;
41
+ /** Zero-based current page; the product pager owns it. */
42
+ currentIndex: number;
43
+ /** Requested page from a dot or an arrow key. It can repeat the current index. */
44
+ onCurrentIndexChange: (index: number) => void;
45
+ composeAccessibleName: ComposePageIndicatorAccessibleName;
46
+ /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
47
+ layoutStyle?: HjmCompositionStyleProp;
48
+ }> & import("react").RefAttributes<HTMLDivElement>>;
21
49
  /** Finite keyed cards. Hidden slides stay mounted but cannot receive focus. */
22
50
  export declare const Carousel: import("react").ForwardRefExoticComponent<CarouselProps & import("react").RefAttributes<HTMLDivElement>>;
23
51
  //# sourceMappingURL=carousel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../src/carousel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACtH,OAAO,EAEL,KAAK,uBAAuB,EAAE,KAAK,iBAAiB,EAAE,KAAK,sBAAsB,EACjF,KAAK,6BAA6B,EACnC,MAAM,6CAA6C,CAAC;AAMrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC7H,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,iBAAiB,GAAG,QAAQ,CAAC;IACvH,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC3C,WAAW,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,SAAS,CAAC;IAC3D,qBAAqB,EAAE,6BAA6B,CAAC;IACrD,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,0GAmGnB,CAAC"}
1
+ {"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../src/carousel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACtH,OAAO,EAGL,KAAK,uBAAuB,EAAE,KAAK,iBAAiB,EAAE,KAAK,sBAAsB,EACjF,KAAK,6BAA6B,EAAE,KAAK,kCAAkC,EAC5E,MAAM,6CAA6C,CAAC;AAMrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC7H,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,iBAAiB,GAAG,QAAQ,CAAC;IACvH,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC3C,WAAW,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,SAAS,CAAC;IAC3D,qBAAqB,EAAE,6BAA6B,CAAC;IACrD,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG,QAAQ,CAAC;IACxG,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,qBAAqB,EAAE,kCAAkC,CAAC;IAC1D,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAeH;;;GAGG;AACH,eAAO,MAAM,aAAa;IA7BxB,iFAAiF;WAC1E,MAAM;WACN,MAAM;IACb,0DAA0D;kBAC5C,MAAM;IACpB,kFAAkF;0BAC5D,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;2BACtB,kCAAkC;IACzD,gGAAgG;kBAClF,uBAAuB;mDAuCrC,CAAC;AAEH,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,0GAmGnB,CAAC"}
package/dist/carousel.js CHANGED
@@ -1,11 +1,35 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useLayoutEffect, useRef, useState, forwardRef } from "react";
3
- import { resolveCarouselDescriptor, getCarouselNavigationTarget, isCarouselAutoplayActive, } from "@hjmds/design-contracts/components/carousel";
3
+ import { resolveCarouselDescriptor, getCarouselNavigationTarget, isCarouselAutoplayActive, resolvePageIndicator, getPageIndicatorTarget, } from "@hjmds/design-contracts/components/carousel";
4
4
  import { Button, IconButton } from "./actions.js";
5
5
  import { Icon } from "./supplemental-display.js";
6
6
  import { isLargeTextScale } from "@hjmds/design-contracts/components/design-system-provider";
7
7
  import { assignRef, classNames, useControllableState } from "./internal.js";
8
8
  import { useOptionalHjmTheme } from "./provider.js";
9
+ /** The dot buttons shared by Carousel and PageIndicator, so both rows keep one markup and one recipe. */
10
+ function PageDots({ dots, onSelect, dotClassName, keys }) {
11
+ return _jsx(_Fragment, { children: dots.map((dot) => _jsx("button", { type: "button", "aria-label": dot.accessibleName, "aria-disabled": dot.current, "data-current": dot.current, className: dotClassName, onClick: () => onSelect(dot.index), children: _jsx("span", { "aria-hidden": "true" }) }, keys?.[dot.index] ?? dot.index)) });
12
+ }
13
+ /**
14
+ * Carousel's position dots for a product-owned pager (scroll-snap row, virtualized pager). Arrow keys on a dot move
15
+ * one page in reading direction, as in Carousel's controls.
16
+ */
17
+ export const PageIndicator = forwardRef(function PageIndicator({ label, count, currentIndex, onCurrentIndexChange, composeAccessibleName, className, onKeyDown, layoutStyle, ...props }, ref) {
18
+ const theme = useOptionalHjmTheme();
19
+ if (!label.trim())
20
+ throw new TypeError("PageIndicator label must not be empty");
21
+ const descriptor = { count, currentIndex };
22
+ const dots = resolvePageIndicator(descriptor, composeAccessibleName);
23
+ return _jsx("div", { ...props, ref: ref, style: { ...props.style, ...layoutStyle }, role: "group", "aria-label": label, className: classNames("hjm-page-indicator", className), onKeyDown: (event) => {
24
+ onKeyDown?.(event);
25
+ if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey)
26
+ return;
27
+ if (event.key !== "ArrowLeft" && event.key !== "ArrowRight")
28
+ return;
29
+ event.preventDefault();
30
+ onCurrentIndexChange(getPageIndicatorTarget(descriptor, (event.key === "ArrowRight") !== (theme?.environment.direction === "rtl") ? "next" : "previous"));
31
+ }, children: _jsx(PageDots, { dots: dots, onSelect: onCurrentIndexChange, dotClassName: "hjm-page-indicator__dot" }) });
32
+ });
9
33
  /** Finite keyed cards. Hidden slides stay mounted but cannot receive focus. */
10
34
  export const Carousel = forwardRef(function Carousel({ label, slides, renderSlide, composeAccessibleName, labels, autoplay, currentKey, defaultCurrentKey, onCurrentKeyChange, className, onFocusCapture, onMouseEnter, onMouseLeave, onKeyDown, layoutStyle, ...props }, ref) {
11
35
  const theme = useOptionalHjmTheme();
@@ -84,6 +108,6 @@ export const Carousel = forwardRef(function Carousel({ label, slides, renderSlid
84
108
  if (next && last)
85
109
  setCurrent(slides[0].id);
86
110
  setRotating(next);
87
- }, children: rotationRequested ? labels.pause : labels.resume }) : null, _jsx("div", { className: "hjm-carousel__track", "aria-live": playing ? "off" : "polite", "aria-atomic": false, children: resolved.map((slide) => _jsx("div", { className: "hjm-carousel__slide", role: "group", "aria-roledescription": "slide", "aria-label": slide.accessibleName, hidden: slide.inert, inert: slide.inert, children: renderSlide(slide) }, slide.id)) }), _jsxs("div", { className: "hjm-carousel__controls", "data-carousel-controls": true, role: "group", "aria-label": labels.navigation, children: [_jsx(IconButton, { label: labels.previous, tone: "ghost", "aria-disabled": current === slides[0].id, onClick: () => move("previous"), children: _jsx(Icon, { name: "chevronStart" }) }), _jsx("div", { className: "hjm-carousel__dots", children: resolved.map((slide) => _jsx("button", { type: "button", "aria-label": slide.accessibleName, "aria-disabled": slide.current, "data-current": slide.current, className: "hjm-carousel__dot", onClick: () => select(slide.id), children: _jsx("span", { "aria-hidden": "true" }) }, slide.id)) }), _jsx(IconButton, { label: labels.next, tone: "ghost", "aria-disabled": last, onClick: () => move("next"), children: _jsx(Icon, { name: "chevronEnd" }) })] })] });
111
+ }, children: rotationRequested ? labels.pause : labels.resume }) : null, _jsx("div", { className: "hjm-carousel__track", "aria-live": playing ? "off" : "polite", "aria-atomic": false, children: resolved.map((slide) => _jsx("div", { className: "hjm-carousel__slide", role: "group", "aria-roledescription": "slide", "aria-label": slide.accessibleName, hidden: slide.inert, inert: slide.inert, children: renderSlide(slide) }, slide.id)) }), _jsxs("div", { className: "hjm-carousel__controls", "data-carousel-controls": true, role: "group", "aria-label": labels.navigation, children: [_jsx(IconButton, { label: labels.previous, tone: "ghost", "aria-disabled": current === slides[0].id, onClick: () => move("previous"), children: _jsx(Icon, { name: "chevronStart" }) }), _jsx("div", { className: "hjm-carousel__dots", children: _jsx(PageDots, { dotClassName: "hjm-carousel__dot", keys: slides.map((slide) => slide.id), onSelect: (index) => select(slides[index].id), dots: resolvePageIndicator({ count: slides.length, currentIndex: resolved.findIndex((slide) => slide.current) }, ({ position }) => resolved[position - 1].accessibleName) }) }), _jsx(IconButton, { label: labels.next, tone: "ghost", "aria-disabled": last, onClick: () => move("next"), children: _jsx(Icon, { name: "chevronEnd" }) })] })] });
88
112
  });
89
113
  //# sourceMappingURL=carousel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"carousel.js","sourceRoot":"","sources":["../src/carousel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport {\n resolveCarouselDescriptor, getCarouselNavigationTarget, isCarouselAutoplayActive,\n type CarouselSlideDescriptor, type CarouselSelection, type CarouselAutoplayConfig,\n type ComposeCarouselAccessibleName,\n} from \"@hjmds/design-contracts/components/carousel\";\nimport { Button, IconButton } from \"./actions.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport { isLargeTextScale } from \"@hjmds/design-contracts/components/design-system-provider\";\nimport { assignRef, classNames, useControllableState } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type CarouselLabels = Readonly<{ previous: string; next: string; pause: string; resume: string; navigation: string }>;\nexport type CarouselProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"onChange\"> & CarouselSelection & Readonly<{\n label: string;\n slides: readonly CarouselSlideDescriptor[];\n renderSlide: (slide: CarouselSlideDescriptor) => ReactNode;\n composeAccessibleName: ComposeCarouselAccessibleName;\n labels: CarouselLabels;\n autoplay?: CarouselAutoplayConfig;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Finite keyed cards. Hidden slides stay mounted but cannot receive focus. */\nexport const Carousel = forwardRef<HTMLDivElement, CarouselProps>(function Carousel({\n label, slides, renderSlide, composeAccessibleName, labels, autoplay,\n currentKey, defaultCurrentKey, onCurrentKeyChange, className,\n onFocusCapture, onMouseEnter, onMouseLeave, onKeyDown, layoutStyle, ...props\n}, ref) {\n const theme = useOptionalHjmTheme();\n const [storedCurrent, setCurrent] = useControllableState({\n ...(currentKey === undefined ? {} : { value: currentKey }),\n defaultValue: defaultCurrentKey ?? slides[0]?.id ?? \"\",\n ...(onCurrentKeyChange === undefined ? {} : { onChange: onCurrentKeyChange }),\n });\n const previousIndex = useRef<number | null>(null);\n const host = useRef<HTMLDivElement | null>(null);\n const lastFocused = useRef<HTMLElement | null>(null);\n // A host can delete the current uncontrolled slide after mount. Keep its place\n // in the collection (or the new last slide); explicit invalid keys still fail validation.\n const recovering = currentKey === undefined && previousIndex.current !== null && !slides.some(slide => slide.id === storedCurrent);\n const current = recovering ? slides[Math.min(previousIndex.current!, slides.length - 1)]?.id ?? storedCurrent : storedCurrent;\n useLayoutEffect(() => {\n previousIndex.current = slides.findIndex(slide => slide.id === current);\n if (recovering) {\n setCurrent(current);\n // A removed dot/card can strand focus on body; retained controls keep their focus.\n if (lastFocused.current && !lastFocused.current.isConnected && document.activeElement === document.body) {\n host.current?.querySelector<HTMLButtonElement>('.hjm-carousel__dot[data-current=\"true\"]')?.focus();\n }\n }\n }, [current, recovering, slides, setCurrent]);\n const descriptor = { slides, currentKey: current, ...(autoplay ? { autoplay } : {}) };\n const resolved = resolveCarouselDescriptor(descriptor, { composeAccessibleName });\n if (!label.trim() || Object.values(labels).some((value) => !value.trim())) throw new TypeError(\"Carousel labels must not be empty\");\n const [rotating, setRotating] = useState(autoplay !== undefined);\n const [hovered, setHovered] = useState(false);\n const [hidden, setHidden] = useState(false);\n const pointerRotation = useRef<boolean | null>(null);\n const last = current === slides.at(-1)!.id;\n const playing = isCarouselAutoplayActive(autoplay, {\n reducedMotion: theme?.environment.reducedMotion ?? false,\n paused: !rotating || hovered || hidden || last,\n });\n useEffect(() => {\n const update = () => setHidden(document.hidden);\n update(); document.addEventListener(\"visibilitychange\", update);\n return () => document.removeEventListener(\"visibilitychange\", update);\n }, []);\n useEffect(() => {\n if (!playing || !autoplay) return;\n const timer = setTimeout(() => setCurrent(getCarouselNavigationTarget(descriptor, \"next\")), autoplay.intervalMs);\n return () => clearTimeout(timer);\n }, [playing, autoplay?.intervalMs, current, slides, setCurrent]);\n function select(key: string) { setRotating(false); if (key !== current) setCurrent(key); }\n function move(intent: \"next\" | \"previous\") { select(getCarouselNavigationTarget(descriptor, intent)); }\n const rotationRequested = rotating && !last && !theme?.environment.reducedMotion;\n return <div {...props} style={{ ...props.style, ...layoutStyle }} ref={node => { host.current = node; assignRef(ref, node); }} role=\"region\" aria-label={label} aria-roledescription=\"carousel\"\n className={classNames(\"hjm-carousel\", className)} data-large-text={isLargeTextScale(theme?.environment.textScale ?? 1)}\n onFocusCapture={(event) => {\n lastFocused.current = event.target instanceof HTMLElement ? event.target : null;\n // APG: leaving focus must not silently restart rotation. Explicit resume is required.\n if (!event.currentTarget.contains(event.relatedTarget)) setRotating(false);\n onFocusCapture?.(event);\n }}\n onMouseEnter={(event) => { setHovered(true); onMouseEnter?.(event); }}\n onMouseLeave={(event) => { setHovered(false); onMouseLeave?.(event); }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) return;\n // Do not steal editing/navigation keys from links, inputs or widgets inside a card.\n if (!(event.target instanceof Element) || !event.target.closest(\"[data-carousel-controls]\")) return;\n if (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") return;\n event.preventDefault();\n move((event.key === \"ArrowRight\") !== (theme?.environment.direction === \"rtl\") ? \"next\" : \"previous\");\n }}>\n {autoplay ? <Button tone=\"ghost\" className=\"hjm-carousel__rotation\" disabled={theme?.environment.reducedMotion}\n onPointerDown={() => { pointerRotation.current = !rotationRequested; }}\n onPointerCancel={() => { pointerRotation.current = null; }}\n onClick={(event) => {\n // An abandoned pointer gesture must not override a later keyboard activation.\n const next = event.detail > 0 ? pointerRotation.current ?? !rotationRequested : !rotationRequested;\n pointerRotation.current = null;\n if (next && last) setCurrent(slides[0]!.id);\n setRotating(next);\n }}>{rotationRequested ? labels.pause : labels.resume}</Button> : null}\n <div className=\"hjm-carousel__track\" aria-live={playing ? \"off\" : \"polite\"} aria-atomic={false}>\n {resolved.map((slide) => <div key={slide.id} className=\"hjm-carousel__slide\" role=\"group\"\n aria-roledescription=\"slide\" aria-label={slide.accessibleName} hidden={slide.inert} inert={slide.inert}>\n {renderSlide(slide)}\n </div>)}\n </div>\n <div className=\"hjm-carousel__controls\" data-carousel-controls role=\"group\" aria-label={labels.navigation}>\n {/* Previous/next are tool actions: icon buttons named by the localized label (2026-10-17 review E9). */}\n <IconButton label={labels.previous} tone=\"ghost\" aria-disabled={current === slides[0]!.id} onClick={() => move(\"previous\")}><Icon name=\"chevronStart\" /></IconButton>\n <div className=\"hjm-carousel__dots\">\n {resolved.map((slide) => <button key={slide.id} type=\"button\" aria-label={slide.accessibleName}\n aria-disabled={slide.current} data-current={slide.current} className=\"hjm-carousel__dot\"\n onClick={() => select(slide.id)}><span aria-hidden=\"true\" /></button>)}\n </div>\n <IconButton label={labels.next} tone=\"ghost\" aria-disabled={last} onClick={() => move(\"next\")}><Icon name=\"chevronEnd\" /></IconButton>\n </div>\n </div>;\n});\n"]}
1
+ {"version":3,"file":"carousel.js","sourceRoot":"","sources":["../src/carousel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport {\n resolveCarouselDescriptor, getCarouselNavigationTarget, isCarouselAutoplayActive,\n resolvePageIndicator, getPageIndicatorTarget,\n type CarouselSlideDescriptor, type CarouselSelection, type CarouselAutoplayConfig,\n type ComposeCarouselAccessibleName, type ComposePageIndicatorAccessibleName, type ResolvedPageIndicatorDot,\n} from \"@hjmds/design-contracts/components/carousel\";\nimport { Button, IconButton } from \"./actions.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport { isLargeTextScale } from \"@hjmds/design-contracts/components/design-system-provider\";\nimport { assignRef, classNames, useControllableState } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type CarouselLabels = Readonly<{ previous: string; next: string; pause: string; resume: string; navigation: string }>;\nexport type CarouselProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"onChange\"> & CarouselSelection & Readonly<{\n label: string;\n slides: readonly CarouselSlideDescriptor[];\n renderSlide: (slide: CarouselSlideDescriptor) => ReactNode;\n composeAccessibleName: ComposeCarouselAccessibleName;\n labels: CarouselLabels;\n autoplay?: CarouselAutoplayConfig;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport type PageIndicatorProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"onChange\"> & Readonly<{\n /** Name of the paged region (e.g. \"Home pages\"); the group's accessible name. */\n label: string;\n count: number;\n /** Zero-based current page; the product pager owns it. */\n currentIndex: number;\n /** Requested page from a dot or an arrow key. It can repeat the current index. */\n onCurrentIndexChange: (index: number) => void;\n composeAccessibleName: ComposePageIndicatorAccessibleName;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** The dot buttons shared by Carousel and PageIndicator, so both rows keep one markup and one recipe. */\nfunction PageDots({ dots, onSelect, dotClassName, keys }: Readonly<{\n dots: readonly ResolvedPageIndicatorDot[];\n onSelect: (index: number) => void;\n dotClassName: string;\n /** Carousel keys dots by slide id so removing a slide removes its own (possibly focused) dot. */\n keys?: readonly string[];\n}>) {\n return <>{dots.map((dot) => <button key={keys?.[dot.index] ?? dot.index} type=\"button\" aria-label={dot.accessibleName}\n aria-disabled={dot.current} data-current={dot.current} className={dotClassName}\n onClick={() => onSelect(dot.index)}><span aria-hidden=\"true\" /></button>)}</>;\n}\n\n/**\n * Carousel's position dots for a product-owned pager (scroll-snap row, virtualized pager). Arrow keys on a dot move\n * one page in reading direction, as in Carousel's controls.\n */\nexport const PageIndicator = forwardRef<HTMLDivElement, PageIndicatorProps>(function PageIndicator({\n label, count, currentIndex, onCurrentIndexChange, composeAccessibleName, className, onKeyDown, layoutStyle, ...props\n}, ref) {\n const theme = useOptionalHjmTheme();\n if (!label.trim()) throw new TypeError(\"PageIndicator label must not be empty\");\n const descriptor = { count, currentIndex };\n const dots = resolvePageIndicator(descriptor, composeAccessibleName);\n return <div {...props} ref={ref} style={{ ...props.style, ...layoutStyle }} role=\"group\" aria-label={label}\n className={classNames(\"hjm-page-indicator\", className)}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) return;\n if (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") return;\n event.preventDefault();\n onCurrentIndexChange(getPageIndicatorTarget(descriptor,\n (event.key === \"ArrowRight\") !== (theme?.environment.direction === \"rtl\") ? \"next\" : \"previous\"));\n }}>\n <PageDots dots={dots} onSelect={onCurrentIndexChange} dotClassName=\"hjm-page-indicator__dot\" />\n </div>;\n});\n\n/** Finite keyed cards. Hidden slides stay mounted but cannot receive focus. */\nexport const Carousel = forwardRef<HTMLDivElement, CarouselProps>(function Carousel({\n label, slides, renderSlide, composeAccessibleName, labels, autoplay,\n currentKey, defaultCurrentKey, onCurrentKeyChange, className,\n onFocusCapture, onMouseEnter, onMouseLeave, onKeyDown, layoutStyle, ...props\n}, ref) {\n const theme = useOptionalHjmTheme();\n const [storedCurrent, setCurrent] = useControllableState({\n ...(currentKey === undefined ? {} : { value: currentKey }),\n defaultValue: defaultCurrentKey ?? slides[0]?.id ?? \"\",\n ...(onCurrentKeyChange === undefined ? {} : { onChange: onCurrentKeyChange }),\n });\n const previousIndex = useRef<number | null>(null);\n const host = useRef<HTMLDivElement | null>(null);\n const lastFocused = useRef<HTMLElement | null>(null);\n // A host can delete the current uncontrolled slide after mount. Keep its place\n // in the collection (or the new last slide); explicit invalid keys still fail validation.\n const recovering = currentKey === undefined && previousIndex.current !== null && !slides.some(slide => slide.id === storedCurrent);\n const current = recovering ? slides[Math.min(previousIndex.current!, slides.length - 1)]?.id ?? storedCurrent : storedCurrent;\n useLayoutEffect(() => {\n previousIndex.current = slides.findIndex(slide => slide.id === current);\n if (recovering) {\n setCurrent(current);\n // A removed dot/card can strand focus on body; retained controls keep their focus.\n if (lastFocused.current && !lastFocused.current.isConnected && document.activeElement === document.body) {\n host.current?.querySelector<HTMLButtonElement>('.hjm-carousel__dot[data-current=\"true\"]')?.focus();\n }\n }\n }, [current, recovering, slides, setCurrent]);\n const descriptor = { slides, currentKey: current, ...(autoplay ? { autoplay } : {}) };\n const resolved = resolveCarouselDescriptor(descriptor, { composeAccessibleName });\n if (!label.trim() || Object.values(labels).some((value) => !value.trim())) throw new TypeError(\"Carousel labels must not be empty\");\n const [rotating, setRotating] = useState(autoplay !== undefined);\n const [hovered, setHovered] = useState(false);\n const [hidden, setHidden] = useState(false);\n const pointerRotation = useRef<boolean | null>(null);\n const last = current === slides.at(-1)!.id;\n const playing = isCarouselAutoplayActive(autoplay, {\n reducedMotion: theme?.environment.reducedMotion ?? false,\n paused: !rotating || hovered || hidden || last,\n });\n useEffect(() => {\n const update = () => setHidden(document.hidden);\n update(); document.addEventListener(\"visibilitychange\", update);\n return () => document.removeEventListener(\"visibilitychange\", update);\n }, []);\n useEffect(() => {\n if (!playing || !autoplay) return;\n const timer = setTimeout(() => setCurrent(getCarouselNavigationTarget(descriptor, \"next\")), autoplay.intervalMs);\n return () => clearTimeout(timer);\n }, [playing, autoplay?.intervalMs, current, slides, setCurrent]);\n function select(key: string) { setRotating(false); if (key !== current) setCurrent(key); }\n function move(intent: \"next\" | \"previous\") { select(getCarouselNavigationTarget(descriptor, intent)); }\n const rotationRequested = rotating && !last && !theme?.environment.reducedMotion;\n return <div {...props} style={{ ...props.style, ...layoutStyle }} ref={node => { host.current = node; assignRef(ref, node); }} role=\"region\" aria-label={label} aria-roledescription=\"carousel\"\n className={classNames(\"hjm-carousel\", className)} data-large-text={isLargeTextScale(theme?.environment.textScale ?? 1)}\n onFocusCapture={(event) => {\n lastFocused.current = event.target instanceof HTMLElement ? event.target : null;\n // APG: leaving focus must not silently restart rotation. Explicit resume is required.\n if (!event.currentTarget.contains(event.relatedTarget)) setRotating(false);\n onFocusCapture?.(event);\n }}\n onMouseEnter={(event) => { setHovered(true); onMouseEnter?.(event); }}\n onMouseLeave={(event) => { setHovered(false); onMouseLeave?.(event); }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) return;\n // Do not steal editing/navigation keys from links, inputs or widgets inside a card.\n if (!(event.target instanceof Element) || !event.target.closest(\"[data-carousel-controls]\")) return;\n if (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") return;\n event.preventDefault();\n move((event.key === \"ArrowRight\") !== (theme?.environment.direction === \"rtl\") ? \"next\" : \"previous\");\n }}>\n {autoplay ? <Button tone=\"ghost\" className=\"hjm-carousel__rotation\" disabled={theme?.environment.reducedMotion}\n onPointerDown={() => { pointerRotation.current = !rotationRequested; }}\n onPointerCancel={() => { pointerRotation.current = null; }}\n onClick={(event) => {\n // An abandoned pointer gesture must not override a later keyboard activation.\n const next = event.detail > 0 ? pointerRotation.current ?? !rotationRequested : !rotationRequested;\n pointerRotation.current = null;\n if (next && last) setCurrent(slides[0]!.id);\n setRotating(next);\n }}>{rotationRequested ? labels.pause : labels.resume}</Button> : null}\n <div className=\"hjm-carousel__track\" aria-live={playing ? \"off\" : \"polite\"} aria-atomic={false}>\n {resolved.map((slide) => <div key={slide.id} className=\"hjm-carousel__slide\" role=\"group\"\n aria-roledescription=\"slide\" aria-label={slide.accessibleName} hidden={slide.inert} inert={slide.inert}>\n {renderSlide(slide)}\n </div>)}\n </div>\n <div className=\"hjm-carousel__controls\" data-carousel-controls role=\"group\" aria-label={labels.navigation}>\n {/* Previous/next are tool actions: icon buttons named by the localized label (2026-10-17 review E9). */}\n <IconButton label={labels.previous} tone=\"ghost\" aria-disabled={current === slides[0]!.id} onClick={() => move(\"previous\")}><Icon name=\"chevronStart\" /></IconButton>\n <div className=\"hjm-carousel__dots\">\n <PageDots dotClassName=\"hjm-carousel__dot\" keys={slides.map((slide) => slide.id)} onSelect={(index) => select(slides[index]!.id)}\n dots={resolvePageIndicator({ count: slides.length, currentIndex: resolved.findIndex((slide) => slide.current) },\n ({ position }) => resolved[position - 1]!.accessibleName)} />\n </div>\n <IconButton label={labels.next} tone=\"ghost\" aria-disabled={last} onClick={() => move(\"next\")}><Icon name=\"chevronEnd\" /></IconButton>\n </div>\n </div>;\n});\n"]}
package/dist/display.d.ts CHANGED
@@ -43,7 +43,10 @@ export type CardProps = Omit<HTMLAttributes<HTMLElement>, "title"> & Readonly<{
43
43
  actions?: ReactNode;
44
44
  headingLevel?: CardHeadingLevel;
45
45
  selected?: boolean;
46
- /** Whole-card activation. Do not combine with interactive children or actions. */
46
+ /**
47
+ * Whole-card activation. With `actions`, the card stays an article and a separate full-card button sits under the
48
+ * action region, so actions remain independent buttons (never a button inside a button). Keep other children passive.
49
+ */
47
50
  onActivate?: () => void;
48
51
  disabled?: boolean;
49
52
  tone?: SurfaceTone;
@@ -61,7 +64,10 @@ export declare const Card: import("react").ForwardRefExoticComponent<Omit<HTMLAt
61
64
  actions?: ReactNode;
62
65
  headingLevel?: CardHeadingLevel;
63
66
  selected?: boolean;
64
- /** Whole-card activation. Do not combine with interactive children or actions. */
67
+ /**
68
+ * Whole-card activation. With `actions`, the card stays an article and a separate full-card button sits under the
69
+ * action region, so actions remain independent buttons (never a button inside a button). Keep other children passive.
70
+ */
65
71
  onActivate?: () => void;
66
72
  disabled?: boolean;
67
73
  tone?: SurfaceTone;
@@ -1 +1 @@
1
- {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,YAAY,IAAI,oBAAoB,EACzC,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEL,KAAK,OAAO,EACb,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,YAAY,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC,eAAe,CAAC,GACtD,QAAQ,CAAC;IACP,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,OAAO,CAAC,EAAE,SAAS,CAAC;IAClB,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,KAAK;WARP,SAAS;WACT,SAAS;cACN,YAAY;cACZ,SAAS;IACjB,4EAA4E;kBAChE,uBAAuB;oDAmCvC,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,GACtE,QAAQ,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACb,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,GAAG;cANF,MAAM;WACT,OAAO;IACZ,4EAA4E;kBAChE,uBAAuB;oDAsBvC,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,GAChE,QAAQ,CAAC;IACP,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,wFAAwF;IACxF,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEL,eAAO,MAAM,IAAI;YAlBL,SAAS;kBACH,SAAS;cACb,SAAS;YACX,SAAS;cACP,SAAS;mBACJ,gBAAgB;eACpB,OAAO;IAClB,kFAAkF;iBACrE,MAAM,IAAI;eACZ,OAAO;WACX,WAAW;eACP,OAAO;cACR,cAAc;aACf,aAAa;IACtB,wFAAwF;kBAC1E,uBAAuB;gDAwFvC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC,GAC/E,QAAQ,CAAC;IACP,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,uEAAuE;IACvE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;IACpE,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,OAAO,aAAa,CAAC,KAAK,CAAC;IACxC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACvC,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,OAAO;WA7BT,SAAS;kBACF,SAAS;cACb,SAAS;eACR,SAAS;IACpB,+DAA+D;qBAC9C,SAAS;IAC1B,uEAAuE;iBAC1D,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS;cACzD,cAAc;IACxB,mFAAmF;WAC5E,MAAM,OAAO,aAAa,CAAC,KAAK;IACvC,2EAA2E;mBAC5D,mBAAmB;eACvB,OAAO;eACP,OAAO;IAClB;;;;OAIG;cACO,OAAO;IACjB,uDAAuD;mBACxC,MAAM;WACd,MAAM;cACH,iBAAiB,CAAC,WAAW,CAAC;IACtC,4EAA4E;kBAChE,uBAAuB;gDAsHvC,CAAC"}
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"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"}
package/dist/display.js CHANGED
@@ -18,18 +18,23 @@ export const Tag = forwardRef(function Tag({ children, tone, className, layoutSt
18
18
  return (_jsx("span", { ...props, style: { ...style, ...layoutStyle }, ref: ref, className: classNames("hjm-tag", className), "data-tone": descriptor.tone, children: _jsx("span", { className: "hjm-tag__label", children: descriptor.label }) }));
19
19
  });
20
20
  export const Card = forwardRef(function Card({ title, description, leading, media, actions, headingLevel = cardRecipe.defaults.headingLevel, selected = cardRecipe.defaults.selected, onActivate, disabled = false, tone = cardRecipe.defaults.tone, bordered = cardRecipe.defaults.bordered, padding = cardRecipe.defaults.padding, radius, className, children, ...props }, ref) {
21
- if (onActivate && (!props["aria-label"]?.trim() || actions !== undefined)) {
22
- throw new TypeError("Interactive Card requires aria-label and no actions");
21
+ if (onActivate && !props["aria-label"]?.trim()) {
22
+ throw new TypeError("Interactive Card requires aria-label");
23
23
  }
24
24
  const hasHeader = leading !== undefined || title !== undefined || description !== undefined;
25
- return (_jsxs(Surface, { ...props, ref: ref, as: onActivate ? "button" : "article", ...(onActivate ? {
25
+ // Whole-card open plus separate commands (2026-10-18 unairplane journey card: open + delete). A root button cannot
26
+ // contain the action buttons, so the root stays an article and an overlay button carries the card's name and state.
27
+ const overlay = onActivate !== undefined && Boolean(actions);
28
+ const { "aria-label": activationLabel, ...rootProps } = props;
29
+ const activate = () => { if (!disabled)
30
+ onActivate?.(); };
31
+ return (_jsxs(Surface, { ...(overlay ? rootProps : props), ref: ref, as: onActivate && !overlay ? "button" : "article", ...(onActivate && !overlay ? {
26
32
  type: "button", disabled, "aria-pressed": selected,
27
- "data-interactive": true, onClick: () => { if (!disabled)
28
- onActivate(); },
29
- } : {}), tone: selected ? cardRecipe.selectedTone : tone, bordered: bordered, ...(radius === undefined ? {} : { radius }), className: classNames("hjm-card", className), "data-state": onActivate && disabled ? "disabled" : selected ? "selected" : "idle", style: { "--hjm-card-disabled-opacity": cardRecipe.interaction.disabledOpacity,
33
+ "data-interactive": true, onClick: activate,
34
+ } : {}), ...(overlay ? { "data-activation": "overlay" } : {}), tone: selected ? cardRecipe.selectedTone : tone, bordered: bordered, ...(radius === undefined ? {} : { radius }), className: classNames("hjm-card", className), "data-state": onActivate && disabled ? "disabled" : selected ? "selected" : "idle", style: { "--hjm-card-disabled-opacity": cardRecipe.interaction.disabledOpacity,
30
35
  "--hjm-card-pressed-opacity": cardRecipe.interaction.pressedOpacity, ...props.style }, children: [media ? _jsx("div", { className: "hjm-card__media", "data-slot": "media", children: media }) : null, _jsxs("div", { className: "hjm-card__body", "data-slot": "body", style: { padding: surfaceGeometry.paddings[padding] }, children: [hasHeader ? (_jsxs("div", { className: "hjm-card__header", "data-slot": "header", children: [leading === undefined ? null : (_jsx("span", { className: "hjm-card__leading", "data-slot": "leading", children: leading })), _jsxs("div", { className: "hjm-card__copy", children: [title === undefined
31
36
  ? null
32
- : createElement(`h${headingLevel}`, { className: "hjm-card__title", "data-slot": "title" }, title), description === undefined ? null : (_jsx(Text, { as: "p", tone: "muted", className: "hjm-card__description", "data-slot": "description", children: description }))] })] })) : null, children === undefined ? null : (_jsx("div", { className: "hjm-card__content", "data-slot": "content", children: children }))] }), actions ? _jsx("div", { className: "hjm-card__actions", "data-slot": "actions", children: actions }) : null] }));
37
+ : createElement(`h${headingLevel}`, { className: "hjm-card__title", "data-slot": "title" }, title), description === undefined ? null : (_jsx(Text, { as: "p", tone: "muted", className: "hjm-card__description", "data-slot": "description", children: description }))] })] })) : null, children === undefined ? null : (_jsx("div", { className: "hjm-card__content", "data-slot": "content", children: children }))] }), overlay ? (_jsx("button", { type: "button", className: "hjm-card__activator", "data-slot": "activator", "aria-label": activationLabel, "aria-pressed": selected, disabled: disabled, onClick: activate })) : null, actions ? _jsx("div", { className: "hjm-card__actions", "data-slot": "actions", children: actions }) : null] }));
33
38
  });
34
39
  export const ListRow = forwardRef(function ListRow({ title, description, leading, trailing, trailingAction, renderLink, density: densityProp, tone = listRowRecipe.defaults.tone, leadingShape = "square", selected = listRowRecipe.defaults.selected, disabled = false, loading = false, loadingLabel, href, onClick, className, layoutStyle, style, ...props }, ref) {
35
40
  // The hook runs unconditionally — `??` would short-circuit it and break the
@@ -1 +1 @@
1
- {"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n badgeRecipe,\n listRowRecipe,\n type BadgeSize,\n type BadgeTone,\n type BadgeVariant as ContractBadgeVariant,\n type ListRowDensity,\n type ListRowLeadingShape,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n resolveTagDescriptor,\n type TagTone,\n} from \"@hjmds/design-contracts/components/tag\";\nimport {\n cardRecipe,\n type CardHeadingLevel,\n} from \"@hjmds/design-contracts/components/card\";\nimport {\n surfaceGeometry,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n createElement,\n forwardRef,\n type CSSProperties,\n type HTMLAttributes,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useHjmDensityDefault } from \"./provider.js\";\nimport { Surface, Text } from \"./layout.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type { CardHeadingLevel } from \"@hjmds/design-contracts/components/card\";\nexport type { TagTone } from \"@hjmds/design-contracts/components/tag\";\nexport type BadgeVariant = ContractBadgeVariant;\n\nexport type BadgeProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{\n tone?: BadgeTone;\n size?: BadgeSize;\n variant?: BadgeVariant;\n leading?: ReactNode;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n {\n tone = badgeRecipe.defaults.tone,\n size = badgeRecipe.defaults.size,\n variant = badgeRecipe.defaults.variant,\n leading,\n className,\n children,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-badge\", className)}\n data-tone={tone}\n data-size={size}\n data-variant={variant}\n >\n {leading === undefined ? null : (\n <span aria-hidden=\"true\" className=\"hjm-badge__icon\">\n {leading}\n </span>\n )}\n <span className=\"hjm-badge__label\">{children}</span>\n </span>\n );\n});\n\nexport type TagProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n children: string;\n tone?: TagTone;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Tag = forwardRef<HTMLSpanElement, TagProps>(function Tag(\n { children, tone, className, layoutStyle, style, ...props },\n ref,\n) {\n const descriptor = resolveTagDescriptor({\n label: children,\n ...(tone === undefined ? {} : { tone }),\n });\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-tag\", className)}\n data-tone={descriptor.tone}\n >\n <span className=\"hjm-tag__label\">{descriptor.label}</span>\n </span>\n );\n});\n\nexport type CardProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n media?: ReactNode;\n actions?: ReactNode;\n headingLevel?: CardHeadingLevel;\n selected?: boolean;\n /** Whole-card activation. Do not combine with interactive children or actions. */\n onActivate?: () => void;\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement; forwarded to the root Surface, which applies it. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Card = forwardRef<HTMLElement, CardProps>(function Card(\n {\n title,\n description,\n leading,\n media,\n actions,\n headingLevel = cardRecipe.defaults.headingLevel,\n selected = cardRecipe.defaults.selected,\n onActivate,\n disabled = false,\n tone = cardRecipe.defaults.tone,\n bordered = cardRecipe.defaults.bordered,\n padding = cardRecipe.defaults.padding,\n radius,\n className,\n children,\n ...props\n },\n ref,\n) {\n if (onActivate && (!props[\"aria-label\"]?.trim() || actions !== undefined)) {\n throw new TypeError(\"Interactive Card requires aria-label and no actions\");\n }\n const hasHeader =\n leading !== undefined || title !== undefined || description !== undefined;\n\n return (\n <Surface\n {...props}\n ref={ref}\n as={onActivate ? \"button\" : \"article\"}\n {...(onActivate ? {\n type: \"button\" as const, disabled, \"aria-pressed\": selected,\n \"data-interactive\": true, onClick: () => { if (!disabled) onActivate(); },\n } : {})}\n tone={selected ? cardRecipe.selectedTone : tone}\n bordered={bordered}\n {...(radius === undefined ? {} : { radius })}\n className={classNames(\"hjm-card\", className)}\n data-state={onActivate && disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"}\n style={{ \"--hjm-card-disabled-opacity\": cardRecipe.interaction.disabledOpacity,\n \"--hjm-card-pressed-opacity\": cardRecipe.interaction.pressedOpacity, ...props.style } as CSSProperties}\n >\n {media ? <div className=\"hjm-card__media\" data-slot=\"media\">{media}</div> : null}\n <div\n className=\"hjm-card__body\"\n data-slot=\"body\"\n style={{ padding: surfaceGeometry.paddings[padding] }}\n >\n {hasHeader ? (\n <div className=\"hjm-card__header\" data-slot=\"header\">\n {leading === undefined ? null : (\n <span className=\"hjm-card__leading\" data-slot=\"leading\">\n {leading}\n </span>\n )}\n <div className=\"hjm-card__copy\">\n {title === undefined\n ? null\n : createElement(\n `h${headingLevel}`,\n { className: \"hjm-card__title\", \"data-slot\": \"title\" },\n title,\n )}\n {description === undefined ? null : (\n <Text\n as=\"p\"\n tone=\"muted\"\n className=\"hjm-card__description\"\n data-slot=\"description\"\n >\n {description}\n </Text>\n )}\n </div>\n </div>\n ) : null}\n {children === undefined ? null : (\n <div className=\"hjm-card__content\" data-slot=\"content\">{children}</div>\n )}\n </div>\n {actions ? <div className=\"hjm-card__actions\" data-slot=\"actions\">{actions}</div> : null}\n </Surface>\n );\n});\n\nexport type ListRowProps = Omit<HTMLAttributes<HTMLElement>, \"title\" | \"onClick\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n trailing?: ReactNode;\n /** Independent command outside the row's navigation target. */\n trailingAction?: ReactNode;\n /** Supply a framework Link without replacing the shared row layout. */\n renderLink?: (props: React.ComponentPropsWithRef<\"a\">) => ReactNode;\n density?: ListRowDensity;\n /** Semantic emphasis for destructive destinations; selection stays independent. */\n tone?: keyof typeof listRowRecipe.tones;\n /** Frame the ListRow paints around `leading`; the recipe owns its size. */\n leadingShape?: ListRowLeadingShape;\n selected?: boolean;\n disabled?: boolean;\n /**\n * Placeholder row while the real one loads. It keeps the row's own height\n * and slot geometry, so a list does not jump when the content arrives —\n * which is exactly what a product-owned skeleton next to the list cannot do.\n */\n loading?: boolean;\n /** Localized status text announced while `loading`. */\n loadingLabel?: string;\n href?: string;\n onClick?: MouseEventHandler<HTMLElement>;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const ListRow = forwardRef<HTMLElement, ListRowProps>(function ListRow(\n {\n title,\n description,\n leading,\n trailing,\n trailingAction,\n renderLink,\n density: densityProp,\n tone = listRowRecipe.defaults.tone,\n leadingShape = \"square\",\n selected = listRowRecipe.defaults.selected,\n disabled = false,\n loading = false,\n loadingLabel,\n href,\n onClick,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n // The hook runs unconditionally — `??` would short-circuit it and break the\n // rules of hooks on the very first row that passes `density`.\n const densityDefault = useHjmDensityDefault({\n comfortable: listRowRecipe.defaults.density,\n compact: \"compact\",\n });\n const density = densityProp ?? densityDefault;\n if (loading) {\n // A loading row is never interactive: there is nothing to activate yet.\n return (\n <div\n {...props}\n ref={ref as React.Ref<HTMLDivElement>}\n role={loadingLabel ? \"status\" : undefined}\n aria-busy={loadingLabel ? true : undefined}\n aria-hidden={loadingLabel ? undefined : true}\n aria-label={loadingLabel}\n className={classNames(\"hjm-list-row\", \"hjm-list-row--loading\", className)}\n data-density={density}\n data-leading={leading ? \"\" : undefined}\n data-lines={description ? \"two\" : \"one\"}\n data-state=\"loading\"\n style={{ ...style, ...layoutStyle }}\n >\n {leading ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape} data-placeholder=\"\" /> : null}\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.titleWidthPercent}%` }} />\n {description ? <span className=\"hjm-list-row__description\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.descriptionWidthPercent}%` }} /> : null}\n </span>\n {trailing ? <span className=\"hjm-list-row__trailing\" data-placeholder=\"\" style={{ width: listRowRecipe.loading.trailingWidth }} /> : null}\n </div>\n );\n }\n const element = href ? \"a\" : onClick ? \"button\" : \"div\";\n const interactiveProps = href\n ? {\n href: disabled ? undefined : href,\n \"aria-current\": selected ? (\"page\" as const) : undefined,\n \"aria-disabled\": disabled || undefined,\n tabIndex: disabled ? -1 : undefined,\n }\n : onClick\n ? {\n type: \"button\" as const,\n onClick: disabled ? undefined : onClick,\n disabled,\n \"aria-pressed\": selected,\n }\n : {};\n\n const row = createElement(\n element,\n {\n ...props,\n ...interactiveProps,\n ref,\n className: classNames(\"hjm-list-row\", className),\n \"data-density\": density,\n // Exposes the text column to the enclosing List: its indented separator starts after the leading frame\n // (listRecipe.separators.indented.leadingInsetStart) only when this row has one.\n \"data-leading\": leading ? \"\" : undefined,\n \"data-tone\": tone,\n // One- and two-line rows have different minimum heights in the recipe;\n // the web renderer used a single hardcoded value until now.\n \"data-lines\": description ? \"two\" : \"one\",\n \"data-state\": disabled ? \"disabled\" : selected ? \"selected\" : \"idle\",\n // Placement wins over the legacy `style`, matching Surface's ordering.\n // With trailingAction the frame is the placed root, as Native's outer View.\n style: trailingAction ? style : { ...style, ...layoutStyle },\n },\n leading\n ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape}>{leading}</span>\n : null,\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\">{title}</span>\n {description ? (\n <span className=\"hjm-list-row__description\">{description}</span>\n ) : null}\n </span>,\n trailing ? <span className=\"hjm-list-row__trailing\">{trailing}</span> : null,\n );\n const linked = href && renderLink ? renderLink(row.props as React.ComponentPropsWithRef<\"a\">) : row;\n // The frame owns the row surface and its bleed so the command and the separate action share one fill, as Native;\n // the action stays outside the link/button (styles.css `.hjm-list-row-frame`).\n return trailingAction ? (\n <div className=\"hjm-list-row-frame\" data-density={density} data-leading={leading ? \"\" : undefined}\n data-state={disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"} style={layoutStyle}>\n {linked}\n <div className=\"hjm-list-row__action\">{trailingAction}</div>\n </div>\n ) : linked;\n});\n"]}
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n badgeRecipe,\n listRowRecipe,\n type BadgeSize,\n type BadgeTone,\n type BadgeVariant as ContractBadgeVariant,\n type ListRowDensity,\n type ListRowLeadingShape,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n resolveTagDescriptor,\n type TagTone,\n} from \"@hjmds/design-contracts/components/tag\";\nimport {\n cardRecipe,\n type CardHeadingLevel,\n} from \"@hjmds/design-contracts/components/card\";\nimport {\n surfaceGeometry,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n createElement,\n forwardRef,\n type CSSProperties,\n type HTMLAttributes,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useHjmDensityDefault } from \"./provider.js\";\nimport { Surface, Text } from \"./layout.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type { CardHeadingLevel } from \"@hjmds/design-contracts/components/card\";\nexport type { TagTone } from \"@hjmds/design-contracts/components/tag\";\nexport type BadgeVariant = ContractBadgeVariant;\n\nexport type BadgeProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{\n tone?: BadgeTone;\n size?: BadgeSize;\n variant?: BadgeVariant;\n leading?: ReactNode;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n {\n tone = badgeRecipe.defaults.tone,\n size = badgeRecipe.defaults.size,\n variant = badgeRecipe.defaults.variant,\n leading,\n className,\n children,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-badge\", className)}\n data-tone={tone}\n data-size={size}\n data-variant={variant}\n >\n {leading === undefined ? null : (\n <span aria-hidden=\"true\" className=\"hjm-badge__icon\">\n {leading}\n </span>\n )}\n <span className=\"hjm-badge__label\">{children}</span>\n </span>\n );\n});\n\nexport type TagProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n children: string;\n tone?: TagTone;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Tag = forwardRef<HTMLSpanElement, TagProps>(function Tag(\n { children, tone, className, layoutStyle, style, ...props },\n ref,\n) {\n const descriptor = resolveTagDescriptor({\n label: children,\n ...(tone === undefined ? {} : { tone }),\n });\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-tag\", className)}\n data-tone={descriptor.tone}\n >\n <span className=\"hjm-tag__label\">{descriptor.label}</span>\n </span>\n );\n});\n\nexport type CardProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n media?: ReactNode;\n actions?: ReactNode;\n headingLevel?: CardHeadingLevel;\n selected?: boolean;\n /**\n * Whole-card activation. With `actions`, the card stays an article and a separate full-card button sits under the\n * action region, so actions remain independent buttons (never a button inside a button). Keep other children passive.\n */\n onActivate?: () => void;\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement; forwarded to the root Surface, which applies it. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Card = forwardRef<HTMLElement, CardProps>(function Card(\n {\n title,\n description,\n leading,\n media,\n actions,\n headingLevel = cardRecipe.defaults.headingLevel,\n selected = cardRecipe.defaults.selected,\n onActivate,\n disabled = false,\n tone = cardRecipe.defaults.tone,\n bordered = cardRecipe.defaults.bordered,\n padding = cardRecipe.defaults.padding,\n radius,\n className,\n children,\n ...props\n },\n ref,\n) {\n if (onActivate && !props[\"aria-label\"]?.trim()) {\n throw new TypeError(\"Interactive Card requires aria-label\");\n }\n const hasHeader =\n leading !== undefined || title !== undefined || description !== undefined;\n // Whole-card open plus separate commands (2026-10-18 unairplane journey card: open + delete). A root button cannot\n // contain the action buttons, so the root stays an article and an overlay button carries the card's name and state.\n const overlay = onActivate !== undefined && Boolean(actions);\n const { \"aria-label\": activationLabel, ...rootProps } = props;\n const activate = () => { if (!disabled) onActivate?.(); };\n\n return (\n <Surface\n {...(overlay ? rootProps : props)}\n ref={ref}\n as={onActivate && !overlay ? \"button\" : \"article\"}\n {...(onActivate && !overlay ? {\n type: \"button\" as const, disabled, \"aria-pressed\": selected,\n \"data-interactive\": true, onClick: activate,\n } : {})}\n {...(overlay ? { \"data-activation\": \"overlay\" } : {})}\n tone={selected ? cardRecipe.selectedTone : tone}\n bordered={bordered}\n {...(radius === undefined ? {} : { radius })}\n className={classNames(\"hjm-card\", className)}\n data-state={onActivate && disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"}\n style={{ \"--hjm-card-disabled-opacity\": cardRecipe.interaction.disabledOpacity,\n \"--hjm-card-pressed-opacity\": cardRecipe.interaction.pressedOpacity, ...props.style } as CSSProperties}\n >\n {media ? <div className=\"hjm-card__media\" data-slot=\"media\">{media}</div> : null}\n <div\n className=\"hjm-card__body\"\n data-slot=\"body\"\n style={{ padding: surfaceGeometry.paddings[padding] }}\n >\n {hasHeader ? (\n <div className=\"hjm-card__header\" data-slot=\"header\">\n {leading === undefined ? null : (\n <span className=\"hjm-card__leading\" data-slot=\"leading\">\n {leading}\n </span>\n )}\n <div className=\"hjm-card__copy\">\n {title === undefined\n ? null\n : createElement(\n `h${headingLevel}`,\n { className: \"hjm-card__title\", \"data-slot\": \"title\" },\n title,\n )}\n {description === undefined ? null : (\n <Text\n as=\"p\"\n tone=\"muted\"\n className=\"hjm-card__description\"\n data-slot=\"description\"\n >\n {description}\n </Text>\n )}\n </div>\n </div>\n ) : null}\n {children === undefined ? null : (\n <div className=\"hjm-card__content\" data-slot=\"content\">{children}</div>\n )}\n </div>\n {overlay ? (\n <button\n type=\"button\"\n className=\"hjm-card__activator\"\n data-slot=\"activator\"\n aria-label={activationLabel}\n aria-pressed={selected}\n disabled={disabled}\n onClick={activate}\n />\n ) : null}\n {actions ? <div className=\"hjm-card__actions\" data-slot=\"actions\">{actions}</div> : null}\n </Surface>\n );\n});\n\nexport type ListRowProps = Omit<HTMLAttributes<HTMLElement>, \"title\" | \"onClick\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n trailing?: ReactNode;\n /** Independent command outside the row's navigation target. */\n trailingAction?: ReactNode;\n /** Supply a framework Link without replacing the shared row layout. */\n renderLink?: (props: React.ComponentPropsWithRef<\"a\">) => ReactNode;\n density?: ListRowDensity;\n /** Semantic emphasis for destructive destinations; selection stays independent. */\n tone?: keyof typeof listRowRecipe.tones;\n /** Frame the ListRow paints around `leading`; the recipe owns its size. */\n leadingShape?: ListRowLeadingShape;\n selected?: boolean;\n disabled?: boolean;\n /**\n * Placeholder row while the real one loads. It keeps the row's own height\n * and slot geometry, so a list does not jump when the content arrives —\n * which is exactly what a product-owned skeleton next to the list cannot do.\n */\n loading?: boolean;\n /** Localized status text announced while `loading`. */\n loadingLabel?: string;\n href?: string;\n onClick?: MouseEventHandler<HTMLElement>;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const ListRow = forwardRef<HTMLElement, ListRowProps>(function ListRow(\n {\n title,\n description,\n leading,\n trailing,\n trailingAction,\n renderLink,\n density: densityProp,\n tone = listRowRecipe.defaults.tone,\n leadingShape = \"square\",\n selected = listRowRecipe.defaults.selected,\n disabled = false,\n loading = false,\n loadingLabel,\n href,\n onClick,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n // The hook runs unconditionally — `??` would short-circuit it and break the\n // rules of hooks on the very first row that passes `density`.\n const densityDefault = useHjmDensityDefault({\n comfortable: listRowRecipe.defaults.density,\n compact: \"compact\",\n });\n const density = densityProp ?? densityDefault;\n if (loading) {\n // A loading row is never interactive: there is nothing to activate yet.\n return (\n <div\n {...props}\n ref={ref as React.Ref<HTMLDivElement>}\n role={loadingLabel ? \"status\" : undefined}\n aria-busy={loadingLabel ? true : undefined}\n aria-hidden={loadingLabel ? undefined : true}\n aria-label={loadingLabel}\n className={classNames(\"hjm-list-row\", \"hjm-list-row--loading\", className)}\n data-density={density}\n data-leading={leading ? \"\" : undefined}\n data-lines={description ? \"two\" : \"one\"}\n data-state=\"loading\"\n style={{ ...style, ...layoutStyle }}\n >\n {leading ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape} data-placeholder=\"\" /> : null}\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.titleWidthPercent}%` }} />\n {description ? <span className=\"hjm-list-row__description\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.descriptionWidthPercent}%` }} /> : null}\n </span>\n {trailing ? <span className=\"hjm-list-row__trailing\" data-placeholder=\"\" style={{ width: listRowRecipe.loading.trailingWidth }} /> : null}\n </div>\n );\n }\n const element = href ? \"a\" : onClick ? \"button\" : \"div\";\n const interactiveProps = href\n ? {\n href: disabled ? undefined : href,\n \"aria-current\": selected ? (\"page\" as const) : undefined,\n \"aria-disabled\": disabled || undefined,\n tabIndex: disabled ? -1 : undefined,\n }\n : onClick\n ? {\n type: \"button\" as const,\n onClick: disabled ? undefined : onClick,\n disabled,\n \"aria-pressed\": selected,\n }\n : {};\n\n const row = createElement(\n element,\n {\n ...props,\n ...interactiveProps,\n ref,\n className: classNames(\"hjm-list-row\", className),\n \"data-density\": density,\n // Exposes the text column to the enclosing List: its indented separator starts after the leading frame\n // (listRecipe.separators.indented.leadingInsetStart) only when this row has one.\n \"data-leading\": leading ? \"\" : undefined,\n \"data-tone\": tone,\n // One- and two-line rows have different minimum heights in the recipe;\n // the web renderer used a single hardcoded value until now.\n \"data-lines\": description ? \"two\" : \"one\",\n \"data-state\": disabled ? \"disabled\" : selected ? \"selected\" : \"idle\",\n // Placement wins over the legacy `style`, matching Surface's ordering.\n // With trailingAction the frame is the placed root, as Native's outer View.\n style: trailingAction ? style : { ...style, ...layoutStyle },\n },\n leading\n ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape}>{leading}</span>\n : null,\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\">{title}</span>\n {description ? (\n <span className=\"hjm-list-row__description\">{description}</span>\n ) : null}\n </span>,\n trailing ? <span className=\"hjm-list-row__trailing\">{trailing}</span> : null,\n );\n const linked = href && renderLink ? renderLink(row.props as React.ComponentPropsWithRef<\"a\">) : row;\n // The frame owns the row surface and its bleed so the command and the separate action share one fill, as Native;\n // the action stays outside the link/button (styles.css `.hjm-list-row-frame`).\n return trailingAction ? (\n <div className=\"hjm-list-row-frame\" data-density={density} data-leading={leading ? \"\" : undefined}\n data-state={disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"} style={layoutStyle}>\n {linked}\n <div className=\"hjm-list-row__action\">{trailingAction}</div>\n </div>\n ) : linked;\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.30.0";
37
+ readonly packageVersion: "1.32.0";
38
38
  readonly surface: "web";
39
39
  readonly components: Readonly<{
40
40
  /** Canonical component id from the design-contracts catalog. */
package/dist/evidence.js CHANGED
@@ -134,7 +134,7 @@ const activeWebEntries = componentCatalog.filter((entry) => {
134
134
  export const reactRendererEvidence = {
135
135
  schemaVersion: reactRendererEvidenceSchemaVersion,
136
136
  packageName: "@hjmds/react",
137
- packageVersion: "1.30.0",
137
+ packageVersion: "1.32.0",
138
138
  surface: "web",
139
139
  components: activeWebEntries.map(derivedClaim),
140
140
  };