@hjmds/react 1.6.0 → 1.8.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 (55) hide show
  1. package/README.md +17 -0
  2. package/THIRD_PARTY_NOTICES.md +28 -0
  3. package/dist/advanced-display.d.ts +3 -1
  4. package/dist/advanced-display.d.ts.map +1 -1
  5. package/dist/advanced-display.js +2 -2
  6. package/dist/advanced-display.js.map +1 -1
  7. package/dist/clipboard.d.ts +2 -2
  8. package/dist/clipboard.d.ts.map +1 -1
  9. package/dist/clipboard.js.map +1 -1
  10. package/dist/context-menu.d.ts.map +1 -1
  11. package/dist/context-menu.js +36 -9
  12. package/dist/context-menu.js.map +1 -1
  13. package/dist/evidence.d.ts +61 -2
  14. package/dist/evidence.d.ts.map +1 -1
  15. package/dist/evidence.js +133 -64
  16. package/dist/evidence.js.map +1 -1
  17. package/dist/feedback.d.ts +4 -4
  18. package/dist/feedback.d.ts.map +1 -1
  19. package/dist/feedback.js.map +1 -1
  20. package/dist/layout.d.ts.map +1 -1
  21. package/dist/layout.js +3 -2
  22. package/dist/layout.js.map +1 -1
  23. package/dist/masonry.d.ts +14 -0
  24. package/dist/masonry.d.ts.map +1 -0
  25. package/dist/masonry.js +13 -0
  26. package/dist/masonry.js.map +1 -0
  27. package/dist/menu-morph.d.ts +12 -0
  28. package/dist/menu-morph.d.ts.map +1 -0
  29. package/dist/menu-morph.js +79 -0
  30. package/dist/menu-morph.js.map +1 -0
  31. package/dist/navigation.d.ts.map +1 -1
  32. package/dist/navigation.js +13 -1
  33. package/dist/navigation.js.map +1 -1
  34. package/dist/qr-code.d.ts +11 -0
  35. package/dist/qr-code.d.ts.map +1 -0
  36. package/dist/qr-code.js +14 -0
  37. package/dist/qr-code.js.map +1 -0
  38. package/dist/statistic-motion.d.ts +12 -0
  39. package/dist/statistic-motion.d.ts.map +1 -0
  40. package/dist/statistic-motion.js +23 -0
  41. package/dist/statistic-motion.js.map +1 -0
  42. package/dist/styles.css +136 -133
  43. package/dist/styles.layered.css +136 -133
  44. package/dist/theme.d.ts.map +1 -1
  45. package/dist/theme.js +2 -1
  46. package/dist/theme.js.map +1 -1
  47. package/dist/thinking-orb.d.ts +9 -0
  48. package/dist/thinking-orb.d.ts.map +1 -0
  49. package/dist/thinking-orb.js +86 -0
  50. package/dist/thinking-orb.js.map +1 -0
  51. package/dist/virtual-list.d.ts +14 -0
  52. package/dist/virtual-list.d.ts.map +1 -0
  53. package/dist/virtual-list.js +48 -0
  54. package/dist/virtual-list.js.map +1 -0
  55. package/package.json +61 -5
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2DAA2D,CAAC;AAWnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,aAAa,GACvC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAmB7C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,yBAAyB,GAC/B,aAAa,CAyHf"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAeA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2DAA2D,CAAC;AAWnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,aAAa,GACvC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAmB7C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,yBAAyB,GAC/B,aAAa,CA0Hf"}
package/dist/theme.js CHANGED
@@ -1,4 +1,4 @@
1
- import { control, easing, fontFamily, fontWeight, motion, radius, shadow, spacing, stroke, typography, } from "@hjmds/design-contracts/foundations";
1
+ import { backdrop, control, easing, fontFamily, fontWeight, motion, radius, shadow, spacing, stroke, typography, } from "@hjmds/design-contracts/foundations";
2
2
  import { resolveColorReference } from "@hjmds/design-contracts/color-references";
3
3
  import { focusIndicatorContract } from "@hjmds/design-contracts/contracts";
4
4
  import { visibleControlHeight, } from "@hjmds/design-contracts/components/design-system-provider";
@@ -19,6 +19,7 @@ function rem(value) {
19
19
  export function createHjmThemeStyle(value) {
20
20
  const { environment, palette } = value;
21
21
  const style = {
22
+ "--hjm-backdrop-modal": `color-mix(in srgb, ${backdrop.modal.color} ${backdrop.modal.opacity * 100}%, transparent)`,
22
23
  "--hjm-text-scale": environment.textScale,
23
24
  "--hjm-motion-scale": environment.reducedMotion ? 0 : 1,
24
25
  colorScheme: environment.theme,
package/dist/theme.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n control,\n easing,\n fontFamily,\n fontWeight,\n motion,\n radius,\n shadow,\n spacing,\n stroke,\n typography,\n} from \"@hjmds/design-contracts/foundations\";\nimport { resolveColorReference } from \"@hjmds/design-contracts/color-references\";\nimport { focusIndicatorContract } from \"@hjmds/design-contracts/contracts\";\nimport {\n visibleControlHeight,\n type DesignSystemProviderValue,\n} from \"@hjmds/design-contracts/components/design-system-provider\";\nimport { buttonRecipe, fieldRecipe } from \"@hjmds/design-contracts/recipes/base\";\nimport {\n bottomNavigationRecipe,\n dialogRecipe,\n listRowRecipe,\n sheetRecipe,\n skeletonRecipe,\n switchRecipe,\n toastRecipe,\n} from \"@hjmds/design-contracts/recipes\";\nimport type { CSSProperties } from \"react\";\n\nexport type HjmThemeStyle = CSSProperties &\n Record<`--hjm-${string}`, string | number>;\n\nfunction kebab(value: string): string {\n return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\ntype ShadowToken = Readonly<{ color: string; opacity: number; radius: number; offsetY: number }>;\n\n// RN shadow token -> CSS; blur = radius, as react-native-web maps it.\nfunction shadowCss(token: ShadowToken): string {\n const hex = token.color.replace(\"#\", \"\");\n const [r, g, b] = [0, 2, 4].map((start) => Number.parseInt(hex.slice(start, start + 2), 16));\n return `0 ${token.offsetY}px ${token.radius}px rgb(${r} ${g} ${b} / ${Math.round(token.opacity * 100)}%)`;\n}\n\nfunction rem(value: number): string {\n return `${Number((value / 16).toFixed(5))}rem`;\n}\n\nexport function createHjmThemeStyle(\n value: DesignSystemProviderValue,\n): HjmThemeStyle {\n const { environment, palette } = value;\n const style: HjmThemeStyle = {\n \"--hjm-text-scale\": environment.textScale,\n \"--hjm-motion-scale\": environment.reducedMotion ? 0 : 1,\n colorScheme: environment.theme,\n backgroundColor: palette.theme.bg,\n color: palette.theme.text,\n };\n\n for (const [name, color] of Object.entries(palette.theme)) {\n style[`--hjm-color-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccents)) {\n style[`--hjm-accent-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccentFills)) {\n style[`--hjm-accent-fill-${kebab(name)}`] = color;\n }\n for (const [name, value] of Object.entries(spacing)) {\n style[`--hjm-space-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(radius)) {\n style[`--hjm-radius-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(typography)) {\n style[`--hjm-type-${kebab(name)}-size`] =\n `calc(${rem(value.fontSize)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-line-height`] =\n `calc(${rem(value.lineHeight)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-weight`] = value.fontWeight;\n }\n for (const [name, value] of Object.entries(fontWeight)) {\n style[`--hjm-font-weight-${kebab(name)}`] = value;\n }\n for (const [name, value] of Object.entries(motion)) {\n style[`--hjm-motion-${kebab(name)}`] = environment.reducedMotion\n ? \"0ms\"\n : `${value}ms`;\n }\n\n style[\"--hjm-font-family-ui\"] = fontFamily.ui.join(\", \");\n for (const [name, value] of Object.entries(stroke)) {\n style[`--hjm-stroke-${kebab(name)}`] = `${value}px`;\n }\n // Unset before 1.4.1, so focus rules were invalid and drew no ring.\n style[\"--hjm-color-focus\"] = resolveColorReference(focusIndicatorContract.color, palette);\n style[\"--hjm-focus-width\"] = `${focusIndicatorContract.width}px`;\n style[\"--hjm-focus-offset\"] = `${focusIndicatorContract.offset}px`;\n style[\"--hjm-bottom-navigation-pressed-background\"] = resolveColorReference(\n bottomNavigationRecipe.states.pressedBackground,\n palette,\n );\n // Row rhythm and the leading frame come from the recipe so the stylesheet\n // does not carry a second copy of the same numbers.\n style[\"--hjm-list-row-gap\"] = rem(listRowRecipe.gap);\n style[\"--hjm-list-row-leading-size\"] = rem(listRowRecipe.leadingSize);\n for (const [name, value] of Object.entries(switchRecipe.sizes)) {\n style[`--hjm-switch-${kebab(name)}-width`] = rem(value.width);\n style[`--hjm-switch-${kebab(name)}-height`] = rem(value.height);\n style[`--hjm-switch-${kebab(name)}-thumb`] = rem(value.thumb);\n style[`--hjm-switch-${kebab(name)}-inset`] = rem(value.inset);\n style[`--hjm-switch-${kebab(name)}-offset`] = rem(\n value.width - value.thumb - value.inset * 2,\n );\n }\n for (const [name, value] of Object.entries(listRowRecipe.density)) {\n style[`--hjm-list-row-${kebab(name)}-one-line`] = rem(value.oneLineMinHeight);\n style[`--hjm-list-row-${kebab(name)}-two-line`] = rem(value.twoLineMinHeight);\n style[`--hjm-list-row-${kebab(name)}-padding-inline`] = rem(value.paddingHorizontal);\n style[`--hjm-list-row-${kebab(name)}-padding-block`] = rem(value.paddingVertical);\n }\n // The recipe owns these; a second copy in the stylesheet drifts silently\n // because the gates read that file as text only. Block and text heights\n // already resolve through --hjm-space-*, so they are not re-emitted.\n const skeletonCurve = easing[skeletonRecipe.animation.easing];\n style[\"--hjm-skeleton-circle-size\"] =\n `${skeletonRecipe.shapes.circle.defaultHeight}px`;\n style[\"--hjm-skeleton-duration\"] = `${skeletonRecipe.animation.duration}ms`;\n style[\"--hjm-skeleton-easing\"] = `cubic-bezier(${skeletonCurve.join(\", \")})`;\n style[\"--hjm-skeleton-from-opacity\"] = skeletonRecipe.animation.fromOpacity;\n style[\"--hjm-skeleton-to-opacity\"] = skeletonRecipe.animation.toOpacity;\n for (const [name, token] of Object.entries(shadow)) {\n style[`--hjm-shadow-${kebab(name)}`] = shadowCss(token);\n }\n // Overlay chrome and sizes come from the recipes Native reads (1.5.0).\n for (const [name, chrome] of [[\"dialog\", dialogRecipe.content], [\"sheet\", sheetRecipe.content], [\"toast\", toastRecipe.surface]] as const) {\n style[`--hjm-${name}-background`] = resolveColorReference(chrome.background, palette);\n style[`--hjm-${name}-border`] = resolveColorReference(chrome.border, palette);\n style[`--hjm-${name}-border-width`] = `${chrome.borderWidth}px`;\n style[`--hjm-${name}-radius`] = `var(--hjm-radius-${chrome.radius})`;\n style[`--hjm-${name}-shadow`] = shadowCss(chrome.shadow);\n }\n style[\"--hjm-sheet-max-height\"] = `${sheetRecipe.content.maxHeightRatio * 100}dvh`;\n style[\"--hjm-sheet-max-width\"] = `${sheetRecipe.web.maxWidth}px`;\n style[\"--hjm-sheet-handle-width\"] = `${sheetRecipe.handle.width}px`;\n style[\"--hjm-sheet-handle-height\"] = `${sheetRecipe.handle.height}px`;\n style[\"--hjm-sheet-handle-color\"] = resolveColorReference(sheetRecipe.handle.color, palette);\n for (const [name, ratio] of Object.entries(sheetRecipe.sizes)) {\n if (ratio !== null) style[`--hjm-sheet-size-${name}`] = `${ratio * 100}dvh`;\n }\n const toastExit = toastRecipe.transition.web.exit;\n style[\"--hjm-toast-exit-duration\"] = environment.reducedMotion ? \"0ms\" : `${toastExit.duration}ms`;\n style[\"--hjm-toast-exit-easing\"] = `cubic-bezier(${easing[toastExit.easing].join(\", \")})`;\n style[\"--hjm-button-pressed-opacity\"] = buttonRecipe.opacity.pressed;\n style[\"--hjm-button-disabled-opacity\"] = buttonRecipe.opacity.disabled;\n style[\"--hjm-field-border-width\"] = `${fieldRecipe.borderWidth}px`;\n style[\"--hjm-field-focus-ring-width\"] = `${fieldRecipe.focusRingWidth}px`;\n style[\"--hjm-field-disabled-opacity\"] = fieldRecipe.disabledOpacity;\n style[\"--hjm-control-min-touch-target\"] = `${control.minTouchTarget}px`;\n style[\"--hjm-control-field-height\"] = `${control.fieldHeight}px`;\n style[\"--hjm-field-multiline-min-height\"] = rem(fieldRecipe.multilineMinHeight);\n style[\"--hjm-field-padding-block\"] = rem(fieldRecipe.paddingVertical);\n for (const [name, value] of Object.entries(control.buttonHeight)) {\n // The axis is applied to the emitted variables rather than to each rule so\n // that every stylesheet consumer of a control height honours it at once.\n style[`--hjm-control-button-${kebab(name)}`] =\n `${visibleControlHeight(value, environment.minimumVisualTarget)}px`;\n }\n\n return style;\n}\n"]}
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n backdrop,\n control,\n easing,\n fontFamily,\n fontWeight,\n motion,\n radius,\n shadow,\n spacing,\n stroke,\n typography,\n} from \"@hjmds/design-contracts/foundations\";\nimport { resolveColorReference } from \"@hjmds/design-contracts/color-references\";\nimport { focusIndicatorContract } from \"@hjmds/design-contracts/contracts\";\nimport {\n visibleControlHeight,\n type DesignSystemProviderValue,\n} from \"@hjmds/design-contracts/components/design-system-provider\";\nimport { buttonRecipe, fieldRecipe } from \"@hjmds/design-contracts/recipes/base\";\nimport {\n bottomNavigationRecipe,\n dialogRecipe,\n listRowRecipe,\n sheetRecipe,\n skeletonRecipe,\n switchRecipe,\n toastRecipe,\n} from \"@hjmds/design-contracts/recipes\";\nimport type { CSSProperties } from \"react\";\n\nexport type HjmThemeStyle = CSSProperties &\n Record<`--hjm-${string}`, string | number>;\n\nfunction kebab(value: string): string {\n return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\ntype ShadowToken = Readonly<{ color: string; opacity: number; radius: number; offsetY: number }>;\n\n// RN shadow token -> CSS; blur = radius, as react-native-web maps it.\nfunction shadowCss(token: ShadowToken): string {\n const hex = token.color.replace(\"#\", \"\");\n const [r, g, b] = [0, 2, 4].map((start) => Number.parseInt(hex.slice(start, start + 2), 16));\n return `0 ${token.offsetY}px ${token.radius}px rgb(${r} ${g} ${b} / ${Math.round(token.opacity * 100)}%)`;\n}\n\nfunction rem(value: number): string {\n return `${Number((value / 16).toFixed(5))}rem`;\n}\n\nexport function createHjmThemeStyle(\n value: DesignSystemProviderValue,\n): HjmThemeStyle {\n const { environment, palette } = value;\n const style: HjmThemeStyle = {\n \"--hjm-backdrop-modal\": `color-mix(in srgb, ${backdrop.modal.color} ${backdrop.modal.opacity * 100}%, transparent)`,\n \"--hjm-text-scale\": environment.textScale,\n \"--hjm-motion-scale\": environment.reducedMotion ? 0 : 1,\n colorScheme: environment.theme,\n backgroundColor: palette.theme.bg,\n color: palette.theme.text,\n };\n\n for (const [name, color] of Object.entries(palette.theme)) {\n style[`--hjm-color-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccents)) {\n style[`--hjm-accent-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccentFills)) {\n style[`--hjm-accent-fill-${kebab(name)}`] = color;\n }\n for (const [name, value] of Object.entries(spacing)) {\n style[`--hjm-space-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(radius)) {\n style[`--hjm-radius-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(typography)) {\n style[`--hjm-type-${kebab(name)}-size`] =\n `calc(${rem(value.fontSize)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-line-height`] =\n `calc(${rem(value.lineHeight)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-weight`] = value.fontWeight;\n }\n for (const [name, value] of Object.entries(fontWeight)) {\n style[`--hjm-font-weight-${kebab(name)}`] = value;\n }\n for (const [name, value] of Object.entries(motion)) {\n style[`--hjm-motion-${kebab(name)}`] = environment.reducedMotion\n ? \"0ms\"\n : `${value}ms`;\n }\n\n style[\"--hjm-font-family-ui\"] = fontFamily.ui.join(\", \");\n for (const [name, value] of Object.entries(stroke)) {\n style[`--hjm-stroke-${kebab(name)}`] = `${value}px`;\n }\n // Unset before 1.4.1, so focus rules were invalid and drew no ring.\n style[\"--hjm-color-focus\"] = resolveColorReference(focusIndicatorContract.color, palette);\n style[\"--hjm-focus-width\"] = `${focusIndicatorContract.width}px`;\n style[\"--hjm-focus-offset\"] = `${focusIndicatorContract.offset}px`;\n style[\"--hjm-bottom-navigation-pressed-background\"] = resolveColorReference(\n bottomNavigationRecipe.states.pressedBackground,\n palette,\n );\n // Row rhythm and the leading frame come from the recipe so the stylesheet\n // does not carry a second copy of the same numbers.\n style[\"--hjm-list-row-gap\"] = rem(listRowRecipe.gap);\n style[\"--hjm-list-row-leading-size\"] = rem(listRowRecipe.leadingSize);\n for (const [name, value] of Object.entries(switchRecipe.sizes)) {\n style[`--hjm-switch-${kebab(name)}-width`] = rem(value.width);\n style[`--hjm-switch-${kebab(name)}-height`] = rem(value.height);\n style[`--hjm-switch-${kebab(name)}-thumb`] = rem(value.thumb);\n style[`--hjm-switch-${kebab(name)}-inset`] = rem(value.inset);\n style[`--hjm-switch-${kebab(name)}-offset`] = rem(\n value.width - value.thumb - value.inset * 2,\n );\n }\n for (const [name, value] of Object.entries(listRowRecipe.density)) {\n style[`--hjm-list-row-${kebab(name)}-one-line`] = rem(value.oneLineMinHeight);\n style[`--hjm-list-row-${kebab(name)}-two-line`] = rem(value.twoLineMinHeight);\n style[`--hjm-list-row-${kebab(name)}-padding-inline`] = rem(value.paddingHorizontal);\n style[`--hjm-list-row-${kebab(name)}-padding-block`] = rem(value.paddingVertical);\n }\n // The recipe owns these; a second copy in the stylesheet drifts silently\n // because the gates read that file as text only. Block and text heights\n // already resolve through --hjm-space-*, so they are not re-emitted.\n const skeletonCurve = easing[skeletonRecipe.animation.easing];\n style[\"--hjm-skeleton-circle-size\"] =\n `${skeletonRecipe.shapes.circle.defaultHeight}px`;\n style[\"--hjm-skeleton-duration\"] = `${skeletonRecipe.animation.duration}ms`;\n style[\"--hjm-skeleton-easing\"] = `cubic-bezier(${skeletonCurve.join(\", \")})`;\n style[\"--hjm-skeleton-from-opacity\"] = skeletonRecipe.animation.fromOpacity;\n style[\"--hjm-skeleton-to-opacity\"] = skeletonRecipe.animation.toOpacity;\n for (const [name, token] of Object.entries(shadow)) {\n style[`--hjm-shadow-${kebab(name)}`] = shadowCss(token);\n }\n // Overlay chrome and sizes come from the recipes Native reads (1.5.0).\n for (const [name, chrome] of [[\"dialog\", dialogRecipe.content], [\"sheet\", sheetRecipe.content], [\"toast\", toastRecipe.surface]] as const) {\n style[`--hjm-${name}-background`] = resolveColorReference(chrome.background, palette);\n style[`--hjm-${name}-border`] = resolveColorReference(chrome.border, palette);\n style[`--hjm-${name}-border-width`] = `${chrome.borderWidth}px`;\n style[`--hjm-${name}-radius`] = `var(--hjm-radius-${chrome.radius})`;\n style[`--hjm-${name}-shadow`] = shadowCss(chrome.shadow);\n }\n style[\"--hjm-sheet-max-height\"] = `${sheetRecipe.content.maxHeightRatio * 100}dvh`;\n style[\"--hjm-sheet-max-width\"] = `${sheetRecipe.web.maxWidth}px`;\n style[\"--hjm-sheet-handle-width\"] = `${sheetRecipe.handle.width}px`;\n style[\"--hjm-sheet-handle-height\"] = `${sheetRecipe.handle.height}px`;\n style[\"--hjm-sheet-handle-color\"] = resolveColorReference(sheetRecipe.handle.color, palette);\n for (const [name, ratio] of Object.entries(sheetRecipe.sizes)) {\n if (ratio !== null) style[`--hjm-sheet-size-${name}`] = `${ratio * 100}dvh`;\n }\n const toastExit = toastRecipe.transition.web.exit;\n style[\"--hjm-toast-exit-duration\"] = environment.reducedMotion ? \"0ms\" : `${toastExit.duration}ms`;\n style[\"--hjm-toast-exit-easing\"] = `cubic-bezier(${easing[toastExit.easing].join(\", \")})`;\n style[\"--hjm-button-pressed-opacity\"] = buttonRecipe.opacity.pressed;\n style[\"--hjm-button-disabled-opacity\"] = buttonRecipe.opacity.disabled;\n style[\"--hjm-field-border-width\"] = `${fieldRecipe.borderWidth}px`;\n style[\"--hjm-field-focus-ring-width\"] = `${fieldRecipe.focusRingWidth}px`;\n style[\"--hjm-field-disabled-opacity\"] = fieldRecipe.disabledOpacity;\n style[\"--hjm-control-min-touch-target\"] = `${control.minTouchTarget}px`;\n style[\"--hjm-control-field-height\"] = `${control.fieldHeight}px`;\n style[\"--hjm-field-multiline-min-height\"] = rem(fieldRecipe.multilineMinHeight);\n style[\"--hjm-field-padding-block\"] = rem(fieldRecipe.paddingVertical);\n for (const [name, value] of Object.entries(control.buttonHeight)) {\n // The axis is applied to the emitted variables rather than to each rule so\n // that every stylesheet consumer of a control height honours it at once.\n style[`--hjm-control-button-${kebab(name)}`] =\n `${visibleControlHeight(value, environment.minimumVisualTarget)}px`;\n }\n\n return style;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { type CSSProperties } from "react";
2
+ import { type ThinkingOrbOptions } from "@hjmds/design-contracts/components/thinking-orb";
3
+ export type ThinkingOrbProps = ThinkingOrbOptions & Readonly<{
4
+ className?: string;
5
+ style?: CSSProperties;
6
+ }>;
7
+ /** Optional AI status presentation; ordinary loading retains Spinner. */
8
+ export declare function ThinkingOrb({ state, size, label, speed, paused, active, className, style }: ThinkingOrbProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=thinking-orb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thinking-orb.d.ts","sourceRoot":"","sources":["../src/thinking-orb.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAyF,KAAK,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAGjL,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG,QAAQ,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC,CAAC;AAC5G,yEAAyE;AACzE,wBAAgB,WAAW,CAAC,EAAE,KAAiB,EAAE,IAAS,EAAE,KAAK,EAAE,KAAS,EAAE,MAAc,EAAE,MAAa,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,gBAAgB,+BAgEhJ"}
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from "react";
3
+ import { buildThinkingOrbFrame, createThinkingOrbClock, thinkingOrbRecipe, validateThinkingOrb } from "@hjmds/design-contracts/components/thinking-orb";
4
+ import { useHjmTheme } from "./provider.js";
5
+ /** Optional AI status presentation; ordinary loading retains Spinner. */
6
+ export function ThinkingOrb({ state = "working", size = 64, label, speed = 1, paused = false, active = true, className, style }) {
7
+ validateThinkingOrb({ state, size, speed, label });
8
+ const theme = useHjmTheme();
9
+ const ink = theme.palette.theme.text;
10
+ const reduced = theme.environment.reducedMotion;
11
+ const canvasRef = useRef(null);
12
+ const clock = useRef(createThinkingOrbClock());
13
+ useEffect(() => {
14
+ const canvas = canvasRef.current;
15
+ const ctx = canvas?.getContext("2d");
16
+ if (!canvas || !ctx)
17
+ return;
18
+ let ratio = 1;
19
+ let raf = 0;
20
+ let visible = typeof IntersectionObserver === "undefined";
21
+ let disposed = false;
22
+ const draw = () => {
23
+ const frame = buildThinkingOrbFrame(state, size, reduced ? thinkingOrbRecipe.motion.staticTime : clock.current.time);
24
+ ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
25
+ ctx.clearRect(0, 0, size, size);
26
+ ctx.fillStyle = ctx.strokeStyle = ink;
27
+ // Depth becomes semantic-ink opacity, so brand palettes work on any HJM surface.
28
+ for (const line of frame.lines) {
29
+ ctx.globalAlpha = (1 - Math.min(1, Math.max(0, line.white))) * (line.a ?? 1);
30
+ ctx.lineWidth = line.w;
31
+ ctx.beginPath();
32
+ ctx.moveTo(line.x1, line.y1);
33
+ ctx.lineTo(line.x2, line.y2);
34
+ ctx.stroke();
35
+ }
36
+ for (const dot of frame.dots) {
37
+ ctx.globalAlpha = (1 - Math.min(1, Math.max(0, dot.white))) * (dot.a ?? 1);
38
+ ctx.beginPath();
39
+ ctx.arc(dot.x, dot.y, dot.r, 0, Math.PI * 2);
40
+ ctx.fill();
41
+ }
42
+ ctx.globalAlpha = 1;
43
+ };
44
+ const resize = () => {
45
+ ratio = Math.min(thinkingOrbRecipe.maxPixelRatio, window.devicePixelRatio || 1);
46
+ canvas.width = Math.round(size * ratio);
47
+ canvas.height = Math.round(size * ratio);
48
+ draw();
49
+ };
50
+ const eligible = () => !disposed && active && !paused && !reduced && visible && document.visibilityState !== "hidden";
51
+ const loop = (now) => {
52
+ raf = 0;
53
+ if (!eligible())
54
+ return;
55
+ clock.current.sample(now, speed);
56
+ draw();
57
+ raf = requestAnimationFrame(loop);
58
+ };
59
+ const sync = () => {
60
+ cancelAnimationFrame(raf);
61
+ raf = 0;
62
+ clock.current.resetDelta();
63
+ if (eligible())
64
+ raf = requestAnimationFrame(loop);
65
+ };
66
+ const observer = typeof IntersectionObserver === "undefined" ? null : new IntersectionObserver(entries => {
67
+ visible = entries[0]?.isIntersecting ?? false;
68
+ sync();
69
+ });
70
+ resize();
71
+ observer?.observe(canvas);
72
+ sync();
73
+ document.addEventListener("visibilitychange", sync);
74
+ window.addEventListener("resize", resize);
75
+ return () => {
76
+ disposed = true;
77
+ cancelAnimationFrame(raf);
78
+ observer?.disconnect();
79
+ clock.current.resetDelta();
80
+ document.removeEventListener("visibilitychange", sync);
81
+ window.removeEventListener("resize", resize);
82
+ };
83
+ }, [state, size, speed, active, paused, reduced, ink]);
84
+ return _jsxs("span", { className: className, "data-hjm-thinking-orb": state, role: "status", "aria-live": "polite", "aria-atomic": "true", style: { display: "inline-flex", ...style }, children: [_jsx("canvas", { ref: canvasRef, "aria-hidden": "true", style: { width: size, height: size, display: "block" } }), _jsx("span", { style: { position: "absolute", width: 1, height: 1, padding: 0, margin: -1, overflow: "hidden", clipPath: "inset(50%)", whiteSpace: "nowrap", border: 0 }, children: label })] });
85
+ }
86
+ //# sourceMappingURL=thinking-orb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thinking-orb.js","sourceRoot":"","sources":["../src/thinking-orb.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, type CSSProperties } from \"react\";\nimport { buildThinkingOrbFrame, createThinkingOrbClock, thinkingOrbRecipe, validateThinkingOrb, type ThinkingOrbOptions } from \"@hjmds/design-contracts/components/thinking-orb\";\nimport { useHjmTheme } from \"./provider.js\";\n\nexport type ThinkingOrbProps = ThinkingOrbOptions & Readonly<{ className?: string; style?: CSSProperties }>;\n/** Optional AI status presentation; ordinary loading retains Spinner. */\nexport function ThinkingOrb({ state = \"working\", size = 64, label, speed = 1, paused = false, active = true, className, style }: ThinkingOrbProps) {\n validateThinkingOrb({ state, size, speed, label });\n const theme = useHjmTheme();\n const ink = theme.palette.theme.text;\n const reduced = theme.environment.reducedMotion;\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const clock = useRef(createThinkingOrbClock());\n useEffect(() => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!canvas || !ctx) return;\n let ratio = 1;\n let raf = 0;\n let visible = typeof IntersectionObserver === \"undefined\";\n let disposed = false;\n const draw = () => {\n const frame = buildThinkingOrbFrame(state, size, reduced ? thinkingOrbRecipe.motion.staticTime : clock.current.time);\n ctx.setTransform(ratio, 0, 0, ratio, 0, 0);\n ctx.clearRect(0, 0, size, size);\n ctx.fillStyle = ctx.strokeStyle = ink;\n // Depth becomes semantic-ink opacity, so brand palettes work on any HJM surface.\n for (const line of frame.lines) {\n ctx.globalAlpha = (1 - Math.min(1, Math.max(0, line.white))) * (line.a ?? 1);\n ctx.lineWidth = line.w;\n ctx.beginPath(); ctx.moveTo(line.x1, line.y1); ctx.lineTo(line.x2, line.y2); ctx.stroke();\n }\n for (const dot of frame.dots) {\n ctx.globalAlpha = (1 - Math.min(1, Math.max(0, dot.white))) * (dot.a ?? 1);\n ctx.beginPath(); ctx.arc(dot.x, dot.y, dot.r, 0, Math.PI * 2); ctx.fill();\n }\n ctx.globalAlpha = 1;\n };\n const resize = () => {\n ratio = Math.min(thinkingOrbRecipe.maxPixelRatio, window.devicePixelRatio || 1);\n canvas.width = Math.round(size * ratio); canvas.height = Math.round(size * ratio);\n draw();\n };\n const eligible = () => !disposed && active && !paused && !reduced && visible && document.visibilityState !== \"hidden\";\n const loop = (now: number) => {\n raf = 0;\n if (!eligible()) return;\n clock.current.sample(now, speed); draw();\n raf = requestAnimationFrame(loop);\n };\n const sync = () => {\n cancelAnimationFrame(raf); raf = 0; clock.current.resetDelta();\n if (eligible()) raf = requestAnimationFrame(loop);\n };\n const observer = typeof IntersectionObserver === \"undefined\" ? null : new IntersectionObserver(entries => {\n visible = entries[0]?.isIntersecting ?? false; sync();\n });\n resize(); observer?.observe(canvas); sync();\n document.addEventListener(\"visibilitychange\", sync);\n window.addEventListener(\"resize\", resize);\n return () => {\n disposed = true; cancelAnimationFrame(raf); observer?.disconnect(); clock.current.resetDelta();\n document.removeEventListener(\"visibilitychange\", sync); window.removeEventListener(\"resize\", resize);\n };\n }, [state, size, speed, active, paused, reduced, ink]);\n return <span className={className} data-hjm-thinking-orb={state} role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" style={{ display: \"inline-flex\", ...style }}>\n <canvas ref={canvasRef} aria-hidden=\"true\" style={{ width: size, height: size, display: \"block\" }} />\n {/* Inline hiding works for granular consumers who do not import the stylesheet. */}\n <span style={{ position: \"absolute\", width: 1, height: 1, padding: 0, margin: -1, overflow: \"hidden\", clipPath: \"inset(50%)\", whiteSpace: \"nowrap\", border: 0 }}>{label}</span>\n </span>;\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { type ReactNode } from "react";
2
+ export type VirtualListProps<T> = {
3
+ items: readonly T[];
4
+ keyExtractor: (item: T) => string;
5
+ renderItem: (item: T, index: number) => ReactNode;
6
+ rowHeight: number;
7
+ height: number;
8
+ label: string;
9
+ empty?: ReactNode;
10
+ overscan?: number;
11
+ };
12
+ /** Fixed-height rows are an explicit host contract; use List for unconstrained flowing copy. */
13
+ export declare function VirtualList<T>({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan }: VirtualListProps<T>): import("react").JSX.Element;
14
+ //# sourceMappingURL=virtual-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-list.d.ts","sourceRoot":"","sources":["../src/virtual-list.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1F,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAAC,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAAC,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACxO,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAY,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BA+BrI"}
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useId, useLayoutEffect, useMemo, useRef, useState } from "react";
3
+ import { resolveVirtualWindow, validateListKeys } from "@hjmds/design-contracts/components/virtual-list";
4
+ /** Fixed-height rows are an explicit host contract; use List for unconstrained flowing copy. */
5
+ export function VirtualList({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan = 3 }) {
6
+ const keys = useMemo(() => items.map(keyExtractor), [items, keyExtractor]);
7
+ validateListKeys(keys, label);
8
+ const [scrollTop, setScrollTop] = useState(0);
9
+ const [active, setActive] = useState(0);
10
+ const [focused, setFocused] = useState(null);
11
+ const host = useRef(null);
12
+ const moveFocus = useRef(false);
13
+ const id = useId();
14
+ const range = resolveVirtualWindow(items.length, rowHeight, height, scrollTop, overscan);
15
+ const selected = Math.min(active, Math.max(0, items.length - 1));
16
+ useLayoutEffect(() => { if (host.current && host.current.scrollTop !== range.offset)
17
+ host.current.scrollTop = range.offset; }, [range.offset]);
18
+ useLayoutEffect(() => { if (moveFocus.current) {
19
+ document.getElementById(`${id}-${selected}`)?.focus({ preventScroll: true });
20
+ moveFocus.current = false;
21
+ } }, [selected, id]);
22
+ // Keep keyboard/descendant focus mounted when wheel scrolling moves it outside the window.
23
+ const indices = [...new Set([...Array.from({ length: range.end - range.start }, (_, i) => i + range.start), ...(items.length ? [selected] : []), ...(focused !== null && focused < items.length ? [focused] : [])])].sort((a, b) => a - b);
24
+ return _jsx("div", { "data-hjm-virtual-list": true, className: "hjm-virtual-list", ref: host, role: "list", "aria-label": label, tabIndex: 0, style: { overflowY: "auto", height, position: "relative" }, onScroll: event => setScrollTop(event.currentTarget.scrollTop), onKeyDown: event => {
25
+ if (!items.length || !(event.target instanceof HTMLElement) || (event.target !== event.currentTarget && !event.target.hasAttribute("data-virtual-row")))
26
+ return;
27
+ const next = event.key === "ArrowDown" ? Math.min(selected + 1, items.length - 1) : event.key === "ArrowUp" ? Math.max(0, selected - 1) : event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : null;
28
+ if (next === null)
29
+ return;
30
+ event.preventDefault();
31
+ moveFocus.current = true;
32
+ setActive(next);
33
+ const top = next * rowHeight;
34
+ const viewport = event.currentTarget;
35
+ if (top < viewport.scrollTop)
36
+ viewport.scrollTop = top;
37
+ else if (top + rowHeight > viewport.scrollTop + height)
38
+ viewport.scrollTop = top + rowHeight - height;
39
+ setScrollTop(viewport.scrollTop);
40
+ const rendered = document.getElementById(`${id}-${next}`);
41
+ if (rendered) {
42
+ rendered.focus({ preventScroll: true });
43
+ moveFocus.current = false;
44
+ }
45
+ }, children: !items.length ? empty : _jsx("div", { style: { position: "relative", height: range.totalHeight }, children: indices.map(index => _jsx("div", { id: `${id}-${index}`, role: "listitem", "data-virtual-row": true, className: "hjm-virtual-list__row", tabIndex: index === selected ? 0 : -1, "aria-setsize": items.length, "aria-posinset": index + 1, onFocusCapture: () => setFocused(index), onBlurCapture: event => { if (!event.currentTarget.contains(event.relatedTarget))
46
+ setFocused(null); }, style: { position: "absolute", top: index * rowHeight, height: rowHeight, width: "100%" }, children: renderItem(items[index], index) }, keys[index])) }) });
47
+ }
48
+ //# sourceMappingURL=virtual-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-list.js","sourceRoot":"","sources":["../src/virtual-list.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useId, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { resolveVirtualWindow, validateListKeys } from \"@hjmds/design-contracts/components/virtual-list\";\nexport type VirtualListProps<T> = { items: readonly T[]; keyExtractor: (item: T) => string; renderItem: (item: T, index: number) => ReactNode; rowHeight: number; height: number; label: string; empty?: ReactNode; overscan?: number };\n/** Fixed-height rows are an explicit host contract; use List for unconstrained flowing copy. */\nexport function VirtualList<T>({ items, keyExtractor, renderItem, rowHeight, height, label, empty, overscan = 3 }: VirtualListProps<T>) {\n const keys = useMemo(() => items.map(keyExtractor), [items, keyExtractor]); validateListKeys(keys, label);\n const [scrollTop, setScrollTop] = useState(0);\n const [active, setActive] = useState(0);\n const [focused, setFocused] = useState<number | null>(null);\n const host = useRef<HTMLDivElement>(null); const moveFocus = useRef(false); const id = useId();\n const range = resolveVirtualWindow(items.length, rowHeight, height, scrollTop, overscan);\n const selected = Math.min(active, Math.max(0, items.length - 1));\n useLayoutEffect(() => { if (host.current && host.current.scrollTop !== range.offset) host.current.scrollTop = range.offset; }, [range.offset]);\n useLayoutEffect(() => { if (moveFocus.current) { document.getElementById(`${id}-${selected}`)?.focus({ preventScroll: true }); moveFocus.current = false; } }, [selected, id]);\n // Keep keyboard/descendant focus mounted when wheel scrolling moves it outside the window.\n const indices = [...new Set([...Array.from({ length: range.end - range.start }, (_, i) => i + range.start), ...(items.length ? [selected] : []), ...(focused !== null && focused < items.length ? [focused] : [])])].sort((a,b) => a-b);\n return <div data-hjm-virtual-list className=\"hjm-virtual-list\" ref={host} role=\"list\" aria-label={label} tabIndex={0}\n style={{ overflowY: \"auto\", height, position: \"relative\" }} onScroll={event => setScrollTop(event.currentTarget.scrollTop)}\n onKeyDown={event => {\n if (!items.length || !(event.target instanceof HTMLElement) || (event.target !== event.currentTarget && !event.target.hasAttribute(\"data-virtual-row\"))) return;\n const next = event.key === \"ArrowDown\" ? Math.min(selected + 1, items.length - 1) : event.key === \"ArrowUp\" ? Math.max(0, selected - 1) : event.key === \"Home\" ? 0 : event.key === \"End\" ? items.length - 1 : null;\n if (next === null) return; event.preventDefault(); moveFocus.current = true; setActive(next);\n const top = next * rowHeight; const viewport = event.currentTarget;\n if (top < viewport.scrollTop) viewport.scrollTop = top;\n else if (top + rowHeight > viewport.scrollTop + height) viewport.scrollTop = top + rowHeight - height;\n setScrollTop(viewport.scrollTop);\n const rendered = document.getElementById(`${id}-${next}`);\n if (rendered) { rendered.focus({ preventScroll: true }); moveFocus.current = false; }\n }}>\n {!items.length ? empty : <div style={{ position: \"relative\", height: range.totalHeight }}>\n {indices.map(index => <div key={keys[index]} id={`${id}-${index}`} role=\"listitem\" data-virtual-row className=\"hjm-virtual-list__row\" tabIndex={index === selected ? 0 : -1} aria-setsize={items.length} aria-posinset={index + 1}\n onFocusCapture={() => setFocused(index)} onBlurCapture={event => { if (!event.currentTarget.contains(event.relatedTarget)) setFocused(null); }}\n style={{ position: \"absolute\", top: index * rowHeight, height: rowHeight, width: \"100%\" }}>{renderItem(items[index]!, index)}</div>)}\n </div>}\n </div>;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hjmds/react",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "Accessible React 19 renderers for HJM design contracts.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -293,18 +293,56 @@
293
293
  "import": "./dist/evidence.js",
294
294
  "default": "./dist/evidence.js"
295
295
  },
296
+ "./thinking-orb": {
297
+ "types": "./dist/thinking-orb.d.ts",
298
+ "import": "./dist/thinking-orb.js",
299
+ "default": "./dist/thinking-orb.js"
300
+ },
301
+ "./statistic-motion": {
302
+ "types": "./dist/statistic-motion.d.ts",
303
+ "import": "./dist/statistic-motion.js",
304
+ "default": "./dist/statistic-motion.js"
305
+ },
306
+ "./menu-morph": {
307
+ "types": "./dist/menu-morph.d.ts",
308
+ "import": "./dist/menu-morph.js",
309
+ "default": "./dist/menu-morph.js"
310
+ },
311
+ "./masonry": {
312
+ "types": "./dist/masonry.d.ts",
313
+ "react-native": "./dist/masonry.js",
314
+ "import": "./dist/masonry.js",
315
+ "default": "./dist/masonry.js"
316
+ },
317
+ "./virtual-list": {
318
+ "types": "./dist/virtual-list.d.ts",
319
+ "react-native": "./dist/virtual-list.js",
320
+ "import": "./dist/virtual-list.js",
321
+ "default": "./dist/virtual-list.js"
322
+ },
323
+ "./qr-code": {
324
+ "types": "./dist/qr-code.d.ts",
325
+ "react-native": "./dist/qr-code.js",
326
+ "import": "./dist/qr-code.js",
327
+ "default": "./dist/qr-code.js"
328
+ },
296
329
  "./styles.css": "./dist/styles.css",
297
330
  "./styles.layered.css": "./dist/styles.layered.css"
298
331
  },
299
332
  "files": [
300
333
  "dist",
301
334
  "README.md",
302
- "LICENSE"
335
+ "LICENSE",
336
+ "THIRD_PARTY_NOTICES.md"
303
337
  ],
304
338
  "peerDependencies": {
305
- "@hjmds/design-contracts": ">=1.6.0 <1.7.0",
339
+ "@hjmds/design-contracts": ">=1.8.0 <1.9.0",
306
340
  "react": ">=19.0.0",
307
- "react-dom": ">=19.0.0"
341
+ "react-dom": ">=19.0.0",
342
+ "@number-flow/react": "0.6.2",
343
+ "bloom-menu": "0.1.0",
344
+ "framer-motion": "13.4.4",
345
+ "qrcode-generator": "2.0.4"
308
346
  },
309
347
  "devDependencies": {
310
348
  "@types/node": "^24.13.3",
@@ -316,7 +354,25 @@
316
354
  "react-dom": "19.2.3",
317
355
  "typescript": "^5.9.3",
318
356
  "vitest": "^4.1.11",
319
- "@hjmds/design-contracts": "1.6.0"
357
+ "@number-flow/react": "0.6.2",
358
+ "bloom-menu": "0.1.0",
359
+ "framer-motion": "13.4.4",
360
+ "qrcode-generator": "2.0.4",
361
+ "@hjmds/design-contracts": "1.8.0"
362
+ },
363
+ "peerDependenciesMeta": {
364
+ "@number-flow/react": {
365
+ "optional": true
366
+ },
367
+ "bloom-menu": {
368
+ "optional": true
369
+ },
370
+ "framer-motion": {
371
+ "optional": true
372
+ },
373
+ "qrcode-generator": {
374
+ "optional": true
375
+ }
320
376
  },
321
377
  "scripts": {
322
378
  "build": "tsc -p tsconfig.build.json && node scripts/copy-styles.mjs",