@hjmds/design-contracts 1.13.1 → 1.15.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/dist/agreement.d.ts +7 -1
- package/dist/agreement.d.ts.map +1 -1
- package/dist/agreement.js +14 -3
- package/dist/agreement.js.map +1 -1
- package/dist/behaviors.d.ts +1 -1
- package/dist/catalog.d.ts +4 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/content-transition.d.ts +17 -0
- package/dist/content-transition.d.ts.map +1 -1
- package/dist/content-transition.js +21 -0
- package/dist/content-transition.js.map +1 -1
- package/dist/date-entry.d.ts +71 -0
- package/dist/date-entry.d.ts.map +1 -0
- package/dist/date-entry.js +78 -0
- package/dist/date-entry.js.map +1 -0
- package/dist/design-profile-layout.d.ts +11 -0
- package/dist/design-profile-layout.d.ts.map +1 -0
- package/dist/design-profile-layout.js +18 -0
- package/dist/design-profile-layout.js.map +1 -0
- package/dist/design-profile.d.ts +89 -0
- package/dist/design-profile.d.ts.map +1 -0
- package/dist/design-profile.js +262 -0
- package/dist/design-profile.js.map +1 -0
- package/dist/design-system-provider.d.ts +6 -0
- package/dist/design-system-provider.d.ts.map +1 -1
- package/dist/design-system-provider.js +4 -2
- package/dist/design-system-provider.js.map +1 -1
- package/dist/document-resource.d.ts +104 -0
- package/dist/document-resource.d.ts.map +1 -0
- package/dist/document-resource.js +77 -0
- package/dist/document-resource.js.map +1 -0
- package/dist/effect-surface.d.ts +6 -1
- package/dist/effect-surface.d.ts.map +1 -1
- package/dist/effect-surface.js +5 -2
- package/dist/effect-surface.js.map +1 -1
- package/dist/field-group.d.ts +47 -0
- package/dist/field-group.d.ts.map +1 -0
- package/dist/field-group.js +92 -0
- package/dist/field-group.js.map +1 -0
- package/dist/gooey-navigation.d.ts +19 -1
- package/dist/gooey-navigation.d.ts.map +1 -1
- package/dist/gooey-navigation.js +37 -2
- package/dist/gooey-navigation.js.map +1 -1
- package/dist/image.d.ts +17 -0
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +19 -0
- package/dist/image.js.map +1 -1
- package/dist/internal/effect-noise.d.ts +2 -0
- package/dist/internal/effect-noise.d.ts.map +1 -0
- package/dist/internal/effect-noise.js +4 -0
- package/dist/internal/effect-noise.js.map +1 -0
- package/dist/palette-contrast.d.ts +6 -0
- package/dist/palette-contrast.d.ts.map +1 -1
- package/dist/palette-contrast.js +17 -0
- package/dist/palette-contrast.js.map +1 -1
- package/dist/progressive-blur.d.ts +32 -0
- package/dist/progressive-blur.d.ts.map +1 -0
- package/dist/progressive-blur.js +28 -0
- package/dist/progressive-blur.js.map +1 -0
- package/dist/reference-controls.d.ts +32 -0
- package/dist/reference-controls.d.ts.map +1 -0
- package/dist/reference-controls.js +28 -0
- package/dist/reference-controls.js.map +1 -0
- package/dist/screen-patterns.d.ts +16 -1
- package/dist/screen-patterns.d.ts.map +1 -1
- package/dist/screen-patterns.js +4 -0
- package/dist/screen-patterns.js.map +1 -1
- package/dist/scroll-progress.d.ts +7 -1
- package/dist/scroll-progress.d.ts.map +1 -1
- package/dist/scroll-progress.js +21 -2
- package/dist/scroll-progress.js.map +1 -1
- package/dist/text-annotation.d.ts +43 -0
- package/dist/text-annotation.d.ts.map +1 -0
- package/dist/text-annotation.js +137 -0
- package/dist/text-annotation.js.map +1 -0
- package/dist/toast-liquid.d.ts +3 -1
- package/dist/toast-liquid.d.ts.map +1 -1
- package/dist/toast-liquid.js +6 -2
- package/dist/toast-liquid.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/agreement.md +14 -0
- package/docs/asset.md +7 -0
- package/docs/brand-boundary.md +14 -5
- package/docs/code-block.md +12 -1
- package/docs/collapsible.md +6 -0
- package/docs/design-profile.md +263 -0
- package/docs/design-system-provider.md +7 -0
- package/docs/dialog.md +20 -1
- package/docs/effect-surface.md +19 -3
- package/docs/generated/component-maturity.md +1 -1
- package/docs/generated/renderer-evidence.json +3 -3
- package/docs/generated/renderer-evidence.md +1 -1
- package/docs/generated/showcase-manifest.json +1 -1
- package/docs/gooey-navigation.md +37 -6
- package/docs/heading.md +15 -0
- package/docs/image.md +17 -0
- package/docs/optional-adapters.md +25 -0
- package/docs/popover.md +15 -0
- package/docs/rating.md +6 -1
- package/docs/reference-controls.md +40 -0
- package/docs/task-list.md +15 -1
- package/docs/text-annotation.md +85 -0
- package/docs/theming.md +18 -5
- package/docs/usage/README.md +23 -1
- package/docs/usage/components/activity-heatmap.md +3 -1
- package/docs/usage/components/agreement.md +15 -3
- package/docs/usage/components/alert-dialog.md +16 -1
- package/docs/usage/components/asset.md +9 -2
- package/docs/usage/components/avatar.md +33 -1
- package/docs/usage/components/badge.md +3 -1
- package/docs/usage/components/bottom-cta.md +3 -1
- package/docs/usage/components/bottom-navigation.md +5 -1
- package/docs/usage/components/button.md +7 -1
- package/docs/usage/components/calendar.md +3 -1
- package/docs/usage/components/card.md +26 -3
- package/docs/usage/components/carousel.md +10 -1
- package/docs/usage/components/chat-message.md +11 -1
- package/docs/usage/components/chip.md +5 -0
- package/docs/usage/components/code-block.md +14 -2
- package/docs/usage/components/collapsible.md +10 -2
- package/docs/usage/components/combobox.md +12 -1
- package/docs/usage/components/command-palette.md +11 -6
- package/docs/usage/components/content-transition.md +29 -5
- package/docs/usage/components/context-menu.md +7 -1
- package/docs/usage/components/date-picker.md +3 -1
- package/docs/usage/components/design-system-provider.md +7 -5
- package/docs/usage/components/dialog.md +70 -1
- package/docs/usage/components/effect-surface.md +4 -2
- package/docs/usage/components/empty-state.md +10 -2
- package/docs/usage/components/field.md +26 -1
- package/docs/usage/components/form.md +13 -3
- package/docs/usage/components/heading.md +7 -1
- package/docs/usage/components/image-comparison.md +82 -0
- package/docs/usage/components/image.md +83 -2
- package/docs/usage/components/keyboard-avoiding.md +6 -1
- package/docs/usage/components/link.md +3 -1
- package/docs/usage/components/list-row.md +5 -1
- package/docs/usage/components/list.md +8 -1
- package/docs/usage/components/load-more.md +3 -1
- package/docs/usage/components/mentions.md +3 -1
- package/docs/usage/components/menu.md +3 -1
- package/docs/usage/components/menubar.md +7 -1
- package/docs/usage/components/message-composer.md +16 -5
- package/docs/usage/components/notice.md +9 -0
- package/docs/usage/components/number-field.md +3 -1
- package/docs/usage/components/onboarding-screen.md +16 -9
- package/docs/usage/components/overview-screen.md +73 -0
- package/docs/usage/components/password-field.md +5 -1
- package/docs/usage/components/popover.md +14 -1
- package/docs/usage/components/progress.md +28 -0
- package/docs/usage/components/progressive-blur.md +113 -0
- package/docs/usage/components/rating.md +74 -0
- package/docs/usage/components/saved-items-screen.md +3 -1
- package/docs/usage/components/screen-layout.md +9 -1
- package/docs/usage/components/search-field.md +13 -1
- package/docs/usage/components/search-screen.md +5 -0
- package/docs/usage/components/segmented-control.md +17 -0
- package/docs/usage/components/select.md +9 -0
- package/docs/usage/components/sheet.md +14 -1
- package/docs/usage/components/skeleton.md +9 -0
- package/docs/usage/components/slider.md +3 -1
- package/docs/usage/components/statistic.md +14 -1
- package/docs/usage/components/surface.md +8 -1
- package/docs/usage/components/tabs.md +11 -2
- package/docs/usage/components/tag.md +3 -1
- package/docs/usage/components/tags-input.md +11 -1
- package/docs/usage/components/text-area.md +3 -1
- package/docs/usage/components/text-transition.md +8 -2
- package/docs/usage/components/text.md +3 -1
- package/docs/usage/components/toast.md +23 -1
- package/docs/usage/components/top-bar.md +3 -1
- package/docs/usage/components/upload-item.md +3 -1
- package/docs/usage/compositions/action-feedback.md +77 -0
- package/docs/usage/compositions/adaptive-content.md +81 -0
- package/docs/usage/compositions/command-records.md +106 -0
- package/docs/usage/compositions/content-transition-comparison.md +108 -0
- package/docs/usage/compositions/context-toolbar.md +85 -0
- package/docs/usage/compositions/date-entry.md +108 -0
- package/docs/usage/compositions/date-time-selection.md +110 -0
- package/docs/usage/compositions/design-profile-comparison.md +114 -0
- package/docs/usage/compositions/document-resource.md +124 -0
- package/docs/usage/compositions/field-group.md +104 -0
- package/docs/usage/compositions/illustrated-outcome.md +91 -0
- package/docs/usage/compositions/live-list.md +104 -0
- package/docs/usage/compositions/optional-adapters.md +1 -1
- package/docs/usage/compositions/origin-dialog.md +108 -0
- package/docs/usage/compositions/selection-motion.md +73 -0
- package/docs/usage/compositions/texture-comparison.md +86 -0
- package/docs/usage/compositions/upload-recovery.md +80 -0
- package/docs/usage/compositions/video-dialog.md +100 -0
- package/docs/usage/screens/flow-onboarding.md +5 -3
- package/docs/usage/screens/product-bento.md +117 -0
- package/docs/usage/tokens/color.md +9 -2
- package/docs/usage/tokens/elevation-opacity.md +8 -1
- package/docs/usage/tokens/motion.md +10 -1
- package/docs/usage/tokens/radius.md +8 -1
- package/docs/usage/tokens/typography.md +15 -1
- package/package.json +49 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"design-system-provider.js","sourceRoot":"","sources":["../src/design-system-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ColorReferencePalette } from \"./color-references.js\";\nimport { control, largeTextThreshold } from \"./foundations.js\";\nimport {\n ACCENTS,\n THEMES,\n accentFill,\n isThemePreference,\n type ResolvedTheme,\n type ThemeColors,\n type ThemePreference,\n} from \"./colors.js\";\n\n/**\n * Canonical logical direction. Existing public component-specific names stay\n * source-compatible as aliases of this type instead of redeclaring the union.\n */\nexport type DesignSystemDirection = \"ltr\" | \"rtl\";\n\n/**\n * A continuous OS/user font-scale multiplier (iOS Dynamic Type, Android font\n * size, browser zoom) — not `ShowcaseTextScale`'s closed `1 | 1.5 | 2`, which\n * only names Showcase's five fixture stories, or `description-list.ts`'s\n * local layout clamp. This is the single upstream signal both now consume.\n */\nexport type DesignSystemTextScale = number;\n\n/**\n * Whether a resolved `textScale` has crossed into large-text layout. A\n * stylesheet cannot compare numbers, so the provider resolves the axis once and\n * publishes the result for surfaces that can only match a flag (#20).\n */\nexport function isLargeTextScale(textScale: DesignSystemTextScale): boolean {\n return Number.isFinite(textScale) && textScale >= largeTextThreshold;\n}\n\n/**\n * Visible height a compact control paints under a product's target-size policy.\n *\n * The compact recipes stay at 36 and reach the 44pt target through hit slop,\n * which satisfies WCAG 2.5.8 but not the stricter iOS/Android guidance some\n * products commit to. `minimumVisualTarget` turns that commitment into one\n * resolved axis, so both renderers compute the same geometry instead of each\n * consumer re-adding `minHeight` in product styles. It lives beside the axis\n * rather than in `foundations` because it is a policy over a token, not a token.\n */\nexport function visibleControlHeight(\n recipeHeight: number,\n minimumVisualTarget: boolean,\n): number {\n return minimumVisualTarget ? Math.max(recipeHeight, control.minTouchTarget) : recipeHeight;\n}\n\n/**\n * 한 화면 안에서 목록·메뉴·표가 각각 다른 밀도로 그려지던 문제를 하나의 축으로 모은다.\n * 지금까지는 `ListRow density`, `Menu density`, DataTable의 행 높이가 서로 모르는 값이라\n * 제품이 세 군데를 따로 맞췄다. 컴포넌트의 명시적 prop이 언제나 이 축을 이긴다 —\n * 전역값은 기본이지 강제가 아니다.\n *\n * OS 신호가 없다. 밀도는 제품의 입장(같은 화면에 얼마나 담을 것인가)이지 사용자 설정이\n * 아니라서 `system*` 짝을 두지 않았다. 반대로 큰 글자 설정은 사용자 설정이므로\n * `textScale`이 큰 상태에서 `compact`를 쓰는 것은 제품이 스스로 막아야 한다.\n */\nexport type DesignSystemDensity = \"comfortable\" | \"compact\";\n\n/**\n * 전역 밀도를 컴포넌트마다 다른 밀도 어휘로 옮긴다. 컴포넌트의 명시적 prop이 언제나\n * 이긴다 — 전역값은 기본이지 강제가 아니다. 어휘를 하나로 통일하지 않은 이유: 목록의\n * `relaxed`와 표의 `regular`는 같은 말이 아니고, 억지로 합치면 둘 중 하나가 거짓말을 한다.\n */\nexport function resolveDensityDefault<Comfortable extends string, Compact extends string>(\n density: DesignSystemDensity,\n vocabulary: Readonly<{ comfortable: Comfortable; compact: Compact }>,\n): Comfortable | Compact {\n return density === \"compact\" ? vocabulary.compact : vocabulary.comfortable;\n}\n\nexport type DesignSystemEnvironmentInput = Readonly<{\n theme?: ThemePreference;\n direction?: DesignSystemDirection;\n textScale?: DesignSystemTextScale;\n reducedMotion?: boolean;\n /**\n * Paint the minimum touch target as visible control geometry instead of\n * reaching it with hit slop. This is a product accessibility stance, not an\n * OS signal, so it has no `system*` counterpart.\n */\n minimumVisualTarget?: boolean;\n /** Default row/menu/table density for everything below this provider. */\n density?: DesignSystemDensity;\n}>;\n\nexport const designSystemEnvironmentDefaults = {\n theme: \"system\",\n direction: \"ltr\",\n textScale: 1,\n reducedMotion: false,\n minimumVisualTarget: false,\n density: \"comfortable\",\n} as const satisfies Readonly<{\n theme: ThemePreference;\n direction: DesignSystemDirection;\n textScale: DesignSystemTextScale;\n reducedMotion: boolean;\n minimumVisualTarget: boolean;\n density: DesignSystemDensity;\n}>;\n\nexport type ResolvedDesignSystemEnvironment = Readonly<{\n theme: ResolvedTheme;\n direction: DesignSystemDirection;\n textScale: DesignSystemTextScale;\n reducedMotion: boolean;\n minimumVisualTarget: boolean;\n density: DesignSystemDensity;\n}>;\n\nexport type ResolveDesignSystemEnvironmentOptions = Readonly<{\n /**\n * The platform's current OS-level scheme, consulted only when `theme`\n * resolves to `\"system\"`. Renderers detect this themselves\n * (`Appearance.getColorScheme()`, `matchMedia('(prefers-color-scheme)')`)\n * — this package never queries the OS.\n */\n systemTheme: ResolvedTheme;\n /** Optional OS/renderer signals used when neither input nor a parent supplies the axis. */\n systemDirection?: DesignSystemDirection;\n systemTextScale?: DesignSystemTextScale;\n systemReducedMotion?: boolean;\n /**\n * Product brand colors layered over the HJM semantic keys. The key set is\n * unchanged, so recipes and contrast rules keep applying. Without this entry\n * point a consumer has to build its own token layer and override the CSS\n * variables, which is a copy of the canonical palette. Only the supplied\n * keys are replaced; the rest keep the HJM defaults.\n */\n brandPalette?: Readonly<Partial<Record<ResolvedTheme, Readonly<Partial<ThemeColors>>>>>;\n /** A nested renderer inherits the already-resolved parent before consulting OS defaults. */\n parent?: ResolvedDesignSystemEnvironment;\n}>;\n\nexport type DesignSystemProviderValue = Readonly<{\n environment: ResolvedDesignSystemEnvironment;\n /** Palette consumed directly by `resolveColorReference`. */\n palette: ColorReferencePalette;\n}>;\n\nconst themeColorKeys = Object.keys(THEMES.light) as readonly (keyof typeof THEMES.light)[];\nconst accentColorKeys = Object.keys(ACCENTS.light) as readonly (keyof typeof ACCENTS.light)[];\nconst sixDigitHexColor = /^#[0-9a-f]{6}$/i;\n\nfunction assertColorRecord(\n value: unknown,\n keys: readonly string[],\n field: string,\n): asserts value is Readonly<Record<string, string>> {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new TypeError(`DesignSystemProviderValue ${field} must be a color record`);\n }\n const record = value as Readonly<Record<string, unknown>>;\n for (const key of keys) {\n const color = record[key];\n if (typeof color !== \"string\" || !sixDigitHexColor.test(color)) {\n throw new TypeError(\n `DesignSystemProviderValue ${field}.${key} must be a six-digit hex color`,\n );\n }\n }\n}\n\n/**\n * Runtime boundary for the resolved palette a renderer receives, including one\n * merged from a partial `brandPalette`: after merging, every semantic role a\n * recipe reads must be present, and alpha composition requires six-digit hex.\n * Brand rules: docs/brand-boundary.md.\n */\nexport function validateDesignSystemProviderValue(\n value: DesignSystemProviderValue,\n): void {\n if (value === null || typeof value !== \"object\") {\n throw new TypeError(\"DesignSystemProviderValue must be an object\");\n }\n if (value.environment === null || typeof value.environment !== \"object\") {\n throw new TypeError(\"DesignSystemProviderValue environment must be an object\");\n }\n validateResolvedDesignSystemEnvironment(value.environment);\n const palette = value.palette;\n if (palette === null || typeof palette !== \"object\") {\n throw new TypeError(\"DesignSystemProviderValue palette must be an object\");\n }\n assertColorRecord(palette.theme, themeColorKeys, \"palette.theme\");\n assertColorRecord(\n palette.statusAccents,\n accentColorKeys,\n \"palette.statusAccents\",\n );\n assertColorRecord(\n palette.statusAccentFills,\n accentColorKeys,\n \"palette.statusAccentFills\",\n );\n}\n\nfunction assertBoolean(value: boolean, field: string): void {\n if (typeof value !== \"boolean\") {\n throw new TypeError(`DesignSystemEnvironment ${field} must be a boolean`);\n }\n}\n\nfunction assertDirection(value: DesignSystemDirection, field: string): void {\n if (value !== \"ltr\" && value !== \"rtl\") {\n throw new TypeError(`Unsupported DesignSystemEnvironment ${field}: ${String(value)}`);\n }\n}\n\nfunction assertTextScale(value: DesignSystemTextScale, field: string): void {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n throw new RangeError(\n `DesignSystemEnvironment ${field} must be a finite number greater than 0`,\n );\n }\n}\n\nfunction assertDensity(value: unknown, field: string): asserts value is DesignSystemDensity {\n if (value !== \"comfortable\" && value !== \"compact\") {\n throw new TypeError(`Unsupported DesignSystemEnvironment ${field}: ${String(value)}`);\n }\n}\n\nexport function validateDesignSystemEnvironmentInput(\n input: DesignSystemEnvironmentInput,\n): void {\n if (input.theme !== undefined && !isThemePreference(input.theme)) {\n throw new TypeError(`Unsupported DesignSystemEnvironment theme: ${String(input.theme)}`);\n }\n if (\n input.direction !== undefined &&\n input.direction !== \"ltr\" &&\n input.direction !== \"rtl\"\n ) {\n throw new TypeError(\n `Unsupported DesignSystemEnvironment direction: ${String(input.direction)}`,\n );\n }\n if (input.textScale !== undefined) {\n assertTextScale(input.textScale, \"textScale\");\n }\n if (input.reducedMotion !== undefined) {\n assertBoolean(input.reducedMotion, \"reducedMotion\");\n }\n if (input.minimumVisualTarget !== undefined) {\n assertBoolean(input.minimumVisualTarget, \"minimumVisualTarget\");\n }\n if (input.density !== undefined) {\n assertDensity(input.density, \"density\");\n }\n}\n\n/**\n * A parent has already crossed the system-preference boundary. Unlike the\n * partial input validator, this rejects `\"system\"`, missing axes, and every\n * malformed resolved value instead of silently resolving them again.\n */\nexport function validateResolvedDesignSystemEnvironment(\n environment: ResolvedDesignSystemEnvironment,\n): void {\n if (environment.theme !== \"light\" && environment.theme !== \"dark\") {\n throw new TypeError(\n `Unsupported ResolvedDesignSystemEnvironment theme: ${String(environment.theme)}`,\n );\n }\n assertDirection(environment.direction, \"parent direction\");\n assertTextScale(environment.textScale, \"parent textScale\");\n assertBoolean(environment.reducedMotion, \"parent reducedMotion\");\n assertBoolean(environment.minimumVisualTarget, \"parent minimumVisualTarget\");\n assertDensity(environment.density, \"parent density\");\n}\n\n/**\n * Merges partial signals with safe defaults and resolves `\"system\"` against\n * the renderer-supplied `systemTheme`. This — not a React/RN context, which\n * this package cannot own — is the entire portable contract behind antd\n * `ConfigProvider`: see docs/design-system-provider.md for what was\n * deliberately left to the renderer.\n */\nexport function resolveDesignSystemEnvironment(\n input: DesignSystemEnvironmentInput,\n options: ResolveDesignSystemEnvironmentOptions,\n): ResolvedDesignSystemEnvironment {\n validateDesignSystemEnvironmentInput(input);\n if (options.systemTheme !== \"light\" && options.systemTheme !== \"dark\") {\n throw new TypeError(`Unsupported DesignSystemEnvironment systemTheme: ${String(options.systemTheme)}`);\n }\n if (options.systemDirection !== undefined) {\n assertDirection(options.systemDirection, \"systemDirection\");\n }\n if (options.systemTextScale !== undefined) {\n assertTextScale(options.systemTextScale, \"systemTextScale\");\n }\n if (options.systemReducedMotion !== undefined) {\n assertBoolean(options.systemReducedMotion, \"systemReducedMotion\");\n }\n if (options.parent !== undefined) {\n validateResolvedDesignSystemEnvironment(options.parent);\n }\n\n const theme =\n input.theme ?? options.parent?.theme ?? designSystemEnvironmentDefaults.theme;\n return {\n theme: theme === \"system\" ? options.systemTheme : theme,\n direction:\n input.direction ??\n options.parent?.direction ??\n options.systemDirection ??\n designSystemEnvironmentDefaults.direction,\n textScale:\n input.textScale ??\n options.parent?.textScale ??\n options.systemTextScale ??\n designSystemEnvironmentDefaults.textScale,\n reducedMotion:\n input.reducedMotion ??\n options.parent?.reducedMotion ??\n options.systemReducedMotion ??\n designSystemEnvironmentDefaults.reducedMotion,\n minimumVisualTarget:\n input.minimumVisualTarget ??\n options.parent?.minimumVisualTarget ??\n designSystemEnvironmentDefaults.minimumVisualTarget,\n density:\n input.density ??\n options.parent?.density ??\n designSystemEnvironmentDefaults.density,\n };\n}\n\n/**\n * Resolves the portable Provider value without owning React/RN Context. A\n * renderer stores this object in its own context and feeds `palette` directly\n * to recipe color resolution.\n */\nexport function resolveDesignSystemProviderValue(\n input: DesignSystemEnvironmentInput,\n options: ResolveDesignSystemEnvironmentOptions,\n): DesignSystemProviderValue {\n const environment = resolveDesignSystemEnvironment(input, options);\n const brandOverride = options.brandPalette?.[environment.theme];\n const value = {\n environment,\n palette: {\n theme: brandOverride === undefined\n ? THEMES[environment.theme]\n : { ...THEMES[environment.theme], ...brandOverride },\n statusAccents: ACCENTS[environment.theme],\n statusAccentFills: accentFill,\n },\n };\n validateDesignSystemProviderValue(value);\n return value;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"design-system-provider.js","sourceRoot":"","sources":["../src/design-system-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HjmDesignProfile } from \"./design-profile.js\";\nimport type { ColorReferencePalette } from \"./color-references.js\";\nimport { control, largeTextThreshold } from \"./foundations.js\";\nimport {\n ACCENTS,\n THEMES,\n accentFill,\n isThemePreference,\n type ResolvedTheme,\n type ThemeColors,\n type ThemePreference,\n} from \"./colors.js\";\n\n/**\n * Canonical logical direction. Existing public component-specific names stay\n * source-compatible as aliases of this type instead of redeclaring the union.\n */\nexport type DesignSystemDirection = \"ltr\" | \"rtl\";\n\n/**\n * A continuous OS/user font-scale multiplier (iOS Dynamic Type, Android font\n * size, browser zoom) — not `ShowcaseTextScale`'s closed `1 | 1.5 | 2`, which\n * only names Showcase's five fixture stories, or `description-list.ts`'s\n * local layout clamp. This is the single upstream signal both now consume.\n */\nexport type DesignSystemTextScale = number;\n\n/**\n * Whether a resolved `textScale` has crossed into large-text layout. A\n * stylesheet cannot compare numbers, so the provider resolves the axis once and\n * publishes the result for surfaces that can only match a flag (#20).\n */\nexport function isLargeTextScale(textScale: DesignSystemTextScale): boolean {\n return Number.isFinite(textScale) && textScale >= largeTextThreshold;\n}\n\n/**\n * Visible height a compact control paints under a product's target-size policy.\n *\n * The compact recipes stay at 36 and reach the 44pt target through hit slop,\n * which satisfies WCAG 2.5.8 but not the stricter iOS/Android guidance some\n * products commit to. `minimumVisualTarget` turns that commitment into one\n * resolved axis, so both renderers compute the same geometry instead of each\n * consumer re-adding `minHeight` in product styles. It lives beside the axis\n * rather than in `foundations` because it is a policy over a token, not a token.\n */\nexport function visibleControlHeight(\n recipeHeight: number,\n minimumVisualTarget: boolean,\n): number {\n return minimumVisualTarget ? Math.max(recipeHeight, control.minTouchTarget) : recipeHeight;\n}\n\n/**\n * 한 화면 안에서 목록·메뉴·표가 각각 다른 밀도로 그려지던 문제를 하나의 축으로 모은다.\n * 지금까지는 `ListRow density`, `Menu density`, DataTable의 행 높이가 서로 모르는 값이라\n * 제품이 세 군데를 따로 맞췄다. 컴포넌트의 명시적 prop이 언제나 이 축을 이긴다 —\n * 전역값은 기본이지 강제가 아니다.\n *\n * OS 신호가 없다. 밀도는 제품의 입장(같은 화면에 얼마나 담을 것인가)이지 사용자 설정이\n * 아니라서 `system*` 짝을 두지 않았다. 반대로 큰 글자 설정은 사용자 설정이므로\n * `textScale`이 큰 상태에서 `compact`를 쓰는 것은 제품이 스스로 막아야 한다.\n */\nexport type DesignSystemDensity = \"comfortable\" | \"compact\";\n\n/**\n * 전역 밀도를 컴포넌트마다 다른 밀도 어휘로 옮긴다. 컴포넌트의 명시적 prop이 언제나\n * 이긴다 — 전역값은 기본이지 강제가 아니다. 어휘를 하나로 통일하지 않은 이유: 목록의\n * `relaxed`와 표의 `regular`는 같은 말이 아니고, 억지로 합치면 둘 중 하나가 거짓말을 한다.\n */\nexport function resolveDensityDefault<Comfortable extends string, Compact extends string>(\n density: DesignSystemDensity,\n vocabulary: Readonly<{ comfortable: Comfortable; compact: Compact }>,\n): Comfortable | Compact {\n return density === \"compact\" ? vocabulary.compact : vocabulary.comfortable;\n}\n\nexport type DesignSystemEnvironmentInput = Readonly<{\n theme?: ThemePreference;\n direction?: DesignSystemDirection;\n textScale?: DesignSystemTextScale;\n reducedMotion?: boolean;\n /**\n * Paint the minimum touch target as visible control geometry instead of\n * reaching it with hit slop. This is a product accessibility stance, not an\n * OS signal, so it has no `system*` counterpart.\n */\n minimumVisualTarget?: boolean;\n /** Default row/menu/table density for everything below this provider. */\n density?: DesignSystemDensity;\n}>;\n\nexport const designSystemEnvironmentDefaults = {\n theme: \"system\",\n direction: \"ltr\",\n textScale: 1,\n reducedMotion: false,\n minimumVisualTarget: false,\n density: \"comfortable\",\n} as const satisfies Readonly<{\n theme: ThemePreference;\n direction: DesignSystemDirection;\n textScale: DesignSystemTextScale;\n reducedMotion: boolean;\n minimumVisualTarget: boolean;\n density: DesignSystemDensity;\n}>;\n\nexport type ResolvedDesignSystemEnvironment = Readonly<{\n theme: ResolvedTheme;\n direction: DesignSystemDirection;\n textScale: DesignSystemTextScale;\n reducedMotion: boolean;\n minimumVisualTarget: boolean;\n density: DesignSystemDensity;\n}>;\n\nexport type ResolveDesignSystemEnvironmentOptions = Readonly<{\n /**\n * The platform's current OS-level scheme, consulted only when `theme`\n * resolves to `\"system\"`. Renderers detect this themselves\n * (`Appearance.getColorScheme()`, `matchMedia('(prefers-color-scheme)')`)\n * — this package never queries the OS.\n */\n systemTheme: ResolvedTheme;\n /** Optional OS/renderer signals used when neither input nor a parent supplies the axis. */\n systemDirection?: DesignSystemDirection;\n systemTextScale?: DesignSystemTextScale;\n systemReducedMotion?: boolean;\n /**\n * Product brand colors layered over the HJM semantic keys. The key set is\n * unchanged, so recipes and contrast rules keep applying. Without this entry\n * point a consumer has to build its own token layer and override the CSS\n * variables, which is a copy of the canonical palette. Only the supplied\n * keys are replaced; the rest keep the HJM defaults.\n */\n brandPalette?: Readonly<Partial<Record<ResolvedTheme, Readonly<Partial<ThemeColors>>>>>;\n /** Use defineHjmDesignProfile once at the product boundary; importing its registry\n * here at runtime would force every granular component to bundle all reference packs. */\n designProfile?: HjmDesignProfile;\n /** A nested renderer inherits the already-resolved parent before consulting OS defaults. */\n parent?: ResolvedDesignSystemEnvironment;\n}>;\n\nexport type DesignSystemProviderValue = Readonly<{\n environment: ResolvedDesignSystemEnvironment;\n /** Palette consumed directly by `resolveColorReference`. */\n palette: ColorReferencePalette;\n /** Optional to preserve existing pre-resolved provider values. */\n designProfile?: HjmDesignProfile;\n}>;\n\nconst themeColorKeys = Object.keys(THEMES.light) as readonly (keyof typeof THEMES.light)[];\nconst accentColorKeys = Object.keys(ACCENTS.light) as readonly (keyof typeof ACCENTS.light)[];\nconst sixDigitHexColor = /^#[0-9a-f]{6}$/i;\n\nfunction assertColorRecord(\n value: unknown,\n keys: readonly string[],\n field: string,\n): asserts value is Readonly<Record<string, string>> {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new TypeError(`DesignSystemProviderValue ${field} must be a color record`);\n }\n const record = value as Readonly<Record<string, unknown>>;\n for (const key of keys) {\n const color = record[key];\n if (typeof color !== \"string\" || !sixDigitHexColor.test(color)) {\n throw new TypeError(\n `DesignSystemProviderValue ${field}.${key} must be a six-digit hex color`,\n );\n }\n }\n}\n\n/**\n * Runtime boundary for the resolved palette a renderer receives, including one\n * merged from a partial `brandPalette`: after merging, every semantic role a\n * recipe reads must be present, and alpha composition requires six-digit hex.\n * Brand rules: docs/brand-boundary.md.\n */\nexport function validateDesignSystemProviderValue(\n value: DesignSystemProviderValue,\n): void {\n if (value === null || typeof value !== \"object\") {\n throw new TypeError(\"DesignSystemProviderValue must be an object\");\n }\n if (value.environment === null || typeof value.environment !== \"object\") {\n throw new TypeError(\"DesignSystemProviderValue environment must be an object\");\n }\n validateResolvedDesignSystemEnvironment(value.environment);\n const palette = value.palette;\n if (palette === null || typeof palette !== \"object\") {\n throw new TypeError(\"DesignSystemProviderValue palette must be an object\");\n }\n assertColorRecord(palette.theme, themeColorKeys, \"palette.theme\");\n assertColorRecord(\n palette.statusAccents,\n accentColorKeys,\n \"palette.statusAccents\",\n );\n assertColorRecord(\n palette.statusAccentFills,\n accentColorKeys,\n \"palette.statusAccentFills\",\n );\n}\n\nfunction assertBoolean(value: boolean, field: string): void {\n if (typeof value !== \"boolean\") {\n throw new TypeError(`DesignSystemEnvironment ${field} must be a boolean`);\n }\n}\n\nfunction assertDirection(value: DesignSystemDirection, field: string): void {\n if (value !== \"ltr\" && value !== \"rtl\") {\n throw new TypeError(`Unsupported DesignSystemEnvironment ${field}: ${String(value)}`);\n }\n}\n\nfunction assertTextScale(value: DesignSystemTextScale, field: string): void {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n throw new RangeError(\n `DesignSystemEnvironment ${field} must be a finite number greater than 0`,\n );\n }\n}\n\nfunction assertDensity(value: unknown, field: string): asserts value is DesignSystemDensity {\n if (value !== \"comfortable\" && value !== \"compact\") {\n throw new TypeError(`Unsupported DesignSystemEnvironment ${field}: ${String(value)}`);\n }\n}\n\nexport function validateDesignSystemEnvironmentInput(\n input: DesignSystemEnvironmentInput,\n): void {\n if (input.theme !== undefined && !isThemePreference(input.theme)) {\n throw new TypeError(`Unsupported DesignSystemEnvironment theme: ${String(input.theme)}`);\n }\n if (\n input.direction !== undefined &&\n input.direction !== \"ltr\" &&\n input.direction !== \"rtl\"\n ) {\n throw new TypeError(\n `Unsupported DesignSystemEnvironment direction: ${String(input.direction)}`,\n );\n }\n if (input.textScale !== undefined) {\n assertTextScale(input.textScale, \"textScale\");\n }\n if (input.reducedMotion !== undefined) {\n assertBoolean(input.reducedMotion, \"reducedMotion\");\n }\n if (input.minimumVisualTarget !== undefined) {\n assertBoolean(input.minimumVisualTarget, \"minimumVisualTarget\");\n }\n if (input.density !== undefined) {\n assertDensity(input.density, \"density\");\n }\n}\n\n/**\n * A parent has already crossed the system-preference boundary. Unlike the\n * partial input validator, this rejects `\"system\"`, missing axes, and every\n * malformed resolved value instead of silently resolving them again.\n */\nexport function validateResolvedDesignSystemEnvironment(\n environment: ResolvedDesignSystemEnvironment,\n): void {\n if (environment.theme !== \"light\" && environment.theme !== \"dark\") {\n throw new TypeError(\n `Unsupported ResolvedDesignSystemEnvironment theme: ${String(environment.theme)}`,\n );\n }\n assertDirection(environment.direction, \"parent direction\");\n assertTextScale(environment.textScale, \"parent textScale\");\n assertBoolean(environment.reducedMotion, \"parent reducedMotion\");\n assertBoolean(environment.minimumVisualTarget, \"parent minimumVisualTarget\");\n assertDensity(environment.density, \"parent density\");\n}\n\n/**\n * Merges partial signals with safe defaults and resolves `\"system\"` against\n * the renderer-supplied `systemTheme`. This — not a React/RN context, which\n * this package cannot own — is the entire portable contract behind antd\n * `ConfigProvider`: see docs/design-system-provider.md for what was\n * deliberately left to the renderer.\n */\nexport function resolveDesignSystemEnvironment(\n input: DesignSystemEnvironmentInput,\n options: ResolveDesignSystemEnvironmentOptions,\n): ResolvedDesignSystemEnvironment {\n validateDesignSystemEnvironmentInput(input);\n if (options.systemTheme !== \"light\" && options.systemTheme !== \"dark\") {\n throw new TypeError(`Unsupported DesignSystemEnvironment systemTheme: ${String(options.systemTheme)}`);\n }\n if (options.systemDirection !== undefined) {\n assertDirection(options.systemDirection, \"systemDirection\");\n }\n if (options.systemTextScale !== undefined) {\n assertTextScale(options.systemTextScale, \"systemTextScale\");\n }\n if (options.systemReducedMotion !== undefined) {\n assertBoolean(options.systemReducedMotion, \"systemReducedMotion\");\n }\n if (options.parent !== undefined) {\n validateResolvedDesignSystemEnvironment(options.parent);\n }\n\n const theme =\n input.theme ?? options.parent?.theme ?? designSystemEnvironmentDefaults.theme;\n return {\n theme: theme === \"system\" ? options.systemTheme : theme,\n direction:\n input.direction ??\n options.parent?.direction ??\n options.systemDirection ??\n designSystemEnvironmentDefaults.direction,\n textScale:\n input.textScale ??\n options.parent?.textScale ??\n options.systemTextScale ??\n designSystemEnvironmentDefaults.textScale,\n reducedMotion:\n input.reducedMotion ??\n options.parent?.reducedMotion ??\n options.systemReducedMotion ??\n designSystemEnvironmentDefaults.reducedMotion,\n minimumVisualTarget:\n input.minimumVisualTarget ??\n options.parent?.minimumVisualTarget ??\n designSystemEnvironmentDefaults.minimumVisualTarget,\n density:\n input.density ??\n options.parent?.density ??\n designSystemEnvironmentDefaults.density,\n };\n}\n\n/**\n * Resolves the portable Provider value without owning React/RN Context. A\n * renderer stores this object in its own context and feeds `palette` directly\n * to recipe color resolution.\n */\nexport function resolveDesignSystemProviderValue(\n input: DesignSystemEnvironmentInput,\n options: ResolveDesignSystemEnvironmentOptions,\n): DesignSystemProviderValue {\n const environment = resolveDesignSystemEnvironment(input, options);\n const brandOverride = options.brandPalette?.[environment.theme];\n const basePalette = options.designProfile?.palette[environment.theme] ?? THEMES[environment.theme];\n const value = {\n environment,\n ...(options.designProfile === undefined ? {} : { designProfile: options.designProfile }),\n palette: {\n theme: brandOverride === undefined\n ? basePalette\n : { ...basePalette, ...brandOverride },\n statusAccents: ACCENTS[environment.theme],\n statusAccentFills: accentFill,\n },\n };\n validateDesignSystemProviderValue(value);\n return value;\n}\n"]}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Candidate composition contract; file access, transfer and receipt verification stay with the host. */
|
|
2
|
+
export type DocumentPreviewState = Readonly<{
|
|
3
|
+
status: "none" | "loading" | "ready";
|
|
4
|
+
}> | Readonly<{
|
|
5
|
+
status: "error";
|
|
6
|
+
message: string;
|
|
7
|
+
retryable: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
export type DocumentSaveState = Readonly<{
|
|
10
|
+
status: "idle" | "pending" | "started" | "saved" | "cancelled";
|
|
11
|
+
}> | Readonly<{
|
|
12
|
+
status: "error";
|
|
13
|
+
message: string;
|
|
14
|
+
retryable: boolean;
|
|
15
|
+
}>;
|
|
16
|
+
export type DocumentResourceDescriptor = Readonly<{
|
|
17
|
+
/** Include a revision when reusing a resource id for different file contents. */
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
formatLabel?: string;
|
|
21
|
+
sizeLabel?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/** Product review/permission gates may block export while keeping preview accessible. */
|
|
25
|
+
saveDisabled?: boolean;
|
|
26
|
+
preview: DocumentPreviewState;
|
|
27
|
+
save: DocumentSaveState;
|
|
28
|
+
}>;
|
|
29
|
+
export type DocumentResourceLabels = Readonly<{
|
|
30
|
+
preview: string;
|
|
31
|
+
previewLoading: string;
|
|
32
|
+
previewUnavailable: string;
|
|
33
|
+
retryPreview: string;
|
|
34
|
+
save: string;
|
|
35
|
+
saving: string;
|
|
36
|
+
started: string;
|
|
37
|
+
saved: string;
|
|
38
|
+
cancelled: string;
|
|
39
|
+
retrySave: string;
|
|
40
|
+
}>;
|
|
41
|
+
export type DocumentResourceControls = Readonly<{
|
|
42
|
+
descriptor: DocumentResourceDescriptor;
|
|
43
|
+
labels: DocumentResourceLabels;
|
|
44
|
+
onPreview?: () => void;
|
|
45
|
+
onRetryPreview?: () => void;
|
|
46
|
+
onSave: () => void;
|
|
47
|
+
onRetrySave?: () => void;
|
|
48
|
+
}>;
|
|
49
|
+
/** Controlled UI only: hosts connect the existing action session to their verified results. */
|
|
50
|
+
export declare function resolveDocumentResourceControls(props: DocumentResourceControls): Readonly<{
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
metadata: readonly string[];
|
|
54
|
+
description: string | undefined;
|
|
55
|
+
disabled: boolean;
|
|
56
|
+
saveDisabled: boolean;
|
|
57
|
+
preview: Readonly<{
|
|
58
|
+
status: "none" | "loading" | "ready";
|
|
59
|
+
} | {
|
|
60
|
+
status: "error";
|
|
61
|
+
message: string;
|
|
62
|
+
retryable: boolean;
|
|
63
|
+
}>;
|
|
64
|
+
save: Readonly<{
|
|
65
|
+
status: "idle" | "pending" | "started" | "saved" | "cancelled";
|
|
66
|
+
} | {
|
|
67
|
+
status: "error";
|
|
68
|
+
message: string;
|
|
69
|
+
retryable: boolean;
|
|
70
|
+
}>;
|
|
71
|
+
canPreview: boolean;
|
|
72
|
+
canRetryPreview: boolean;
|
|
73
|
+
canSave: boolean;
|
|
74
|
+
canRetrySave: boolean;
|
|
75
|
+
saved: boolean;
|
|
76
|
+
}>;
|
|
77
|
+
export declare function resolveDocumentResource(descriptor: DocumentResourceDescriptor): Readonly<{
|
|
78
|
+
id: string;
|
|
79
|
+
name: string;
|
|
80
|
+
metadata: readonly string[];
|
|
81
|
+
description: string | undefined;
|
|
82
|
+
disabled: boolean;
|
|
83
|
+
saveDisabled: boolean;
|
|
84
|
+
preview: Readonly<{
|
|
85
|
+
status: "none" | "loading" | "ready";
|
|
86
|
+
} | {
|
|
87
|
+
status: "error";
|
|
88
|
+
message: string;
|
|
89
|
+
retryable: boolean;
|
|
90
|
+
}>;
|
|
91
|
+
save: Readonly<{
|
|
92
|
+
status: "idle" | "pending" | "started" | "saved" | "cancelled";
|
|
93
|
+
} | {
|
|
94
|
+
status: "error";
|
|
95
|
+
message: string;
|
|
96
|
+
retryable: boolean;
|
|
97
|
+
}>;
|
|
98
|
+
canPreview: boolean;
|
|
99
|
+
canRetryPreview: boolean;
|
|
100
|
+
canSave: boolean;
|
|
101
|
+
canRetrySave: boolean;
|
|
102
|
+
saved: boolean;
|
|
103
|
+
}>;
|
|
104
|
+
//# sourceMappingURL=document-resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-resource.d.ts","sourceRoot":"","sources":["../src/document-resource.ts"],"names":[],"mappings":"AAAA,yGAAyG;AACzG,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;CAAE,CAAC,GAClD,QAAQ,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,iBAAiB,GACzB,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAA;CAAE,CAAC,GAC5E,QAAQ,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yFAAyF;IACzF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,UAAU,EAAE,0BAA0B,CAAC;IACvC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC,CAAC;AAEH,+FAA+F;AAC/F,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,wBAAwB;;;;;;;;gBA5CxD,MAAM,GAAG,SAAS,GAAG,OAAO;;gBAC5B,OAAO;iBAAW,MAAM;mBAAa,OAAO;;;gBAG5C,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW;;gBACtD,OAAO;iBAAW,MAAM;mBAAa,OAAO;;;;;;;GAmDlE;AAmBD,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,0BAA0B;;;;;;;;gBA3EvD,MAAM,GAAG,SAAS,GAAG,OAAO;;gBAC5B,OAAO;iBAAW,MAAM;mBAAa,OAAO;;;gBAG5C,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW;;gBACtD,OAAO;iBAAW,MAAM;mBAAa,OAAO;;;;;;;GA6GlE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** Controlled UI only: hosts connect the existing action session to their verified results. */
|
|
2
|
+
export function resolveDocumentResourceControls(props) {
|
|
3
|
+
const resource = resolveDocumentResource(props.descriptor);
|
|
4
|
+
for (const key of ["preview", "previewLoading", "previewUnavailable", "retryPreview", "save", "saving", "started", "saved", "cancelled", "retrySave"]) {
|
|
5
|
+
text(props.labels[key], `labels.${key}`);
|
|
6
|
+
}
|
|
7
|
+
if (typeof props.onSave !== "function")
|
|
8
|
+
throw new TypeError("Document resource requires onSave");
|
|
9
|
+
for (const key of ["onPreview", "onRetryPreview", "onRetrySave"]) {
|
|
10
|
+
if (props[key] !== undefined && typeof props[key] !== "function")
|
|
11
|
+
throw new TypeError(`Document resource ${key} must be a function`);
|
|
12
|
+
}
|
|
13
|
+
if (resource.preview.status === "error" && resource.preview.retryable && !props.onRetryPreview)
|
|
14
|
+
throw new TypeError("Retryable preview requires onRetryPreview");
|
|
15
|
+
if (resource.save.status === "error" && resource.save.retryable && !props.onRetrySave)
|
|
16
|
+
throw new TypeError("Retryable save requires onRetrySave");
|
|
17
|
+
return resource;
|
|
18
|
+
}
|
|
19
|
+
function text(value, field) {
|
|
20
|
+
if (typeof value !== "string" || !value.trim())
|
|
21
|
+
throw new TypeError(`Document resource ${field} must be nonempty text`);
|
|
22
|
+
}
|
|
23
|
+
function state(value, states, field) {
|
|
24
|
+
if (!value || typeof value !== "object" || !("status" in value) || !states.includes(value.status)) {
|
|
25
|
+
throw new TypeError(`Document resource ${field} has an unsupported status`);
|
|
26
|
+
}
|
|
27
|
+
if (value.status === "error") {
|
|
28
|
+
const error = value;
|
|
29
|
+
text(error.message, `${field} error`);
|
|
30
|
+
// An uncertain native save can have committed. Retry permission is explicit,
|
|
31
|
+
// just like action-session; an error alone never authorizes another write.
|
|
32
|
+
if (typeof error.retryable !== "boolean")
|
|
33
|
+
throw new TypeError(`Document resource ${field} retryable must be boolean`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function resolveDocumentResource(descriptor) {
|
|
37
|
+
text(descriptor.id, "id");
|
|
38
|
+
text(descriptor.name, "name");
|
|
39
|
+
for (const key of ["formatLabel", "sizeLabel", "description"]) {
|
|
40
|
+
if (descriptor[key] !== undefined)
|
|
41
|
+
text(descriptor[key], key);
|
|
42
|
+
}
|
|
43
|
+
for (const key of ["disabled", "saveDisabled"]) {
|
|
44
|
+
if (descriptor[key] !== undefined && typeof descriptor[key] !== "boolean") {
|
|
45
|
+
throw new TypeError(`Document resource ${key} must be boolean`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
state(descriptor.preview, ["none", "loading", "ready", "error"], "preview");
|
|
49
|
+
state(descriptor.save, ["idle", "pending", "started", "saved", "cancelled", "error"], "save");
|
|
50
|
+
const disabled = descriptor.disabled ?? false;
|
|
51
|
+
// Utilverse requires viewing the output before accepting export; whole-card disabling
|
|
52
|
+
// would prevent that review. The host owns the requirement, not a fake pending state.
|
|
53
|
+
const saveDisabled = disabled || descriptor.saveDisabled === true;
|
|
54
|
+
const preview = Object.freeze({ ...descriptor.preview });
|
|
55
|
+
const save = Object.freeze({ ...descriptor.save });
|
|
56
|
+
return Object.freeze({
|
|
57
|
+
id: descriptor.id,
|
|
58
|
+
name: descriptor.name,
|
|
59
|
+
// Preserve product formatting and order; neither URL extensions nor inferred
|
|
60
|
+
// byte counts are reliable metadata for remote/signed/local resources.
|
|
61
|
+
metadata: Object.freeze([descriptor.formatLabel, descriptor.sizeLabel].filter((value) => value !== undefined)),
|
|
62
|
+
description: descriptor.description,
|
|
63
|
+
disabled,
|
|
64
|
+
saveDisabled,
|
|
65
|
+
preview,
|
|
66
|
+
save,
|
|
67
|
+
canPreview: !disabled && preview.status === "ready",
|
|
68
|
+
canRetryPreview: !disabled && preview.status === "error" && preview.retryable,
|
|
69
|
+
// Keep failures on the explicit retry path. A second ordinary save must not
|
|
70
|
+
// bypass a host's retryable=false policy after an ambiguous OS response.
|
|
71
|
+
canSave: !saveDisabled && save.status !== "pending" && save.status !== "error",
|
|
72
|
+
canRetrySave: !saveDisabled && save.status === "error" && save.retryable,
|
|
73
|
+
// Browser anchor activation proves initiation, not file-system completion.
|
|
74
|
+
saved: save.status === "saved",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=document-resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-resource.js","sourceRoot":"","sources":["../src/document-resource.ts"],"names":[],"mappings":"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","sourcesContent":["/** Candidate composition contract; file access, transfer and receipt verification stay with the host. */\nexport type DocumentPreviewState =\n | Readonly<{ status: \"none\" | \"loading\" | \"ready\" }>\n | Readonly<{ status: \"error\"; message: string; retryable: boolean }>;\n\nexport type DocumentSaveState =\n | Readonly<{ status: \"idle\" | \"pending\" | \"started\" | \"saved\" | \"cancelled\" }>\n | Readonly<{ status: \"error\"; message: string; retryable: boolean }>;\n\nexport type DocumentResourceDescriptor = Readonly<{\n /** Include a revision when reusing a resource id for different file contents. */\n id: string;\n name: string;\n formatLabel?: string;\n sizeLabel?: string;\n description?: string;\n disabled?: boolean;\n /** Product review/permission gates may block export while keeping preview accessible. */\n saveDisabled?: boolean;\n preview: DocumentPreviewState;\n save: DocumentSaveState;\n}>;\n\nexport type DocumentResourceLabels = Readonly<{\n preview: string;\n previewLoading: string;\n previewUnavailable: string;\n retryPreview: string;\n save: string;\n saving: string;\n started: string;\n saved: string;\n cancelled: string;\n retrySave: string;\n}>;\n\nexport type DocumentResourceControls = Readonly<{\n descriptor: DocumentResourceDescriptor;\n labels: DocumentResourceLabels;\n onPreview?: () => void;\n onRetryPreview?: () => void;\n onSave: () => void;\n onRetrySave?: () => void;\n}>;\n\n/** Controlled UI only: hosts connect the existing action session to their verified results. */\nexport function resolveDocumentResourceControls(props: DocumentResourceControls) {\n const resource = resolveDocumentResource(props.descriptor);\n for (const key of [\"preview\", \"previewLoading\", \"previewUnavailable\", \"retryPreview\", \"save\", \"saving\", \"started\", \"saved\", \"cancelled\", \"retrySave\"] as const) {\n text(props.labels[key], `labels.${key}`);\n }\n if (typeof props.onSave !== \"function\") throw new TypeError(\"Document resource requires onSave\");\n for (const key of [\"onPreview\", \"onRetryPreview\", \"onRetrySave\"] as const) {\n if (props[key] !== undefined && typeof props[key] !== \"function\") throw new TypeError(`Document resource ${key} must be a function`);\n }\n if (resource.preview.status === \"error\" && resource.preview.retryable && !props.onRetryPreview) throw new TypeError(\"Retryable preview requires onRetryPreview\");\n if (resource.save.status === \"error\" && resource.save.retryable && !props.onRetrySave) throw new TypeError(\"Retryable save requires onRetrySave\");\n return resource;\n}\n\nfunction text(value: unknown, field: string): asserts value is string {\n if (typeof value !== \"string\" || !value.trim()) throw new TypeError(`Document resource ${field} must be nonempty text`);\n}\n\nfunction state(value: unknown, states: readonly string[], field: string): void {\n if (!value || typeof value !== \"object\" || !(\"status\" in value) || !states.includes(value.status as string)) {\n throw new TypeError(`Document resource ${field} has an unsupported status`);\n }\n if (value.status === \"error\") {\n const error = value as { message?: unknown; retryable?: unknown };\n text(error.message, `${field} error`);\n // An uncertain native save can have committed. Retry permission is explicit,\n // just like action-session; an error alone never authorizes another write.\n if (typeof error.retryable !== \"boolean\") throw new TypeError(`Document resource ${field} retryable must be boolean`);\n }\n}\n\nexport function resolveDocumentResource(descriptor: DocumentResourceDescriptor) {\n text(descriptor.id, \"id\");\n text(descriptor.name, \"name\");\n for (const key of [\"formatLabel\", \"sizeLabel\", \"description\"] as const) {\n if (descriptor[key] !== undefined) text(descriptor[key], key);\n }\n for (const key of [\"disabled\", \"saveDisabled\"] as const) {\n if (descriptor[key] !== undefined && typeof descriptor[key] !== \"boolean\") {\n throw new TypeError(`Document resource ${key} must be boolean`);\n }\n }\n state(descriptor.preview, [\"none\", \"loading\", \"ready\", \"error\"], \"preview\");\n state(descriptor.save, [\"idle\", \"pending\", \"started\", \"saved\", \"cancelled\", \"error\"], \"save\");\n const disabled = descriptor.disabled ?? false;\n // Utilverse requires viewing the output before accepting export; whole-card disabling\n // would prevent that review. The host owns the requirement, not a fake pending state.\n const saveDisabled = disabled || descriptor.saveDisabled === true;\n const preview = Object.freeze({ ...descriptor.preview });\n const save = Object.freeze({ ...descriptor.save });\n return Object.freeze({\n id: descriptor.id,\n name: descriptor.name,\n // Preserve product formatting and order; neither URL extensions nor inferred\n // byte counts are reliable metadata for remote/signed/local resources.\n metadata: Object.freeze([descriptor.formatLabel, descriptor.sizeLabel].filter((value): value is string => value !== undefined)),\n description: descriptor.description,\n disabled,\n saveDisabled,\n preview,\n save,\n canPreview: !disabled && preview.status === \"ready\",\n canRetryPreview: !disabled && preview.status === \"error\" && preview.retryable,\n // Keep failures on the explicit retry path. A second ordinary save must not\n // bypass a host's retryable=false policy after an ambiguous OS response.\n canSave: !saveDisabled && save.status !== \"pending\" && save.status !== \"error\",\n canRetrySave: !saveDisabled && save.status === \"error\" && save.retryable,\n // Browser anchor activation proves initiation, not file-system completion.\n saved: save.status === \"saved\",\n });\n}\n"]}
|
package/dist/effect-surface.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ColorReference } from "./color-references.js";
|
|
2
|
-
export type EffectLayer = "mesh" | "glow" | "grain";
|
|
2
|
+
export type EffectLayer = "mesh" | "glow" | "grain" | "noise";
|
|
3
3
|
export type EffectSurfaceDescriptor = Readonly<{
|
|
4
4
|
layers?: readonly EffectLayer[];
|
|
5
5
|
seed?: string;
|
|
@@ -15,6 +15,11 @@ export declare function resolveEffectSurface(descriptor?: EffectSurfaceDescripto
|
|
|
15
15
|
period: number;
|
|
16
16
|
active: boolean;
|
|
17
17
|
colors: readonly [ColorReference, ColorReference, ColorReference];
|
|
18
|
+
noise: {
|
|
19
|
+
uri: string;
|
|
20
|
+
size: number;
|
|
21
|
+
offset: number;
|
|
22
|
+
} | undefined;
|
|
18
23
|
points: {
|
|
19
24
|
x: number;
|
|
20
25
|
y: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effect-surface.d.ts","sourceRoot":"","sources":["../src/effect-surface.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"effect-surface.d.ts","sourceRoot":"","sources":["../src/effect-surface.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACxE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAC9D,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC,cAAc,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;CACpE,CAAC,CAAC;AACH,wBAAgB,oBAAoB,CAAC,UAAU,GAAE,uBAA4B;;;;;;;;;;;;;;;;;;;;;EAoB5E"}
|
package/dist/effect-surface.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { effectNoiseTile } from "./internal/effect-noise.js";
|
|
1
2
|
import { themeColor } from "./color-references.js";
|
|
2
3
|
export function resolveEffectSurface(descriptor = {}) {
|
|
3
4
|
const layers = descriptor.layers ?? ["mesh"];
|
|
4
|
-
if (!layers.length || layers.length >
|
|
5
|
-
throw new TypeError("Choose one to
|
|
5
|
+
if (!layers.length || layers.length > 4 || new Set(layers).size !== layers.length || layers.some(layer => !["mesh", "glow", "grain", "noise"].includes(layer)))
|
|
6
|
+
throw new TypeError("Choose one to four unique effect layers");
|
|
6
7
|
const intensity = descriptor.intensity ?? 0.22;
|
|
7
8
|
if (!Number.isFinite(intensity) || intensity < 0 || intensity > 1)
|
|
8
9
|
throw new RangeError("Effect intensity must be between 0 and 1");
|
|
@@ -21,6 +22,8 @@ export function resolveEffectSurface(descriptor = {}) {
|
|
|
21
22
|
const points = Array.from({ length: 32 }, () => ({ x: Math.round(random() * 100), y: Math.round(random() * 100), radius: 0.2 + random() * 0.5 }));
|
|
22
23
|
return { layers, intensity, period, active: descriptor.active ?? false,
|
|
23
24
|
colors: descriptor.colors ?? [themeColor("primary"), themeColor("contentBrand"), themeColor("surfaceAccent")],
|
|
25
|
+
// Fixed periodic raster is shared across hosts; seed shifts its phase, not its pixels.
|
|
26
|
+
noise: layers.includes("noise") ? { uri: effectNoiseTile, size: 64, offset: points[0].x / 4 } : undefined,
|
|
24
27
|
points, anchors: points.slice(0, 3) };
|
|
25
28
|
}
|
|
26
29
|
//# sourceMappingURL=effect-surface.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effect-surface.js","sourceRoot":"","sources":["../src/effect-surface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,uBAAuB,CAAC;AAWxE,MAAM,UAAU,oBAAoB,CAAC,aAAsC,EAAE;IAC3E,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"effect-surface.js","sourceRoot":"","sources":["../src/effect-surface.ts"],"names":[],"mappings":"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","sourcesContent":["import { effectNoiseTile } from \"./internal/effect-noise.js\";\nimport { themeColor, type ColorReference } from \"./color-references.js\";\nexport type EffectLayer = \"mesh\" | \"glow\" | \"grain\" | \"noise\";\nexport type EffectSurfaceDescriptor = Readonly<{\n layers?: readonly EffectLayer[];\n seed?: string;\n intensity?: number;\n /** One slow cycle in seconds; decorative motion is off unless explicitly active. */\n period?: number;\n active?: boolean;\n colors?: readonly [ColorReference, ColorReference, ColorReference];\n}>;\nexport function resolveEffectSurface(descriptor: EffectSurfaceDescriptor = {}) {\n const layers = descriptor.layers ?? [\"mesh\"];\n if (!layers.length || layers.length > 4 || new Set(layers).size !== layers.length || layers.some(layer => ![\"mesh\", \"glow\", \"grain\", \"noise\"].includes(layer))) throw new TypeError(\"Choose one to four unique effect layers\");\n const intensity = descriptor.intensity ?? 0.22;\n if (!Number.isFinite(intensity) || intensity < 0 || intensity > 1) throw new RangeError(\"Effect intensity must be between 0 and 1\");\n const period = descriptor.period ?? 12;\n if (!Number.isFinite(period) || period < 2 || period > 120) throw new RangeError(\"Effect period must be between 2 and 120 seconds\");\n const seed = descriptor.seed ?? \"hjm\";\n if (typeof seed !== \"string\" || seed.length === 0) throw new TypeError(\"Effect seed must not be empty\");\n // Small deterministic spatial sampling keeps SSR/native geometry consistent;\n // it is decorative randomness, not a security or account identifier hash.\n let state = 2166136261;\n for (const character of seed) state = Math.imul(state ^ character.codePointAt(0)!, 16777619) >>> 0;\n const random = () => { state = (Math.imul(state, 1664525) + 1013904223) >>> 0; return state / 4294967296; };\n const points = Array.from({ length: 32 }, () => ({ x: Math.round(random() * 100), y: Math.round(random() * 100), radius: 0.2 + random() * 0.5 }));\n return { layers, intensity, period, active: descriptor.active ?? false,\n colors: descriptor.colors ?? [themeColor(\"primary\"), themeColor(\"contentBrand\"), themeColor(\"surfaceAccent\")] as const,\n // Fixed periodic raster is shared across hosts; seed shifts its phase, not its pixels.\n noise: layers.includes(\"noise\") ? { uri: effectNoiseTile, size: 64, offset: points[0]!.x / 4 } : undefined,\n points, anchors: points.slice(0, 3) };\n}\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Related-input grouping contract. Values and submit/validation timing remain product-owned. */
|
|
2
|
+
export type FieldGroupMember = Readonly<{
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
export type FieldGroupDescriptor = Readonly<{
|
|
10
|
+
label: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** An empty fieldIds list is a group-only error, not a reason to mark every field invalid. */
|
|
14
|
+
error?: Readonly<{
|
|
15
|
+
message: string;
|
|
16
|
+
fieldIds: readonly string[];
|
|
17
|
+
}>;
|
|
18
|
+
fields: readonly FieldGroupMember[];
|
|
19
|
+
}>;
|
|
20
|
+
export type ResolvedFieldGroupMember = Readonly<{
|
|
21
|
+
id: string;
|
|
22
|
+
label: string;
|
|
23
|
+
groupLabel: string;
|
|
24
|
+
disabled: boolean;
|
|
25
|
+
invalid: boolean;
|
|
26
|
+
/** Renderers associate these messages without replacing a field's own help or error. */
|
|
27
|
+
support: readonly Readonly<{
|
|
28
|
+
scope: "group" | "field";
|
|
29
|
+
kind: "description" | "error";
|
|
30
|
+
text: string;
|
|
31
|
+
}>[];
|
|
32
|
+
}>;
|
|
33
|
+
/** Late native events and retained callbacks must use the current committed group policy. */
|
|
34
|
+
export declare function createFieldGroupEditSession(fields: readonly ResolvedFieldGroupMember[]): {
|
|
35
|
+
update(next: readonly ResolvedFieldGroupMember[]): void;
|
|
36
|
+
/** Effect cleanup blocks events without treating Strict Mode replay as field removal. */
|
|
37
|
+
suspend(): void;
|
|
38
|
+
guard<Args extends unknown[]>(id: string, callback: (...args: Args) => void): (...args: Args) => void;
|
|
39
|
+
};
|
|
40
|
+
export declare function resolveFieldGroup(descriptor: FieldGroupDescriptor): Readonly<{
|
|
41
|
+
label: string;
|
|
42
|
+
description: string | undefined;
|
|
43
|
+
error: string | undefined;
|
|
44
|
+
disabled: boolean;
|
|
45
|
+
fields: readonly ResolvedFieldGroupMember[];
|
|
46
|
+
}>;
|
|
47
|
+
//# sourceMappingURL=field-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-group.d.ts","sourceRoot":"","sources":["../src/field-group.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8FAA8F;IAC9F,KAAK,CAAC,EAAE,QAAQ,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACnE,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,wFAAwF;IACxF,OAAO,EAAE,SAAS,QAAQ,CAAC;QAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;QAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;CACzG,CAAC,CAAC;AAMH,6FAA6F;AAC7F,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE;iBAItE,SAAS,wBAAwB,EAAE;IAQhD,yFAAyF;;UAEnF,IAAI,SAAS,OAAO,EAAE,MAAM,MAAM,YAAY,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,IAAI;EAOxG;AAUD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,oBAAoB,GAAG,QAAQ,CAAC;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAC;CAC7C,CAAC,CA2CD"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
function requireText(value, name) {
|
|
2
|
+
if (typeof value !== "string" || !value.trim())
|
|
3
|
+
throw new TypeError(`Field group ${name} must be nonempty text`);
|
|
4
|
+
}
|
|
5
|
+
/** Late native events and retained callbacks must use the current committed group policy. */
|
|
6
|
+
export function createFieldGroupEditSession(fields) {
|
|
7
|
+
let enabled = new Set(fields.filter(field => !field.disabled).map(field => field.id));
|
|
8
|
+
const members = new Map(fields.map(field => [field.id, {}]));
|
|
9
|
+
return {
|
|
10
|
+
update(next) {
|
|
11
|
+
const current = new Set(next.map(field => field.id));
|
|
12
|
+
// A reused id is a new mounted field after removal. Checking only enabled ids
|
|
13
|
+
// would revive queued events from the old field and overwrite the new draft.
|
|
14
|
+
for (const id of members.keys())
|
|
15
|
+
if (!current.has(id))
|
|
16
|
+
members.delete(id);
|
|
17
|
+
for (const id of current)
|
|
18
|
+
if (!members.has(id))
|
|
19
|
+
members.set(id, {});
|
|
20
|
+
enabled = new Set(next.filter(field => !field.disabled).map(field => field.id));
|
|
21
|
+
},
|
|
22
|
+
/** Effect cleanup blocks events without treating Strict Mode replay as field removal. */
|
|
23
|
+
suspend() { enabled.clear(); },
|
|
24
|
+
guard(id, callback) {
|
|
25
|
+
// A new host binds during render, before its committed policy enables it.
|
|
26
|
+
if (!members.has(id))
|
|
27
|
+
members.set(id, {});
|
|
28
|
+
const member = members.get(id);
|
|
29
|
+
return (...args) => { if (members.get(id) === member && enabled.has(id))
|
|
30
|
+
callback(...args); };
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function optionalText(value, name) {
|
|
35
|
+
if (value !== undefined)
|
|
36
|
+
requireText(value, name);
|
|
37
|
+
}
|
|
38
|
+
function optionalBoolean(value) {
|
|
39
|
+
if (value !== undefined && typeof value !== "boolean")
|
|
40
|
+
throw new TypeError("Field group disabled must be boolean");
|
|
41
|
+
}
|
|
42
|
+
export function resolveFieldGroup(descriptor) {
|
|
43
|
+
requireText(descriptor.label, "label");
|
|
44
|
+
optionalText(descriptor.description, "description");
|
|
45
|
+
optionalBoolean(descriptor.disabled);
|
|
46
|
+
if (!Array.isArray(descriptor.fields))
|
|
47
|
+
throw new TypeError("Field group fields must be an array");
|
|
48
|
+
const ids = new Set();
|
|
49
|
+
for (const field of descriptor.fields) {
|
|
50
|
+
requireText(field.id, "field id");
|
|
51
|
+
requireText(field.label, "field label");
|
|
52
|
+
optionalText(field.description, "field description");
|
|
53
|
+
optionalText(field.error, "field error");
|
|
54
|
+
optionalBoolean(field.disabled);
|
|
55
|
+
if (ids.has(field.id))
|
|
56
|
+
throw new TypeError("Field group field ids must be unique");
|
|
57
|
+
ids.add(field.id);
|
|
58
|
+
}
|
|
59
|
+
if (descriptor.error !== undefined) {
|
|
60
|
+
requireText(descriptor.error.message, "error");
|
|
61
|
+
const affected = descriptor.error.fieldIds;
|
|
62
|
+
// A typo or removed field must not silently lose its validation feedback.
|
|
63
|
+
// Products update the visible error with their dynamic field list atomically.
|
|
64
|
+
if (!Array.isArray(affected) || new Set(affected).size !== affected.length || affected.some(id => !ids.has(id))) {
|
|
65
|
+
throw new TypeError("Field group error must reference distinct current field ids");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const disabled = descriptor.disabled ?? false;
|
|
69
|
+
return Object.freeze({
|
|
70
|
+
label: descriptor.label,
|
|
71
|
+
description: descriptor.description,
|
|
72
|
+
error: descriptor.error?.message,
|
|
73
|
+
disabled,
|
|
74
|
+
fields: Object.freeze(descriptor.fields.map(field => {
|
|
75
|
+
const groupError = descriptor.error?.fieldIds.includes(field.id) ? descriptor.error.message : undefined;
|
|
76
|
+
const support = [];
|
|
77
|
+
if (descriptor.description !== undefined)
|
|
78
|
+
support.push({ scope: "group", kind: "description", text: descriptor.description });
|
|
79
|
+
if (field.description !== undefined)
|
|
80
|
+
support.push({ scope: "field", kind: "description", text: field.description });
|
|
81
|
+
if (field.error !== undefined)
|
|
82
|
+
support.push({ scope: "field", kind: "error", text: field.error });
|
|
83
|
+
if (groupError !== undefined)
|
|
84
|
+
support.push({ scope: "group", kind: "error", text: groupError });
|
|
85
|
+
return Object.freeze({ id: field.id, label: field.label, groupLabel: descriptor.label,
|
|
86
|
+
// Group unlock restores independently disabled members; it never enables them.
|
|
87
|
+
disabled: disabled || (field.disabled ?? false), invalid: field.error !== undefined || groupError !== undefined,
|
|
88
|
+
support: Object.freeze(support.map(message => Object.freeze(message))) });
|
|
89
|
+
})),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=field-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-group.js","sourceRoot":"","sources":["../src/field-group.ts"],"names":[],"mappings":"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","sourcesContent":["/** Related-input grouping contract. Values and submit/validation timing remain product-owned. */\nexport type FieldGroupMember = Readonly<{\n id: string;\n label: string;\n description?: string;\n error?: string;\n disabled?: boolean;\n}>;\n\nexport type FieldGroupDescriptor = Readonly<{\n label: string;\n description?: string;\n disabled?: boolean;\n /** An empty fieldIds list is a group-only error, not a reason to mark every field invalid. */\n error?: Readonly<{ message: string; fieldIds: readonly string[] }>;\n fields: readonly FieldGroupMember[];\n}>;\n\nexport type ResolvedFieldGroupMember = Readonly<{\n id: string;\n label: string;\n groupLabel: string;\n disabled: boolean;\n invalid: boolean;\n /** Renderers associate these messages without replacing a field's own help or error. */\n support: readonly Readonly<{ scope: \"group\" | \"field\"; kind: \"description\" | \"error\"; text: string }>[];\n}>;\n\nfunction requireText(value: unknown, name: string): asserts value is string {\n if (typeof value !== \"string\" || !value.trim()) throw new TypeError(`Field group ${name} must be nonempty text`);\n}\n\n/** Late native events and retained callbacks must use the current committed group policy. */\nexport function createFieldGroupEditSession(fields: readonly ResolvedFieldGroupMember[]) {\n let enabled = new Set(fields.filter(field => !field.disabled).map(field => field.id));\n const members = new Map(fields.map(field => [field.id, {}]));\n return {\n update(next: readonly ResolvedFieldGroupMember[]) {\n const current = new Set(next.map(field => field.id));\n // A reused id is a new mounted field after removal. Checking only enabled ids\n // would revive queued events from the old field and overwrite the new draft.\n for (const id of members.keys()) if (!current.has(id)) members.delete(id);\n for (const id of current) if (!members.has(id)) members.set(id, {});\n enabled = new Set(next.filter(field => !field.disabled).map(field => field.id));\n },\n /** Effect cleanup blocks events without treating Strict Mode replay as field removal. */\n suspend() { enabled.clear(); },\n guard<Args extends unknown[]>(id: string, callback: (...args: Args) => void): (...args: Args) => void {\n // A new host binds during render, before its committed policy enables it.\n if (!members.has(id)) members.set(id, {});\n const member = members.get(id);\n return (...args) => { if (members.get(id) === member && enabled.has(id)) callback(...args); };\n },\n };\n}\n\nfunction optionalText(value: unknown, name: string): void {\n if (value !== undefined) requireText(value, name);\n}\n\nfunction optionalBoolean(value: unknown): void {\n if (value !== undefined && typeof value !== \"boolean\") throw new TypeError(\"Field group disabled must be boolean\");\n}\n\nexport function resolveFieldGroup(descriptor: FieldGroupDescriptor): Readonly<{\n label: string;\n description: string | undefined;\n error: string | undefined;\n disabled: boolean;\n fields: readonly ResolvedFieldGroupMember[];\n}> {\n requireText(descriptor.label, \"label\");\n optionalText(descriptor.description, \"description\");\n optionalBoolean(descriptor.disabled);\n if (!Array.isArray(descriptor.fields)) throw new TypeError(\"Field group fields must be an array\");\n const ids = new Set<string>();\n for (const field of descriptor.fields) {\n requireText(field.id, \"field id\");\n requireText(field.label, \"field label\");\n optionalText(field.description, \"field description\");\n optionalText(field.error, \"field error\");\n optionalBoolean(field.disabled);\n if (ids.has(field.id)) throw new TypeError(\"Field group field ids must be unique\");\n ids.add(field.id);\n }\n if (descriptor.error !== undefined) {\n requireText(descriptor.error.message, \"error\");\n const affected = descriptor.error.fieldIds;\n // A typo or removed field must not silently lose its validation feedback.\n // Products update the visible error with their dynamic field list atomically.\n if (!Array.isArray(affected) || new Set(affected).size !== affected.length || affected.some(id => !ids.has(id))) {\n throw new TypeError(\"Field group error must reference distinct current field ids\");\n }\n }\n const disabled = descriptor.disabled ?? false;\n return Object.freeze({\n label: descriptor.label,\n description: descriptor.description,\n error: descriptor.error?.message,\n disabled,\n fields: Object.freeze(descriptor.fields.map(field => {\n const groupError = descriptor.error?.fieldIds.includes(field.id) ? descriptor.error.message : undefined;\n const support: ResolvedFieldGroupMember[\"support\"][number][] = [];\n if (descriptor.description !== undefined) support.push({ scope: \"group\", kind: \"description\", text: descriptor.description });\n if (field.description !== undefined) support.push({ scope: \"field\", kind: \"description\", text: field.description });\n if (field.error !== undefined) support.push({ scope: \"field\", kind: \"error\", text: field.error });\n if (groupError !== undefined) support.push({ scope: \"group\", kind: \"error\", text: groupError });\n return Object.freeze({ id: field.id, label: field.label, groupLabel: descriptor.label,\n // Group unlock restores independently disabled members; it never enables them.\n disabled: disabled || (field.disabled ?? false), invalid: field.error !== undefined || groupError !== undefined,\n support: Object.freeze(support.map(message => Object.freeze(message))) });\n })),\n });\n}\n"]}
|
|
@@ -1,8 +1,26 @@
|
|
|
1
|
-
export type TabsAppearance = "standard" | "gooey";
|
|
1
|
+
export type TabsAppearance = "standard" | "slide" | "gooey";
|
|
2
2
|
export type GooeyIndicatorRect = Readonly<{
|
|
3
3
|
x: number;
|
|
4
4
|
width: number;
|
|
5
5
|
}>;
|
|
6
|
+
/** A product's explicit appearance wins; vertical tabs keep the canonical line.
|
|
7
|
+
* Plain profile sliding is not an implicit request for elastic gooey stretching. */
|
|
8
|
+
export declare function resolveTabsAppearance(appearance: TabsAppearance | undefined, selectionMotion?: "none" | "slide", orientation?: "horizontal" | "vertical"): TabsAppearance;
|
|
9
|
+
/** Both renderers interpolate measured bounds without changing selection or panels. */
|
|
10
|
+
export declare function resolveTabIndicator(from: GooeyIndicatorRect, to: GooeyIndicatorRect, appearance: "slide" | "gooey"): {
|
|
11
|
+
readonly duration: 320;
|
|
12
|
+
readonly input: readonly [0, 0.45, 1];
|
|
13
|
+
readonly x: readonly [number, number, number];
|
|
14
|
+
readonly width: readonly [number, number, number];
|
|
15
|
+
} | {
|
|
16
|
+
readonly duration: 200;
|
|
17
|
+
readonly input: readonly [0, 1];
|
|
18
|
+
readonly x: readonly [number, number];
|
|
19
|
+
readonly width: readonly [number, number];
|
|
20
|
+
};
|
|
21
|
+
/** Capture the current JS-driver frame before cancellation so rapid input starts
|
|
22
|
+
* where the indicator is visible, rather than jumping to the abandoned target. */
|
|
23
|
+
export declare function sampleTabIndicator(recipe: ReturnType<typeof resolveTabIndicator>, progress: number): GooeyIndicatorRect;
|
|
6
24
|
/** Stretch only the selected indicator; tab hit targets and text never move. */
|
|
7
25
|
export declare function resolveGooeyIndicator(from: GooeyIndicatorRect, to: GooeyIndicatorRect): {
|
|
8
26
|
readonly duration: 320;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gooey-navigation.d.ts","sourceRoot":"","sources":["../src/gooey-navigation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gooey-navigation.d.ts","sourceRoot":"","sources":["../src/gooey-navigation.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAC5D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAExE;oFACoF;AACpF,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,cAAc,GAAG,SAAS,EACtC,eAAe,GAAE,MAAM,GAAG,OAAgB,EAC1C,WAAW,GAAE,YAAY,GAAG,UAAyB,GACpD,cAAc,CAGhB;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,kBAAkB,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO;;;;;;;;;;EAOlH;AAED;kFACkF;AAClF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAUvH;AAKD,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,kBAAkB;;;;;EAMrF"}
|