@hjmds/design-contracts 1.13.0 → 1.14.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 +5 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/component-recipes.d.ts +14 -0
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +16 -1
- package/dist/component-recipes.js.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/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/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/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/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/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/dialog.md +16 -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/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/screen-patterns.md +2 -0
- package/docs/sheet.md +9 -0
- package/docs/task-list.md +15 -1
- package/docs/text-annotation.md +85 -0
- package/docs/toggle-group.md +6 -0
- package/docs/usage/README.md +18 -1
- package/docs/usage/components/agreement.md +13 -3
- package/docs/usage/components/alert-dialog.md +7 -1
- package/docs/usage/components/avatar.md +33 -1
- package/docs/usage/components/card.md +7 -1
- package/docs/usage/components/carousel.md +5 -1
- package/docs/usage/components/chat-message.md +11 -1
- package/docs/usage/components/chip.md +10 -2
- package/docs/usage/components/content-transition.md +28 -4
- package/docs/usage/components/dialog.md +18 -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 +23 -0
- package/docs/usage/components/form.md +6 -1
- package/docs/usage/components/image-comparison.md +82 -0
- package/docs/usage/components/image.md +81 -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 +3 -1
- package/docs/usage/components/list.md +6 -1
- package/docs/usage/components/message-composer.md +5 -0
- package/docs/usage/components/popover.md +7 -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/search-field.md +10 -0
- package/docs/usage/components/search-screen.md +16 -5
- package/docs/usage/components/segmented-control.md +29 -4
- package/docs/usage/components/sheet.md +7 -1
- package/docs/usage/components/statistic.md +11 -0
- package/docs/usage/components/tags-input.md +5 -0
- package/docs/usage/components/toast.md +5 -0
- 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/context-toolbar.md +85 -0
- package/docs/usage/compositions/date-entry.md +108 -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/common-search.md +7 -2
- package/docs/usage/screens/flow-onboarding.md +5 -3
- package/docs/usage/screens/product-bento.md +117 -0
- package/package.json +37 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-transition.d.ts","sourceRoot":"","sources":["../src/content-transition.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1E;oFACoF;AACpF,eAAO,MAAM,uBAAuB;;;;CAAgD,CAAC;AACrF;8EAC8E;AAC9E,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,uBAAgC,EAAE,SAAS,GAAE,KAAK,GAAG,KAAa;;;;;EAQlH"}
|
|
1
|
+
{"version":3,"file":"content-transition.d.ts","sourceRoot":"","sources":["../src/content-transition.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1E;oFACoF;AACpF,eAAO,MAAM,uBAAuB;;;;CAAgD,CAAC;AACrF;8EAC8E;AAC9E,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,uBAAgC,EAAE,SAAS,GAAE,KAAK,GAAG,KAAa;;;;;EAQlH;AAED;oFACoF;AACpF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/F;;oFAEoF;AACpF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACzC,WAAW,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EAC9C,aAAa,UAAQ,GACpB,QAAQ,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAe7F"}
|
|
@@ -12,4 +12,25 @@ export function resolveContentTransition(preset = "fade", direction = "ltr") {
|
|
|
12
12
|
default: throw new TypeError("Unsupported content transition preset");
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
/** Invert the destination around its center so it starts at the trigger bounds.
|
|
16
|
+
* A renderer interpolates this transform to identity and owns cancellation,
|
|
17
|
+
* measurement freshness, presence and focus; this resolver never clones content. */
|
|
18
|
+
export function resolveOriginTransition(origin, destination, reducedMotion = false) {
|
|
19
|
+
// Missing/zero geometry occurs before layout and after trigger removal. Keep
|
|
20
|
+
// the canonical overlay available instead of throwing or guessing coordinates.
|
|
21
|
+
if (reducedMotion || !origin || !destination)
|
|
22
|
+
return null;
|
|
23
|
+
for (const rect of [origin, destination]) {
|
|
24
|
+
if (![rect.x, rect.y, rect.width, rect.height].every(Number.isFinite) || rect.width <= 0 || rect.height <= 0)
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const transform = {
|
|
28
|
+
translateX: (origin.x - destination.x) + (origin.width - destination.width) / 2,
|
|
29
|
+
translateY: (origin.y - destination.y) + (origin.height - destination.height) / 2,
|
|
30
|
+
scaleX: origin.width / destination.width,
|
|
31
|
+
scaleY: origin.height / destination.height,
|
|
32
|
+
};
|
|
33
|
+
// Finite measurements can still overflow or underflow during subtraction/division.
|
|
34
|
+
return Object.values(transform).every(Number.isFinite) && transform.scaleX > 0 && transform.scaleY > 0 ? transform : null;
|
|
35
|
+
}
|
|
15
36
|
//# sourceMappingURL=content-transition.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-transition.js","sourceRoot":"","sources":["../src/content-transition.ts"],"names":[],"mappings":"AACA;oFACoF;AACpF,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAW,CAAC;AACrF;8EAC8E;AAC9E,MAAM,UAAU,wBAAwB,CAAC,SAAkC,MAAM,EAAE,YAA2B,KAAK;IACjH,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC3E,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACtG,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACzI,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,uBAAuB,CAAC,KAAK,EAAE,CAAC;QACxG,OAAO,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;IACxE,CAAC;AACH,CAAC","sourcesContent":["export type ContentTransitionPreset = \"fade\" | \"rise\" | \"slide\" | \"scale\";\n/** Small local travel preserves context; these are presentation values, never\n * gesture activation thresholds. Retain the existing geometry for compatibility. */\nexport const contentTransitionMotion = { rise: 12, slide: 16, scale: 0.96 } as const;\n/** Bounded travel keeps decorative motion close to the destination.\n * Single-subtree recipes: preserve wrapping, focus and accessible content. */\nexport function resolveContentTransition(preset: ContentTransitionPreset = \"fade\", direction: \"ltr\" | \"rtl\" = \"ltr\") {\n switch (preset) {\n case \"fade\": return { opacity: 0, translateX: 0, translateY: 0, scale: 1 };\n case \"rise\": return { opacity: 0, translateX: 0, translateY: contentTransitionMotion.rise, scale: 1 };\n case \"slide\": return { opacity: 0, translateX: (direction === \"rtl\" ? -1 : 1) * contentTransitionMotion.slide, translateY: 0, scale: 1 };\n case \"scale\": return { opacity: 0, translateX: 0, translateY: 0, scale: contentTransitionMotion.scale };\n default: throw new TypeError(\"Unsupported content transition preset\");\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"content-transition.js","sourceRoot":"","sources":["../src/content-transition.ts"],"names":[],"mappings":"AACA;oFACoF;AACpF,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAW,CAAC;AACrF;8EAC8E;AAC9E,MAAM,UAAU,wBAAwB,CAAC,SAAkC,MAAM,EAAE,YAA2B,KAAK;IACjH,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC3E,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACtG,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACzI,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,uBAAuB,CAAC,KAAK,EAAE,CAAC;QACxG,OAAO,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAMD;;oFAEoF;AACpF,MAAM,UAAU,uBAAuB,CACrC,MAAyC,EACzC,WAA8C,EAC9C,aAAa,GAAG,KAAK;IAErB,6EAA6E;IAC7E,+EAA+E;IAC/E,IAAI,aAAa,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC1D,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC5H,CAAC;IACD,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC;QAC/E,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;QACjF,MAAM,EAAE,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK;QACxC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM;KAC3C,CAAC;IACF,mFAAmF;IACnF,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5H,CAAC","sourcesContent":["export type ContentTransitionPreset = \"fade\" | \"rise\" | \"slide\" | \"scale\";\n/** Small local travel preserves context; these are presentation values, never\n * gesture activation thresholds. Retain the existing geometry for compatibility. */\nexport const contentTransitionMotion = { rise: 12, slide: 16, scale: 0.96 } as const;\n/** Bounded travel keeps decorative motion close to the destination.\n * Single-subtree recipes: preserve wrapping, focus and accessible content. */\nexport function resolveContentTransition(preset: ContentTransitionPreset = \"fade\", direction: \"ltr\" | \"rtl\" = \"ltr\") {\n switch (preset) {\n case \"fade\": return { opacity: 0, translateX: 0, translateY: 0, scale: 1 };\n case \"rise\": return { opacity: 0, translateX: 0, translateY: contentTransitionMotion.rise, scale: 1 };\n case \"slide\": return { opacity: 0, translateX: (direction === \"rtl\" ? -1 : 1) * contentTransitionMotion.slide, translateY: 0, scale: 1 };\n case \"scale\": return { opacity: 0, translateX: 0, translateY: 0, scale: contentTransitionMotion.scale };\n default: throw new TypeError(\"Unsupported content transition preset\");\n }\n}\n\n/** Both rectangles must be measured in the same physical viewport coordinates.\n * Router shared-element IDs are not a substitute for a local overlay's geometry. */\nexport type TransitionRect = Readonly<{ x: number; y: number; width: number; height: number }>;\n\n/** Invert the destination around its center so it starts at the trigger bounds.\n * A renderer interpolates this transform to identity and owns cancellation,\n * measurement freshness, presence and focus; this resolver never clones content. */\nexport function resolveOriginTransition(\n origin: TransitionRect | null | undefined,\n destination: TransitionRect | null | undefined,\n reducedMotion = false,\n): Readonly<{ translateX: number; translateY: number; scaleX: number; scaleY: number }> | null {\n // Missing/zero geometry occurs before layout and after trigger removal. Keep\n // the canonical overlay available instead of throwing or guessing coordinates.\n if (reducedMotion || !origin || !destination) return null;\n for (const rect of [origin, destination]) {\n if (![rect.x, rect.y, rect.width, rect.height].every(Number.isFinite) || rect.width <= 0 || rect.height <= 0) return null;\n }\n const transform = {\n translateX: (origin.x - destination.x) + (origin.width - destination.width) / 2,\n translateY: (origin.y - destination.y) + (origin.height - destination.height) / 2,\n scaleX: origin.width / destination.width,\n scaleY: origin.height / destination.height,\n };\n // Finite measurements can still overflow or underflow during subtraction/division.\n return Object.values(transform).every(Number.isFinite) && transform.scaleX > 0 && transform.scaleY > 0 ? transform : null;\n}\n"]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Experimental direct date entry contract; date calculation remains product-owned. */
|
|
2
|
+
export type DateEntryPart = "year" | "month" | "day";
|
|
3
|
+
export type DateEntryDraft = Readonly<Record<DateEntryPart, string>>;
|
|
4
|
+
export type DateEntryOrder = readonly [DateEntryPart, DateEntryPart, DateEntryPart];
|
|
5
|
+
export type DateEntryParseResult = Readonly<{
|
|
6
|
+
status: "valid";
|
|
7
|
+
value: string;
|
|
8
|
+
}> | Readonly<{
|
|
9
|
+
status: "incomplete" | "invalid";
|
|
10
|
+
code: string;
|
|
11
|
+
fields: readonly DateEntryPart[];
|
|
12
|
+
}>;
|
|
13
|
+
export type DateEntryIssue = Readonly<{
|
|
14
|
+
kind: "missing";
|
|
15
|
+
fields: readonly DateEntryPart[];
|
|
16
|
+
}> | Readonly<{
|
|
17
|
+
kind: "parse";
|
|
18
|
+
code: string;
|
|
19
|
+
fields: readonly DateEntryPart[];
|
|
20
|
+
}>;
|
|
21
|
+
export type ResolvedDateEntry = Readonly<{
|
|
22
|
+
draft: DateEntryDraft;
|
|
23
|
+
status: "empty" | "incomplete" | "invalid" | "valid";
|
|
24
|
+
/** An optional empty date and any uncommitted draft have no committed value. */
|
|
25
|
+
value: string | null;
|
|
26
|
+
issue: DateEntryIssue | null;
|
|
27
|
+
fields: readonly Readonly<{
|
|
28
|
+
part: DateEntryPart;
|
|
29
|
+
value: string;
|
|
30
|
+
invalid: boolean;
|
|
31
|
+
}>[];
|
|
32
|
+
}>;
|
|
33
|
+
/** Preserve exact input, including partial years, names, whitespace and composition text. */
|
|
34
|
+
export declare function updateDateEntryDraft(draft: DateEntryDraft, part: DateEntryPart, value: string): DateEntryDraft;
|
|
35
|
+
export declare function resolveDateEntryDraft({ draft, order, required, parse }: {
|
|
36
|
+
draft: DateEntryDraft;
|
|
37
|
+
order: DateEntryOrder;
|
|
38
|
+
required: boolean;
|
|
39
|
+
parse: (draft: DateEntryDraft) => DateEntryParseResult;
|
|
40
|
+
}): ResolvedDateEntry;
|
|
41
|
+
export type DateEntryControlProps = Readonly<{
|
|
42
|
+
value: DateEntryDraft;
|
|
43
|
+
onValueChange: (draft: DateEntryDraft) => void;
|
|
44
|
+
order: DateEntryOrder;
|
|
45
|
+
parse: (draft: DateEntryDraft) => DateEntryParseResult;
|
|
46
|
+
labels: Readonly<Record<DateEntryPart | "label", string>>;
|
|
47
|
+
formatIssue: (issue: DateEntryIssue) => string;
|
|
48
|
+
description?: string;
|
|
49
|
+
required?: boolean;
|
|
50
|
+
disabled?: boolean;
|
|
51
|
+
readOnly?: boolean;
|
|
52
|
+
/** Products reveal validation on submit/blur; typing never forces errors visible. */
|
|
53
|
+
showErrors?: boolean;
|
|
54
|
+
purpose?: "date" | "birthdate";
|
|
55
|
+
/** Text is the default so localized month names remain enterable. */
|
|
56
|
+
monthInput?: "text" | "numeric";
|
|
57
|
+
onBlur?: (part: DateEntryPart) => void;
|
|
58
|
+
}>;
|
|
59
|
+
export declare function resolveDateEntryControl(props: DateEntryControlProps): {
|
|
60
|
+
error: string | undefined;
|
|
61
|
+
draft: DateEntryDraft;
|
|
62
|
+
status: "empty" | "incomplete" | "invalid" | "valid";
|
|
63
|
+
value: string | null;
|
|
64
|
+
issue: DateEntryIssue | null;
|
|
65
|
+
fields: readonly Readonly<{
|
|
66
|
+
part: DateEntryPart;
|
|
67
|
+
value: string;
|
|
68
|
+
invalid: boolean;
|
|
69
|
+
}>[];
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=date-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-entry.d.ts","sourceRoot":"","sources":["../src/date-entry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const parts = ["year", "month", "day"];
|
|
2
|
+
function assertDraft(draft) {
|
|
3
|
+
if (!draft || parts.some(part => typeof draft[part] !== "string")) {
|
|
4
|
+
throw new TypeError("Date entry requires string drafts for year, month and day");
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
function assertParts(values, complete = false) {
|
|
8
|
+
if (!Array.isArray(values) || !values.length || new Set(values).size !== values.length ||
|
|
9
|
+
values.some(part => !parts.includes(part)) || (complete && values.length !== 3)) {
|
|
10
|
+
throw new TypeError("Date entry requires distinct date parts and a complete display order");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Preserve exact input, including partial years, names, whitespace and composition text. */
|
|
14
|
+
export function updateDateEntryDraft(draft, part, value) {
|
|
15
|
+
assertDraft(draft);
|
|
16
|
+
if (!parts.includes(part) || typeof value !== "string")
|
|
17
|
+
throw new TypeError("Invalid date entry edit");
|
|
18
|
+
return { ...draft, [part]: value };
|
|
19
|
+
}
|
|
20
|
+
export function resolveDateEntryDraft({ draft, order, required, parse }) {
|
|
21
|
+
assertDraft(draft);
|
|
22
|
+
assertParts(order, true);
|
|
23
|
+
if (typeof required !== "boolean" || typeof parse !== "function")
|
|
24
|
+
throw new TypeError("Date entry requires required and parse policies");
|
|
25
|
+
// Calendar already leaves locale/calendar/clock policy to products. A second
|
|
26
|
+
// Date-based parser would normalize impossible dates and disagree with it.
|
|
27
|
+
// Freeze a snapshot so an adapter cannot rewrite the user's editing draft.
|
|
28
|
+
const snapshot = Object.freeze({ year: draft.year, month: draft.month, day: draft.day });
|
|
29
|
+
const missing = order.filter(part => !snapshot[part].trim());
|
|
30
|
+
let status;
|
|
31
|
+
let value = null;
|
|
32
|
+
let issue = null;
|
|
33
|
+
if (missing.length === 3) {
|
|
34
|
+
status = "empty";
|
|
35
|
+
if (required)
|
|
36
|
+
issue = { kind: "missing", fields: missing };
|
|
37
|
+
}
|
|
38
|
+
else if (missing.length) {
|
|
39
|
+
// Missing data takes priority over format/range errors, so filling one part
|
|
40
|
+
// cannot hide which other parts are still needed (GOV.UK date-input guidance).
|
|
41
|
+
status = "incomplete";
|
|
42
|
+
issue = { kind: "missing", fields: missing };
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const result = parse(snapshot);
|
|
46
|
+
if (result?.status === "valid") {
|
|
47
|
+
if (typeof result.value !== "string" || !result.value.trim())
|
|
48
|
+
throw new TypeError("A valid date entry needs a nonempty value");
|
|
49
|
+
status = "valid";
|
|
50
|
+
value = result.value;
|
|
51
|
+
}
|
|
52
|
+
else if (result?.status === "incomplete" || result?.status === "invalid") {
|
|
53
|
+
if (typeof result.code !== "string" || !result.code.trim())
|
|
54
|
+
throw new TypeError("Date entry issue needs a localization code");
|
|
55
|
+
assertParts(result.fields);
|
|
56
|
+
status = result.status;
|
|
57
|
+
issue = { kind: "parse", code: result.code, fields: order.filter(part => result.fields.includes(part)) };
|
|
58
|
+
}
|
|
59
|
+
else
|
|
60
|
+
throw new TypeError("Invalid date entry parse result");
|
|
61
|
+
}
|
|
62
|
+
return { draft: snapshot, status, value, issue,
|
|
63
|
+
fields: order.map(part => ({ part, value: snapshot[part], invalid: issue?.fields.includes(part) ?? false })) };
|
|
64
|
+
}
|
|
65
|
+
export function resolveDateEntryControl(props) {
|
|
66
|
+
if (["label", ...parts].some(key => !props.labels?.[key]?.trim()) ||
|
|
67
|
+
typeof props.onValueChange !== "function" || typeof props.formatIssue !== "function" ||
|
|
68
|
+
(props.purpose !== undefined && !["date", "birthdate"].includes(props.purpose)) ||
|
|
69
|
+
(props.monthInput !== undefined && !["text", "numeric"].includes(props.monthInput))) {
|
|
70
|
+
throw new TypeError("Date entry needs labels, callbacks and valid input policies");
|
|
71
|
+
}
|
|
72
|
+
const resolved = resolveDateEntryDraft({ draft: props.value, order: props.order, required: props.required ?? false, parse: props.parse });
|
|
73
|
+
const error = props.showErrors && resolved.issue ? props.formatIssue(resolved.issue) : undefined;
|
|
74
|
+
if (error !== undefined && (typeof error !== "string" || !error.trim()))
|
|
75
|
+
throw new TypeError("Date entry issue text must not be empty");
|
|
76
|
+
return { ...resolved, error };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=date-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-entry.js","sourceRoot":"","sources":["../src/date-entry.ts"],"names":[],"mappings":"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","sourcesContent":["/** Experimental direct date entry contract; date calculation remains product-owned. */\nexport type DateEntryPart = \"year\" | \"month\" | \"day\";\nexport type DateEntryDraft = Readonly<Record<DateEntryPart, string>>;\nexport type DateEntryOrder = readonly [DateEntryPart, DateEntryPart, DateEntryPart];\nexport type DateEntryParseResult =\n | Readonly<{ status: \"valid\"; value: string }>\n | Readonly<{ status: \"incomplete\" | \"invalid\"; code: string; fields: readonly DateEntryPart[] }>;\nexport type DateEntryIssue =\n | Readonly<{ kind: \"missing\"; fields: readonly DateEntryPart[] }>\n | Readonly<{ kind: \"parse\"; code: string; fields: readonly DateEntryPart[] }>;\nexport type ResolvedDateEntry = Readonly<{\n draft: DateEntryDraft;\n status: \"empty\" | \"incomplete\" | \"invalid\" | \"valid\";\n /** An optional empty date and any uncommitted draft have no committed value. */\n value: string | null;\n issue: DateEntryIssue | null;\n fields: readonly Readonly<{ part: DateEntryPart; value: string; invalid: boolean }>[];\n}>;\nconst parts: readonly DateEntryPart[] = [\"year\", \"month\", \"day\"];\nfunction assertDraft(draft: DateEntryDraft): void {\n if (!draft || parts.some(part => typeof draft[part] !== \"string\")) {\n throw new TypeError(\"Date entry requires string drafts for year, month and day\");\n }\n}\nfunction assertParts(values: readonly DateEntryPart[], complete = false): void {\n if (!Array.isArray(values) || !values.length || new Set(values).size !== values.length ||\n values.some(part => !parts.includes(part)) || (complete && values.length !== 3)) {\n throw new TypeError(\"Date entry requires distinct date parts and a complete display order\");\n }\n}\n\n/** Preserve exact input, including partial years, names, whitespace and composition text. */\nexport function updateDateEntryDraft(draft: DateEntryDraft, part: DateEntryPart, value: string): DateEntryDraft {\n assertDraft(draft);\n if (!parts.includes(part) || typeof value !== \"string\") throw new TypeError(\"Invalid date entry edit\");\n return { ...draft, [part]: value };\n}\n\nexport function resolveDateEntryDraft({ draft, order, required, parse }: {\n draft: DateEntryDraft;\n order: DateEntryOrder;\n required: boolean;\n parse: (draft: DateEntryDraft) => DateEntryParseResult;\n}): ResolvedDateEntry {\n assertDraft(draft);\n assertParts(order, true);\n if (typeof required !== \"boolean\" || typeof parse !== \"function\") throw new TypeError(\"Date entry requires required and parse policies\");\n // Calendar already leaves locale/calendar/clock policy to products. A second\n // Date-based parser would normalize impossible dates and disagree with it.\n // Freeze a snapshot so an adapter cannot rewrite the user's editing draft.\n const snapshot = Object.freeze({ year: draft.year, month: draft.month, day: draft.day });\n const missing = order.filter(part => !snapshot[part].trim());\n let status: ResolvedDateEntry[\"status\"];\n let value: string | null = null;\n let issue: DateEntryIssue | null = null;\n if (missing.length === 3) {\n status = \"empty\";\n if (required) issue = { kind: \"missing\", fields: missing };\n } else if (missing.length) {\n // Missing data takes priority over format/range errors, so filling one part\n // cannot hide which other parts are still needed (GOV.UK date-input guidance).\n status = \"incomplete\";\n issue = { kind: \"missing\", fields: missing };\n } else {\n const result = parse(snapshot);\n if (result?.status === \"valid\") {\n if (typeof result.value !== \"string\" || !result.value.trim()) throw new TypeError(\"A valid date entry needs a nonempty value\");\n status = \"valid\";\n value = result.value;\n } else if (result?.status === \"incomplete\" || result?.status === \"invalid\") {\n if (typeof result.code !== \"string\" || !result.code.trim()) throw new TypeError(\"Date entry issue needs a localization code\");\n assertParts(result.fields);\n status = result.status;\n issue = { kind: \"parse\", code: result.code, fields: order.filter(part => result.fields.includes(part)) };\n } else throw new TypeError(\"Invalid date entry parse result\");\n }\n return { draft: snapshot, status, value, issue,\n fields: order.map(part => ({ part, value: snapshot[part], invalid: issue?.fields.includes(part) ?? false })) };\n}\n\nexport type DateEntryControlProps = Readonly<{\n value: DateEntryDraft;\n onValueChange: (draft: DateEntryDraft) => void;\n order: DateEntryOrder;\n parse: (draft: DateEntryDraft) => DateEntryParseResult;\n labels: Readonly<Record<DateEntryPart | \"label\", string>>;\n formatIssue: (issue: DateEntryIssue) => string;\n description?: string;\n required?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n /** Products reveal validation on submit/blur; typing never forces errors visible. */\n showErrors?: boolean;\n purpose?: \"date\" | \"birthdate\";\n /** Text is the default so localized month names remain enterable. */\n monthInput?: \"text\" | \"numeric\";\n onBlur?: (part: DateEntryPart) => void;\n}>;\n\nexport function resolveDateEntryControl(props: DateEntryControlProps) {\n if ([\"label\", ...parts].some(key => !props.labels?.[key as keyof typeof props.labels]?.trim()) ||\n typeof props.onValueChange !== \"function\" || typeof props.formatIssue !== \"function\" ||\n (props.purpose !== undefined && ![\"date\", \"birthdate\"].includes(props.purpose)) ||\n (props.monthInput !== undefined && ![\"text\", \"numeric\"].includes(props.monthInput))) {\n throw new TypeError(\"Date entry needs labels, callbacks and valid input policies\");\n }\n const resolved = resolveDateEntryDraft({ draft: props.value, order: props.order, required: props.required ?? false, parse: props.parse });\n const error = props.showErrors && resolved.issue ? props.formatIssue(resolved.issue) : undefined;\n if (error !== undefined && (typeof error !== \"string\" || !error.trim())) throw new TypeError(\"Date entry issue text must not be empty\");\n return { ...resolved, error };\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"}
|