@contentful/experiences-angular 0.2.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/CHANGELOG.md +189 -0
- package/README.md +368 -0
- package/dist/client-experience-renderer.component.d.ts +42 -0
- package/dist/client-experience-renderer.component.d.ts.map +1 -0
- package/dist/client-experience-renderer.component.js +155 -0
- package/dist/client-experience-renderer.component.js.map +1 -0
- package/dist/component-error.component.d.ts +14 -0
- package/dist/component-error.component.d.ts.map +1 -0
- package/dist/component-error.component.js +81 -0
- package/dist/component-error.component.js.map +1 -0
- package/dist/context.d.ts +21 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +54 -0
- package/dist/context.js.map +1 -0
- package/dist/debug-experience.component.d.ts +17 -0
- package/dist/debug-experience.component.d.ts.map +1 -0
- package/dist/debug-experience.component.js +143 -0
- package/dist/debug-experience.component.js.map +1 -0
- package/dist/design-utils.d.ts +22 -0
- package/dist/design-utils.d.ts.map +1 -0
- package/dist/design-utils.js +40 -0
- package/dist/design-utils.js.map +1 -0
- package/dist/experience-defaults.d.ts +16 -0
- package/dist/experience-defaults.d.ts.map +1 -0
- package/dist/experience-defaults.js +27 -0
- package/dist/experience-defaults.js.map +1 -0
- package/dist/experience-scope.d.ts +33 -0
- package/dist/experience-scope.d.ts.map +1 -0
- package/dist/experience-scope.js +90 -0
- package/dist/experience-scope.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/inject-active-viewport.d.ts +32 -0
- package/dist/inject-active-viewport.d.ts.map +1 -0
- package/dist/inject-active-viewport.js +78 -0
- package/dist/inject-active-viewport.js.map +1 -0
- package/dist/inject-design-values.d.ts +14 -0
- package/dist/inject-design-values.d.ts.map +1 -0
- package/dist/inject-design-values.js +24 -0
- package/dist/inject-design-values.js.map +1 -0
- package/dist/inject-experience-plan.d.ts +15 -0
- package/dist/inject-experience-plan.d.ts.map +1 -0
- package/dist/inject-experience-plan.js +39 -0
- package/dist/inject-experience-plan.js.map +1 -0
- package/dist/inject-live-preview-experience.d.ts +13 -0
- package/dist/inject-live-preview-experience.d.ts.map +1 -0
- package/dist/inject-live-preview-experience.js +47 -0
- package/dist/inject-live-preview-experience.js.map +1 -0
- package/dist/inject-live-preview.d.ts +16 -0
- package/dist/inject-live-preview.d.ts.map +1 -0
- package/dist/inject-live-preview.js +14 -0
- package/dist/inject-live-preview.js.map +1 -0
- package/dist/missing-component.component.d.ts +14 -0
- package/dist/missing-component.component.d.ts.map +1 -0
- package/dist/missing-component.component.js +83 -0
- package/dist/missing-component.component.js.map +1 -0
- package/dist/node-render-engine.d.ts +109 -0
- package/dist/node-render-engine.d.ts.map +1 -0
- package/dist/node-render-engine.js +528 -0
- package/dist/node-render-engine.js.map +1 -0
- package/dist/node-renderer.directive.d.ts +46 -0
- package/dist/node-renderer.directive.d.ts.map +1 -0
- package/dist/node-renderer.directive.js +96 -0
- package/dist/node-renderer.directive.js.map +1 -0
- package/dist/node-scopes.d.ts +39 -0
- package/dist/node-scopes.d.ts.map +1 -0
- package/dist/node-scopes.js +75 -0
- package/dist/node-scopes.js.map +1 -0
- package/dist/server-experience-renderer.component.d.ts +46 -0
- package/dist/server-experience-renderer.component.d.ts.map +1 -0
- package/dist/server-experience-renderer.component.js +159 -0
- package/dist/server-experience-renderer.component.js.map +1 -0
- package/dist/types.d.ts +137 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +44 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Browser entry point. Port of adapter-svelte/src/ClientExperienceRenderer.svelte.
|
|
3
|
+
*
|
|
4
|
+
* Identical to `<cf-server-experience>` except that the active viewport tracks
|
|
5
|
+
* `window.matchMedia` instead of being fixed at render time, so design values
|
|
6
|
+
* re-cascade as the window resizes.
|
|
7
|
+
*
|
|
8
|
+
* Simpler than the Svelte original: Svelte mutates a `$state` object in place
|
|
9
|
+
* because its contexts are snapshots, so the mirror and the `$effect` that keeps
|
|
10
|
+
* it in sync are load-bearing there. Angular signals have no such constraint —
|
|
11
|
+
* one `computed` is the whole thing.
|
|
12
|
+
*/
|
|
13
|
+
import { ChangeDetectionStrategy, Component, Input, computed, inject, signal, } from '@angular/core';
|
|
14
|
+
import { ComponentErrorComponent } from './component-error.component.js';
|
|
15
|
+
import { DebugExperienceComponent } from './debug-experience.component.js';
|
|
16
|
+
import { DEFAULT_CONTEXT, EMPTY_CONFIG, FALLBACK_VIEWPORT } from './experience-defaults.js';
|
|
17
|
+
import { ExperienceScope } from './experience-scope.js';
|
|
18
|
+
import { injectActiveViewport } from './inject-active-viewport.js';
|
|
19
|
+
import { MissingComponentComponent } from './missing-component.component.js';
|
|
20
|
+
import { NodesRendererDirective } from './node-renderer.directive.js';
|
|
21
|
+
import * as i0 from "@angular/core";
|
|
22
|
+
export class ClientExperienceRendererComponent {
|
|
23
|
+
/** A resolved render plan, or `null` while one is still being fetched. */
|
|
24
|
+
set experience(value) {
|
|
25
|
+
this.experienceValue.set(value ?? null);
|
|
26
|
+
}
|
|
27
|
+
set config(value) {
|
|
28
|
+
this.configValue.set(value);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Viewport to render for until `matchMedia` takes over after the first render.
|
|
32
|
+
* Set it to whatever the server rendered with so hydration does not flicker.
|
|
33
|
+
*/
|
|
34
|
+
set initialViewportId(value) {
|
|
35
|
+
this.initialViewportIdValue.set(value);
|
|
36
|
+
}
|
|
37
|
+
/** Shallow-merges over the plan's `metadata`. Only needed to override it. */
|
|
38
|
+
set metadata(value) {
|
|
39
|
+
this.metadataValue.set(value);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Renders the resolved plan above the experience for inspection. Defaults to
|
|
43
|
+
* the plan's `debug`; `[debug]="false"` overrides a debug-on plan.
|
|
44
|
+
*/
|
|
45
|
+
set debug(value) {
|
|
46
|
+
this.debugValue.set(value);
|
|
47
|
+
}
|
|
48
|
+
/** Replaces the default missing-component box. Receives `componentId` and `nodeId`. */
|
|
49
|
+
set renderUnknown(value) {
|
|
50
|
+
this.renderUnknownValue.set(value ?? MissingComponentComponent);
|
|
51
|
+
}
|
|
52
|
+
/** Replaces the default error box rendered when a registered component throws. */
|
|
53
|
+
set renderError(value) {
|
|
54
|
+
this.renderErrorValue.set(value ?? ComponentErrorComponent);
|
|
55
|
+
}
|
|
56
|
+
constructor() {
|
|
57
|
+
this.experienceValue = signal(null, ...(ngDevMode ? [{ debugName: "experienceValue" }] : []));
|
|
58
|
+
// `undefined` means "not bound", distinct from an explicit `[debug]="false"`.
|
|
59
|
+
this.debugValue = signal(undefined, ...(ngDevMode ? [{ debugName: "debugValue" }] : []));
|
|
60
|
+
this.resolvedDebug = computed(() => this.debugValue() ?? this.experienceValue()?.debug ?? false, ...(ngDevMode ? [{ debugName: "resolvedDebug" }] : []));
|
|
61
|
+
this.configValue = signal(null, ...(ngDevMode ? [{ debugName: "configValue" }] : []));
|
|
62
|
+
this.initialViewportIdValue = signal(undefined, ...(ngDevMode ? [{ debugName: "initialViewportIdValue" }] : []));
|
|
63
|
+
this.metadataValue = signal(undefined, ...(ngDevMode ? [{ debugName: "metadataValue" }] : []));
|
|
64
|
+
this.renderUnknownValue = signal(MissingComponentComponent, ...(ngDevMode ? [{ debugName: "renderUnknownValue" }] : []));
|
|
65
|
+
this.renderErrorValue = signal(ComponentErrorComponent, ...(ngDevMode ? [{ debugName: "renderErrorValue" }] : []));
|
|
66
|
+
// Getters, not values: this runs during construction, before Angular has bound
|
|
67
|
+
// a single input. See injectActiveViewport's docblock.
|
|
68
|
+
this.tracker = injectActiveViewport(() => this.experienceValue()?.viewports ?? [],
|
|
69
|
+
// Seed from the plan so first paint matches the server renderer.
|
|
70
|
+
() => {
|
|
71
|
+
const explicit = this.initialViewportIdValue();
|
|
72
|
+
if (explicit !== undefined)
|
|
73
|
+
return explicit;
|
|
74
|
+
const experience = this.experienceValue();
|
|
75
|
+
return experience?.viewports[experience.fallbackViewportIndex]?.id;
|
|
76
|
+
});
|
|
77
|
+
this.renderContext = computed(() => {
|
|
78
|
+
const experience = this.experienceValue();
|
|
79
|
+
const activeViewportIndex = this.tracker.activeViewportIndex();
|
|
80
|
+
return {
|
|
81
|
+
...DEFAULT_CONTEXT,
|
|
82
|
+
debug: this.resolvedDebug(),
|
|
83
|
+
metadata: {
|
|
84
|
+
...DEFAULT_CONTEXT.metadata,
|
|
85
|
+
...(experience?.metadata ?? {}),
|
|
86
|
+
...(this.metadataValue() ?? {}),
|
|
87
|
+
},
|
|
88
|
+
viewports: experience?.viewports ?? [],
|
|
89
|
+
activeViewport: experience?.viewports[activeViewportIndex] ?? FALLBACK_VIEWPORT,
|
|
90
|
+
activeViewportIndex,
|
|
91
|
+
fallbackViewportIndex: experience?.fallbackViewportIndex ?? 0,
|
|
92
|
+
};
|
|
93
|
+
}, ...(ngDevMode ? [{ debugName: "renderContext" }] : []));
|
|
94
|
+
this.scope = inject(ExperienceScope);
|
|
95
|
+
/** Resolve-time + render-time diagnostics, merged for `<cf-debug-experience>`. */
|
|
96
|
+
this.errors = computed(() => [
|
|
97
|
+
...(this.experienceValue()?.diagnostics ?? []),
|
|
98
|
+
...this.scope.diagnostics(),
|
|
99
|
+
], ...(ngDevMode ? [{ debugName: "errors" }] : []));
|
|
100
|
+
this.scope.connectExperience(() => this.renderContext());
|
|
101
|
+
this.scope.connectConfig(() => this.configValue() ?? EMPTY_CONFIG);
|
|
102
|
+
this.scope.connectRenderUnknown(() => this.renderUnknownValue());
|
|
103
|
+
this.scope.connectRenderError(() => this.renderErrorValue());
|
|
104
|
+
}
|
|
105
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: ClientExperienceRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
106
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.28", type: ClientExperienceRendererComponent, isStandalone: true, selector: "cf-experience", inputs: { experience: "experience", config: "config", initialViewportId: "initialViewportId", metadata: "metadata", debug: "debug", renderUnknown: "renderUnknown", renderError: "renderError" }, providers: [ExperienceScope], ngImport: i0, template: `
|
|
107
|
+
@if (experienceValue(); as experience) {
|
|
108
|
+
<ng-container *cfNodes="experience.nodes"></ng-container>
|
|
109
|
+
@if (resolvedDebug()) {
|
|
110
|
+
<cf-debug-experience [experience]="experience" [errors]="errors()" />
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
`, isInline: true, dependencies: [{ kind: "component", type: DebugExperienceComponent, selector: "cf-debug-experience", inputs: ["experience", "defaultOpen", "errors"] }, { kind: "directive", type: NodesRendererDirective, selector: "[cfNodes]", inputs: ["cfNodes"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
114
|
+
}
|
|
115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: ClientExperienceRendererComponent, decorators: [{
|
|
116
|
+
type: Component,
|
|
117
|
+
args: [{
|
|
118
|
+
selector: 'cf-experience',
|
|
119
|
+
imports: [DebugExperienceComponent, NodesRendererDirective],
|
|
120
|
+
providers: [ExperienceScope],
|
|
121
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
122
|
+
// The `<cf-experience>` host element itself stays a real element — it is the
|
|
123
|
+
// customer's mount point, and they may well style it. Only the plumbing
|
|
124
|
+
// *inside* it is anchor-only: `*cfNodes` puts the top-level nodes here as
|
|
125
|
+
// siblings of a comment, so nothing the adapter owns wraps them.
|
|
126
|
+
//
|
|
127
|
+
// See the matching note in server-experience-renderer.component.ts on why
|
|
128
|
+
// the node tree renders before `<cf-debug-experience>`.
|
|
129
|
+
template: `
|
|
130
|
+
@if (experienceValue(); as experience) {
|
|
131
|
+
<ng-container *cfNodes="experience.nodes"></ng-container>
|
|
132
|
+
@if (resolvedDebug()) {
|
|
133
|
+
<cf-debug-experience [experience]="experience" [errors]="errors()" />
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
`,
|
|
137
|
+
}]
|
|
138
|
+
}], ctorParameters: () => [], propDecorators: { experience: [{
|
|
139
|
+
type: Input,
|
|
140
|
+
args: [{ required: true }]
|
|
141
|
+
}], config: [{
|
|
142
|
+
type: Input,
|
|
143
|
+
args: [{ required: true }]
|
|
144
|
+
}], initialViewportId: [{
|
|
145
|
+
type: Input
|
|
146
|
+
}], metadata: [{
|
|
147
|
+
type: Input
|
|
148
|
+
}], debug: [{
|
|
149
|
+
type: Input
|
|
150
|
+
}], renderUnknown: [{
|
|
151
|
+
type: Input
|
|
152
|
+
}], renderError: [{
|
|
153
|
+
type: Input
|
|
154
|
+
}] } });
|
|
155
|
+
//# sourceMappingURL=client-experience-renderer.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-experience-renderer.component.js","sourceRoot":"","sources":["../src/client-experience-renderer.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class ComponentErrorComponent {
|
|
3
|
+
protected readonly componentIdValue: import("@angular/core").WritableSignal<string>;
|
|
4
|
+
protected readonly nodeIdValue: import("@angular/core").WritableSignal<string | undefined>;
|
|
5
|
+
protected readonly messageValue: import("@angular/core").WritableSignal<string | undefined>;
|
|
6
|
+
set componentId(value: string);
|
|
7
|
+
set nodeId(value: string | undefined);
|
|
8
|
+
set message(value: string | undefined);
|
|
9
|
+
protected readonly experience: import("@angular/core").Signal<import("@contentful/experiences-sdk-core").RenderContext>;
|
|
10
|
+
protected readonly details: import("@angular/core").Signal<string>;
|
|
11
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ComponentErrorComponent, never>;
|
|
12
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ComponentErrorComponent, "cf-component-error", never, { "componentId": { "alias": "componentId"; "required": true; }; "nodeId": { "alias": "nodeId"; "required": false; }; "message": { "alias": "message"; "required": false; }; }, {}, never, never, true, never>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=component-error.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-error.component.d.ts","sourceRoot":"","sources":["../src/component-error.component.ts"],"names":[],"mappings":";AAeA,qBAmBa,uBAAuB;IAClC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,iDAAc;IACjD,SAAS,CAAC,QAAQ,CAAC,WAAW,6DAAyC;IACvE,SAAS,CAAC,QAAQ,CAAC,YAAY,6DAAyC;IAExE,IAA+B,WAAW,CAAC,KAAK,EAAE,MAAM,EAEvD;IAED,IAAa,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAE5C;IAED,IAAa,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAE7C;IAED,SAAS,CAAC,QAAQ,CAAC,UAAU,2FAAsB;IAEnD,SAAS,CAAC,QAAQ,CAAC,OAAO,yCAUxB;yCA7BS,uBAAuB;2CAAvB,uBAAuB;CA8BnC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Fallback for a node whose registered component threw while rendering. Port
|
|
3
|
+
* of adapter-svelte/src/ComponentError.svelte — sibling of `MissingComponentComponent`
|
|
4
|
+
* with the same debug-gated behavior (visible box in debug mode, silent
|
|
5
|
+
* otherwise), visually distinct so "not registered" reads differently from
|
|
6
|
+
* "registered but threw". The diagnostic + console.warn for this failure
|
|
7
|
+
* mode are recorded once, at the catch site in `node-render-engine.ts` — not
|
|
8
|
+
* here — so they still fire even when a customer overrides `renderError`
|
|
9
|
+
* with their own fallback.
|
|
10
|
+
*/
|
|
11
|
+
import { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core';
|
|
12
|
+
import { injectExperience } from './context.js';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
export class ComponentErrorComponent {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.componentIdValue = signal('', ...(ngDevMode ? [{ debugName: "componentIdValue" }] : []));
|
|
17
|
+
this.nodeIdValue = signal(undefined, ...(ngDevMode ? [{ debugName: "nodeIdValue" }] : []));
|
|
18
|
+
this.messageValue = signal(undefined, ...(ngDevMode ? [{ debugName: "messageValue" }] : []));
|
|
19
|
+
this.experience = injectExperience();
|
|
20
|
+
this.details = computed(() => JSON.stringify({
|
|
21
|
+
componentId: this.componentIdValue(),
|
|
22
|
+
nodeId: this.nodeIdValue() ?? null,
|
|
23
|
+
message: this.messageValue() ?? null,
|
|
24
|
+
}, null, 2), ...(ngDevMode ? [{ debugName: "details" }] : []));
|
|
25
|
+
}
|
|
26
|
+
set componentId(value) {
|
|
27
|
+
this.componentIdValue.set(value);
|
|
28
|
+
}
|
|
29
|
+
set nodeId(value) {
|
|
30
|
+
this.nodeIdValue.set(value);
|
|
31
|
+
}
|
|
32
|
+
set message(value) {
|
|
33
|
+
this.messageValue.set(value);
|
|
34
|
+
}
|
|
35
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: ComponentErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
36
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.28", type: ComponentErrorComponent, isStandalone: true, selector: "cf-component-error", inputs: { componentId: "componentId", nodeId: "nodeId", message: "message" }, ngImport: i0, template: `
|
|
37
|
+
@if (experience().debug) {
|
|
38
|
+
<div
|
|
39
|
+
[attr.data-experiences-render-error]="componentIdValue()"
|
|
40
|
+
style="border: 2px solid #b91c1c; padding: 1rem; color: #b91c1c; background: #fff; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8125rem;"
|
|
41
|
+
>
|
|
42
|
+
<strong>Component ‘{{ componentIdValue() }}’ threw while rendering</strong>
|
|
43
|
+
<p style="margin: 0.5rem 0;">
|
|
44
|
+
This component is registered but threw during render. Rendering this fallback instead of
|
|
45
|
+
crashing the surrounding tree.
|
|
46
|
+
</p>
|
|
47
|
+
<pre style="margin: 0; white-space: pre-wrap;">{{ details() }}</pre>
|
|
48
|
+
</div>
|
|
49
|
+
}
|
|
50
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
51
|
+
}
|
|
52
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: ComponentErrorComponent, decorators: [{
|
|
53
|
+
type: Component,
|
|
54
|
+
args: [{
|
|
55
|
+
selector: 'cf-component-error',
|
|
56
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
57
|
+
template: `
|
|
58
|
+
@if (experience().debug) {
|
|
59
|
+
<div
|
|
60
|
+
[attr.data-experiences-render-error]="componentIdValue()"
|
|
61
|
+
style="border: 2px solid #b91c1c; padding: 1rem; color: #b91c1c; background: #fff; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8125rem;"
|
|
62
|
+
>
|
|
63
|
+
<strong>Component ‘{{ componentIdValue() }}’ threw while rendering</strong>
|
|
64
|
+
<p style="margin: 0.5rem 0;">
|
|
65
|
+
This component is registered but threw during render. Rendering this fallback instead of
|
|
66
|
+
crashing the surrounding tree.
|
|
67
|
+
</p>
|
|
68
|
+
<pre style="margin: 0; white-space: pre-wrap;">{{ details() }}</pre>
|
|
69
|
+
</div>
|
|
70
|
+
}
|
|
71
|
+
`,
|
|
72
|
+
}]
|
|
73
|
+
}], propDecorators: { componentId: [{
|
|
74
|
+
type: Input,
|
|
75
|
+
args: [{ required: true }]
|
|
76
|
+
}], nodeId: [{
|
|
77
|
+
type: Input
|
|
78
|
+
}], message: [{
|
|
79
|
+
type: Input
|
|
80
|
+
}] } });
|
|
81
|
+
//# sourceMappingURL=component-error.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-error.component.js","sourceRoot":"","sources":["../src/component-error.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;;AAqBhD,MAAM,OAAO,uBAAuB;IAnBpC;QAoBqB,qBAAgB,GAAG,MAAM,CAAC,EAAE,4DAAC,CAAC;QAC9B,gBAAW,GAAG,MAAM,CAAqB,SAAS,uDAAC,CAAC;QACpD,iBAAY,GAAG,MAAM,CAAqB,SAAS,wDAAC,CAAC;QAcrD,eAAU,GAAG,gBAAgB,EAAE,CAAC;QAEhC,YAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CACzC,IAAI,CAAC,SAAS,CACZ;YACE,WAAW,EAAE,IAAI,CAAC,gBAAgB,EAAE;YACpC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI;YAClC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI;SACrC,EACD,IAAI,EACJ,CAAC,CACF,mDACF,CAAC;KACH;IAzBC,IAA+B,WAAW,CAAC,KAAa;QACtD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,IAAa,MAAM,CAAC,KAAyB;QAC3C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,IAAa,OAAO,CAAC,KAAyB;QAC5C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;+GAfU,uBAAuB;mGAAvB,uBAAuB,4JAhBxB;;;;;;;;;;;;;;GAcT;;4FAEU,uBAAuB;kBAnBnC,SAAS;mBAAC;oBACT,QAAQ,EAAE,oBAAoB;oBAC9B,eAAe,EAAE,uBAAuB,CAAC,MAAM;oBAC/C,QAAQ,EAAE;;;;;;;;;;;;;;GAcT;iBACF;;sBAME,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;;sBAIxB,KAAK;;sBAIL,KAAK"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Signal } from '@angular/core';
|
|
2
|
+
import type { ContentfulComponent, ContentfulExperienceTemplate, RenderContext } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Render-time experience context: viewports, active viewport, metadata, debug.
|
|
5
|
+
* Throws outside a renderer subtree — reading experience context where there is
|
|
6
|
+
* no experience is a programming error, not a state to branch on.
|
|
7
|
+
*/
|
|
8
|
+
export declare function injectExperience(): Signal<RenderContext>;
|
|
9
|
+
/**
|
|
10
|
+
* Raw Contentful payload for the nearest enclosing component node. Returns a
|
|
11
|
+
* signal of `undefined` outside a rendered component node.
|
|
12
|
+
*/
|
|
13
|
+
export declare function injectContentfulComponent(): Signal<ContentfulComponent | undefined>;
|
|
14
|
+
/**
|
|
15
|
+
* Raw Contentful payload for the nearest enclosing experience template node.
|
|
16
|
+
* Resolves through the element-injector walk-up, so a component nested inside a
|
|
17
|
+
* template still reaches the template's payload. Returns a signal of `undefined`
|
|
18
|
+
* outside a rendered experience template.
|
|
19
|
+
*/
|
|
20
|
+
export declare function injectContentfulExperienceTemplate(): Signal<ContentfulExperienceTemplate | undefined>;
|
|
21
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,MAAM,EAAkB,MAAM,eAAe,CAAC;AAI5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAUnG;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,aAAa,CAAC,CAQxD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAGnF;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,IAAI,MAAM,CAC1D,4BAA4B,GAAG,SAAS,CACzC,CAGA"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Accessors that expose runtime context and the raw Contentful payload to
|
|
3
|
+
* descendants of a rendered Experience. Customer components receive only their
|
|
4
|
+
* declared inputs from the renderer; anything that needs the Experience runtime
|
|
5
|
+
* context or the underlying payload injects it here.
|
|
6
|
+
*
|
|
7
|
+
* Reactivity: every accessor returns a `Signal`, so reads from a template or a
|
|
8
|
+
* `computed()` stay live across viewport changes. Call the signal at the point
|
|
9
|
+
* of use — capturing `injectExperience()()` once loses reactivity, the same rule
|
|
10
|
+
* as any other signal read.
|
|
11
|
+
*
|
|
12
|
+
* Like every `inject()`-based API these must be called from an injection context
|
|
13
|
+
* — a field initializer or the constructor — not from a lifecycle hook or an
|
|
14
|
+
* event handler.
|
|
15
|
+
*/
|
|
16
|
+
import { inject, signal } from '@angular/core';
|
|
17
|
+
import { ExperienceScope } from './experience-scope.js';
|
|
18
|
+
import { ComponentScope, ExperienceTemplateScope } from './node-scopes.js';
|
|
19
|
+
// Module-scope constants rather than a fresh signal per call: the value can
|
|
20
|
+
// never change, so readers should never be invalidated. Real signals, not
|
|
21
|
+
// stub functions — consumers may pass these through APIs that call `isSignal()`.
|
|
22
|
+
const EMPTY_COMPONENT = signal(undefined).asReadonly();
|
|
23
|
+
const EMPTY_EXPERIENCE_TEMPLATE = signal(undefined).asReadonly();
|
|
24
|
+
/**
|
|
25
|
+
* Render-time experience context: viewports, active viewport, metadata, debug.
|
|
26
|
+
* Throws outside a renderer subtree — reading experience context where there is
|
|
27
|
+
* no experience is a programming error, not a state to branch on.
|
|
28
|
+
*/
|
|
29
|
+
export function injectExperience() {
|
|
30
|
+
const scope = inject(ExperienceScope, { optional: true });
|
|
31
|
+
if (!scope) {
|
|
32
|
+
throw new Error('injectExperience() must be called inside a <cf-server-experience> or <cf-experience> subtree.');
|
|
33
|
+
}
|
|
34
|
+
return scope.experience;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Raw Contentful payload for the nearest enclosing component node. Returns a
|
|
38
|
+
* signal of `undefined` outside a rendered component node.
|
|
39
|
+
*/
|
|
40
|
+
export function injectContentfulComponent() {
|
|
41
|
+
const scope = inject(ComponentScope, { optional: true });
|
|
42
|
+
return scope ? scope.node : EMPTY_COMPONENT;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Raw Contentful payload for the nearest enclosing experience template node.
|
|
46
|
+
* Resolves through the element-injector walk-up, so a component nested inside a
|
|
47
|
+
* template still reaches the template's payload. Returns a signal of `undefined`
|
|
48
|
+
* outside a rendered experience template.
|
|
49
|
+
*/
|
|
50
|
+
export function injectContentfulExperienceTemplate() {
|
|
51
|
+
const scope = inject(ExperienceTemplateScope, { optional: true });
|
|
52
|
+
return scope ? scope.template : EMPTY_EXPERIENCE_TEMPLATE;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAe,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,4EAA4E;AAC5E,0EAA0E;AAC1E,iFAAiF;AACjF,MAAM,eAAe,GAAG,MAAM,CAAkC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;AACxF,MAAM,yBAAyB,GAAG,MAAM,CACtC,SAAS,CACV,CAAC,UAAU,EAAE,CAAC;AAEf;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,+FAA+F,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,UAAU,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kCAAkC;IAGhD,MAAM,KAAK,GAAG,MAAM,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { PortableRenderPlan } from '@contentful/experiences-sdk-core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class DebugExperienceComponent {
|
|
4
|
+
protected readonly experienceValue: import("@angular/core").WritableSignal<PortableRenderPlan | null>;
|
|
5
|
+
protected readonly defaultOpenValue: import("@angular/core").WritableSignal<boolean>;
|
|
6
|
+
protected readonly errorsValue: import("@angular/core").WritableSignal<Error[]>;
|
|
7
|
+
set experience(value: PortableRenderPlan);
|
|
8
|
+
set defaultOpen(value: boolean);
|
|
9
|
+
/** Resolve-time + render-time diagnostics, merged by the caller. */
|
|
10
|
+
set errors(value: Error[] | undefined);
|
|
11
|
+
protected readonly open: import("@angular/core").Signal<boolean>;
|
|
12
|
+
protected readonly summary: import("@angular/core").Signal<string>;
|
|
13
|
+
protected readonly json: import("@angular/core").Signal<string>;
|
|
14
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DebugExperienceComponent, never>;
|
|
15
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DebugExperienceComponent, "cf-debug-experience", never, { "experience": { "alias": "experience"; "required": true; }; "defaultOpen": { "alias": "defaultOpen"; "required": false; }; "errors": { "alias": "errors"; "required": false; }; }, {}, never, never, true, never>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=debug-experience.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-experience.component.d.ts","sourceRoot":"","sources":["../src/debug-experience.component.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;;AAoC3E,qBA6Ba,wBAAwB;IACnC,SAAS,CAAC,QAAQ,CAAC,eAAe,oEAA2C;IAC7E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,kDAAiB;IACpD,SAAS,CAAC,QAAQ,CAAC,WAAW,kDAAuB;IAErD,IAA+B,UAAU,CAAC,KAAK,EAAE,kBAAkB,EAElE;IAED,IAAa,WAAW,CAAC,KAAK,EAAE,OAAO,EAEtC;IAED,oEAAoE;IACpE,IAAa,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,SAAS,EAE7C;IAKD,SAAS,CAAC,QAAQ,CAAC,IAAI,0CAErB;IAEF,SAAS,CAAC,QAAQ,CAAC,OAAO,yCAWvB;IAEH,SAAS,CAAC,QAAQ,CAAC,IAAI,yCAAyD;yCAtCrE,wBAAwB;2CAAxB,wBAAwB;CAuCpC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Collapsible dump of the resolved render plan. Port of
|
|
3
|
+
* adapter-svelte/src/DebugExperience.svelte.
|
|
4
|
+
*
|
|
5
|
+
* Rendered by either experience renderer when `debug` is on. Answers "what did
|
|
6
|
+
* the resolver actually produce?" without a devtools round-trip — which matters
|
|
7
|
+
* most under SSR, where the plan never reaches the browser as data.
|
|
8
|
+
*/
|
|
9
|
+
import { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
/**
|
|
12
|
+
* `JSON.stringify` with the sharp edges filed off: render plans can carry
|
|
13
|
+
* circular references (a resolved entry linking back to its parent) and function
|
|
14
|
+
* values (a `resolveData` result), either of which would throw or silently vanish.
|
|
15
|
+
* A debug panel that crashes the page is worse than no debug panel.
|
|
16
|
+
*/
|
|
17
|
+
function safeStringify(value) {
|
|
18
|
+
const seen = new WeakSet();
|
|
19
|
+
try {
|
|
20
|
+
return JSON.stringify(value, (_key, val) => {
|
|
21
|
+
if (typeof val === 'function') {
|
|
22
|
+
return `[Function ${val.name || 'anonymous'}]`;
|
|
23
|
+
}
|
|
24
|
+
if (val === undefined)
|
|
25
|
+
return '[undefined]';
|
|
26
|
+
if (typeof val === 'object' && val !== null) {
|
|
27
|
+
if (seen.has(val))
|
|
28
|
+
return '[Circular]';
|
|
29
|
+
seen.add(val);
|
|
30
|
+
}
|
|
31
|
+
return val;
|
|
32
|
+
}, 2);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
// `err` isn't guaranteed to be an Error — a getter deep in customer data
|
|
36
|
+
// (a resolveData result, resolved design values) can `throw null` or
|
|
37
|
+
// `throw 'reason'` during JSON.stringify's replacer walk, and this
|
|
38
|
+
// fallback's whole job is to never throw itself.
|
|
39
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
40
|
+
return `[DebugExperience: could not serialize plan — ${reason}]`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class DebugExperienceComponent {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.experienceValue = signal(null, ...(ngDevMode ? [{ debugName: "experienceValue" }] : []));
|
|
46
|
+
this.defaultOpenValue = signal(false, ...(ngDevMode ? [{ debugName: "defaultOpenValue" }] : []));
|
|
47
|
+
this.errorsValue = signal([], ...(ngDevMode ? [{ debugName: "errorsValue" }] : []));
|
|
48
|
+
// Auto-expand whenever there's something to see, even if the caller didn't
|
|
49
|
+
// explicitly ask — a beta customer shouldn't have to know to click into a
|
|
50
|
+
// collapsed panel to discover that something went wrong.
|
|
51
|
+
this.open = computed(() => this.defaultOpenValue() || this.errorsValue().length > 0, ...(ngDevMode ? [{ debugName: "open" }] : []));
|
|
52
|
+
this.summary = computed(() => {
|
|
53
|
+
const experience = this.experienceValue();
|
|
54
|
+
if (!experience)
|
|
55
|
+
return 'Experience debug';
|
|
56
|
+
const nodeCount = experience.nodes.length;
|
|
57
|
+
const templateIds = experience.nodes
|
|
58
|
+
.filter((node) => node.registration.kind === 'experienceTemplate')
|
|
59
|
+
.map((node) => node.registration.id);
|
|
60
|
+
const templatePart = templateIds.length
|
|
61
|
+
? `, experience template${templateIds.length === 1 ? '' : 's'}: ${templateIds.join(', ')}`
|
|
62
|
+
: '';
|
|
63
|
+
return `Experience debug — ${nodeCount} top-level node${nodeCount === 1 ? '' : 's'}${templatePart}`;
|
|
64
|
+
}, ...(ngDevMode ? [{ debugName: "summary" }] : []));
|
|
65
|
+
this.json = computed(() => safeStringify(this.experienceValue()), ...(ngDevMode ? [{ debugName: "json" }] : []));
|
|
66
|
+
}
|
|
67
|
+
set experience(value) {
|
|
68
|
+
this.experienceValue.set(value);
|
|
69
|
+
}
|
|
70
|
+
set defaultOpen(value) {
|
|
71
|
+
this.defaultOpenValue.set(value);
|
|
72
|
+
}
|
|
73
|
+
/** Resolve-time + render-time diagnostics, merged by the caller. */
|
|
74
|
+
set errors(value) {
|
|
75
|
+
this.errorsValue.set(value ?? []);
|
|
76
|
+
}
|
|
77
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: DebugExperienceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
78
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.28", type: DebugExperienceComponent, isStandalone: true, selector: "cf-debug-experience", inputs: { experience: "experience", defaultOpen: "defaultOpen", errors: "errors" }, ngImport: i0, template: `
|
|
79
|
+
<details
|
|
80
|
+
[open]="open()"
|
|
81
|
+
data-experiences-debug
|
|
82
|
+
style="margin: 1rem 0; border: 1px solid #6b7280; border-radius: 6px; background: #0b1021; color: #e2e8f0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.75rem; overflow: hidden;"
|
|
83
|
+
>
|
|
84
|
+
<summary
|
|
85
|
+
style="cursor: pointer; padding: 0.5rem 0.75rem; background: #111827; user-select: none;"
|
|
86
|
+
>
|
|
87
|
+
{{ summary() }}
|
|
88
|
+
</summary>
|
|
89
|
+
<!-- Deliberately unstyled for now — this just needs to make the data
|
|
90
|
+
visible, not console-only. Visual treatment can grow later. -->
|
|
91
|
+
@if (errorsValue().length > 0) {
|
|
92
|
+
<ul data-experiences-debug-errors>
|
|
93
|
+
@for (error of errorsValue(); track $index) {
|
|
94
|
+
<li>{{ error.message }}</li>
|
|
95
|
+
}
|
|
96
|
+
</ul>
|
|
97
|
+
}
|
|
98
|
+
<pre
|
|
99
|
+
style="margin: 0; padding: 0.75rem; overflow: auto; max-height: 32rem; white-space: pre-wrap; word-break: break-word;"
|
|
100
|
+
>{{ json() }}</pre>
|
|
101
|
+
</details>
|
|
102
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
103
|
+
}
|
|
104
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: DebugExperienceComponent, decorators: [{
|
|
105
|
+
type: Component,
|
|
106
|
+
args: [{
|
|
107
|
+
selector: 'cf-debug-experience',
|
|
108
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
109
|
+
template: `
|
|
110
|
+
<details
|
|
111
|
+
[open]="open()"
|
|
112
|
+
data-experiences-debug
|
|
113
|
+
style="margin: 1rem 0; border: 1px solid #6b7280; border-radius: 6px; background: #0b1021; color: #e2e8f0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.75rem; overflow: hidden;"
|
|
114
|
+
>
|
|
115
|
+
<summary
|
|
116
|
+
style="cursor: pointer; padding: 0.5rem 0.75rem; background: #111827; user-select: none;"
|
|
117
|
+
>
|
|
118
|
+
{{ summary() }}
|
|
119
|
+
</summary>
|
|
120
|
+
<!-- Deliberately unstyled for now — this just needs to make the data
|
|
121
|
+
visible, not console-only. Visual treatment can grow later. -->
|
|
122
|
+
@if (errorsValue().length > 0) {
|
|
123
|
+
<ul data-experiences-debug-errors>
|
|
124
|
+
@for (error of errorsValue(); track $index) {
|
|
125
|
+
<li>{{ error.message }}</li>
|
|
126
|
+
}
|
|
127
|
+
</ul>
|
|
128
|
+
}
|
|
129
|
+
<pre
|
|
130
|
+
style="margin: 0; padding: 0.75rem; overflow: auto; max-height: 32rem; white-space: pre-wrap; word-break: break-word;"
|
|
131
|
+
>{{ json() }}</pre>
|
|
132
|
+
</details>
|
|
133
|
+
`,
|
|
134
|
+
}]
|
|
135
|
+
}], propDecorators: { experience: [{
|
|
136
|
+
type: Input,
|
|
137
|
+
args: [{ required: true }]
|
|
138
|
+
}], defaultOpen: [{
|
|
139
|
+
type: Input
|
|
140
|
+
}], errors: [{
|
|
141
|
+
type: Input
|
|
142
|
+
}] } });
|
|
143
|
+
//# sourceMappingURL=debug-experience.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-experience.component.js","sourceRoot":"","sources":["../src/debug-experience.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ToCssOptions {
|
|
2
|
+
/** Keys to skip, matched against the original record key. */
|
|
3
|
+
exclude?: string[];
|
|
4
|
+
/** When set, only these keys pass through (still whitelist-filtered). */
|
|
5
|
+
include?: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Convert a design record into a plain style object, keeping only keys that
|
|
9
|
+
* normalize to a known CSS property. Non-CSS keys (`variant`, `as`, …) and
|
|
10
|
+
* non-scalar values are dropped; read those off the `injectDesignValues()`
|
|
11
|
+
* record directly.
|
|
12
|
+
*
|
|
13
|
+
* toCss({ fontSize: '20px', variant: 'h1' }) //=> { fontSize: '20px' }
|
|
14
|
+
*
|
|
15
|
+
* The camelCase keys it emits are what `[ngStyle]` accepts:
|
|
16
|
+
*
|
|
17
|
+
* readonly design = injectDesignValues();
|
|
18
|
+
* protected readonly style = computed(() => toCss(this.design()));
|
|
19
|
+
* // template: <div [ngStyle]="style()">
|
|
20
|
+
*/
|
|
21
|
+
export declare function toCss(design: object, { include, exclude }?: ToCssOptions): Record<string, string | number>;
|
|
22
|
+
//# sourceMappingURL=design-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-utils.d.ts","sourceRoot":"","sources":["../src/design-utils.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,MAAM,EACd,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,YAAiB,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAYjC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Port of adapter-svelte/src/design-utils.ts. Deliberately not hoisted into
|
|
3
|
+
* `@contentful/experiences-design`: the React variant returns `CSSProperties`
|
|
4
|
+
* and keeps any non-null value, while this one is scalar-only and returns a
|
|
5
|
+
* plain record. The plain record is what Angular's `[ngStyle]` wants.
|
|
6
|
+
*/
|
|
7
|
+
import { isCssProperty, toCssKey } from '@contentful/experiences-design';
|
|
8
|
+
/**
|
|
9
|
+
* Convert a design record into a plain style object, keeping only keys that
|
|
10
|
+
* normalize to a known CSS property. Non-CSS keys (`variant`, `as`, …) and
|
|
11
|
+
* non-scalar values are dropped; read those off the `injectDesignValues()`
|
|
12
|
+
* record directly.
|
|
13
|
+
*
|
|
14
|
+
* toCss({ fontSize: '20px', variant: 'h1' }) //=> { fontSize: '20px' }
|
|
15
|
+
*
|
|
16
|
+
* The camelCase keys it emits are what `[ngStyle]` accepts:
|
|
17
|
+
*
|
|
18
|
+
* readonly design = injectDesignValues();
|
|
19
|
+
* protected readonly style = computed(() => toCss(this.design()));
|
|
20
|
+
* // template: <div [ngStyle]="style()">
|
|
21
|
+
*/
|
|
22
|
+
export function toCss(design, { include, exclude } = {}) {
|
|
23
|
+
const out = {};
|
|
24
|
+
for (const [key, value] of Object.entries(design)) {
|
|
25
|
+
if (include && !include.includes(key))
|
|
26
|
+
continue;
|
|
27
|
+
if (exclude?.includes(key))
|
|
28
|
+
continue;
|
|
29
|
+
if (value === undefined || value === null)
|
|
30
|
+
continue;
|
|
31
|
+
if (typeof value !== 'string' && typeof value !== 'number')
|
|
32
|
+
continue;
|
|
33
|
+
const cssKey = toCssKey(key);
|
|
34
|
+
if (!isCssProperty(cssKey))
|
|
35
|
+
continue;
|
|
36
|
+
out[cssKey] = value;
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=design-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-utils.js","sourceRoot":"","sources":["../src/design-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AASzE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,KAAK,CACnB,MAAc,EACd,EAAE,OAAO,EAAE,OAAO,KAAmB,EAAE;IAEvC,MAAM,GAAG,GAAoC,EAAE,CAAC;IAChD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QAChD,IAAI,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACrC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAS;QACrE,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;YAAE,SAAS;QACrC,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ExperienceContext, ViewportDef } from '@contentful/experiences-sdk-core';
|
|
2
|
+
import type { Config } from './types.js';
|
|
3
|
+
export declare const DEFAULT_CONTEXT: ExperienceContext;
|
|
4
|
+
/**
|
|
5
|
+
* Stands in when there is no experience to read viewports from, so descendants
|
|
6
|
+
* always see a viewport rather than having to branch on `undefined`. `query: '*'`
|
|
7
|
+
* matches everything, mirroring what real single-viewport payloads ship today.
|
|
8
|
+
*/
|
|
9
|
+
export declare const FALLBACK_VIEWPORT: ViewportDef;
|
|
10
|
+
/**
|
|
11
|
+
* Read only in the window between a renderer's construction and Angular binding
|
|
12
|
+
* its `config` input — the scope stores a getter, and nothing below the renderer
|
|
13
|
+
* exists to call it yet. It exists so the getter's return type needs no `null`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const EMPTY_CONFIG: Config;
|
|
16
|
+
//# sourceMappingURL=experience-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"experience-defaults.d.ts","sourceRoot":"","sources":["../src/experience-defaults.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAEvF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,iBAAiE,CAAC;AAEhG;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAK/B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,MAA2B,CAAC"}
|