@hjmds/react 1.7.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.
- package/README.md +17 -0
- package/THIRD_PARTY_NOTICES.md +28 -0
- package/dist/advanced-display.d.ts +3 -1
- package/dist/advanced-display.d.ts.map +1 -1
- package/dist/advanced-display.js +2 -2
- package/dist/advanced-display.js.map +1 -1
- package/dist/context-menu.d.ts.map +1 -1
- package/dist/context-menu.js +36 -9
- package/dist/context-menu.js.map +1 -1
- package/dist/evidence.d.ts +61 -2
- package/dist/evidence.d.ts.map +1 -1
- package/dist/evidence.js +133 -64
- package/dist/evidence.js.map +1 -1
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +3 -2
- package/dist/layout.js.map +1 -1
- package/dist/masonry.d.ts +14 -0
- package/dist/masonry.d.ts.map +1 -0
- package/dist/masonry.js +13 -0
- package/dist/masonry.js.map +1 -0
- package/dist/menu-morph.d.ts +12 -0
- package/dist/menu-morph.d.ts.map +1 -0
- package/dist/menu-morph.js +79 -0
- package/dist/menu-morph.js.map +1 -0
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +13 -1
- package/dist/navigation.js.map +1 -1
- package/dist/qr-code.d.ts +11 -0
- package/dist/qr-code.d.ts.map +1 -0
- package/dist/qr-code.js +14 -0
- package/dist/qr-code.js.map +1 -0
- package/dist/statistic-motion.d.ts +12 -0
- package/dist/statistic-motion.d.ts.map +1 -0
- package/dist/statistic-motion.js +23 -0
- package/dist/statistic-motion.js.map +1 -0
- package/dist/styles.css +136 -133
- package/dist/styles.layered.css +136 -133
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +2 -1
- package/dist/theme.js.map +1 -1
- package/dist/thinking-orb.d.ts +9 -0
- package/dist/thinking-orb.d.ts.map +1 -0
- package/dist/thinking-orb.js +86 -0
- package/dist/thinking-orb.js.map +1 -0
- package/dist/virtual-list.d.ts +14 -0
- package/dist/virtual-list.d.ts.map +1 -0
- package/dist/virtual-list.js +48 -0
- package/dist/virtual-list.js.map +1 -0
- package/package.json +61 -5
package/dist/theme.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"
|
|
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.
|
|
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.
|
|
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
|
-
"@
|
|
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",
|