@contentful/experiences-svelte 0.3.1
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 +52 -0
- package/README.md +107 -0
- package/dist/ClientExperienceRenderer.svelte +81 -0
- package/dist/ClientExperienceRenderer.svelte.d.ts +4 -0
- package/dist/ClientExperienceRenderer.svelte.d.ts.map +1 -0
- package/dist/MissingComponent.svelte +35 -0
- package/dist/MissingComponent.svelte.d.ts +5 -0
- package/dist/MissingComponent.svelte.d.ts.map +1 -0
- package/dist/NodeRenderer.svelte +83 -0
- package/dist/NodeRenderer.svelte.d.ts +15 -0
- package/dist/NodeRenderer.svelte.d.ts.map +1 -0
- package/dist/NodesRenderer.svelte +51 -0
- package/dist/NodesRenderer.svelte.d.ts +14 -0
- package/dist/NodesRenderer.svelte.d.ts.map +1 -0
- package/dist/ServerExperienceRenderer.svelte +70 -0
- package/dist/ServerExperienceRenderer.svelte.d.ts +5 -0
- package/dist/ServerExperienceRenderer.svelte.d.ts.map +1 -0
- package/dist/WrapWithTemplate.svelte +87 -0
- package/dist/WrapWithTemplate.svelte.d.ts +13 -0
- package/dist/WrapWithTemplate.svelte.d.ts.map +1 -0
- package/dist/component-props.d.ts +18 -0
- package/dist/component-props.d.ts.map +1 -0
- package/dist/component-props.js +13 -0
- package/dist/context.d.ts +20 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +61 -0
- package/dist/design-utils.d.ts +16 -0
- package/dist/design-utils.d.ts.map +1 -0
- package/dist/design-utils.js +27 -0
- package/dist/get-design-values.d.ts +14 -0
- package/dist/get-design-values.d.ts.map +1 -0
- package/dist/get-design-values.js +16 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/server-renderer.test.d.ts +2 -0
- package/dist/server-renderer.test.d.ts.map +1 -0
- package/dist/server-renderer.test.js +566 -0
- package/dist/test-fixtures/ButtonFixture.svelte +8 -0
- package/dist/test-fixtures/ButtonFixture.svelte.d.ts +7 -0
- package/dist/test-fixtures/ButtonFixture.svelte.d.ts.map +1 -0
- package/dist/test-fixtures/CapturingComponent.svelte +18 -0
- package/dist/test-fixtures/CapturingComponent.svelte.d.ts +4 -0
- package/dist/test-fixtures/CapturingComponent.svelte.d.ts.map +1 -0
- package/dist/test-fixtures/ContainerFixture.svelte +12 -0
- package/dist/test-fixtures/ContainerFixture.svelte.d.ts +8 -0
- package/dist/test-fixtures/ContainerFixture.svelte.d.ts.map +1 -0
- package/dist/test-fixtures/HeadingFixture.svelte +8 -0
- package/dist/test-fixtures/HeadingFixture.svelte.d.ts +7 -0
- package/dist/test-fixtures/HeadingFixture.svelte.d.ts.map +1 -0
- package/dist/test-fixtures/ItemFixture.svelte +11 -0
- package/dist/test-fixtures/ItemFixture.svelte.d.ts +8 -0
- package/dist/test-fixtures/ItemFixture.svelte.d.ts.map +1 -0
- package/dist/test-fixtures/PrecedenceFixture.svelte +5 -0
- package/dist/test-fixtures/PrecedenceFixture.svelte.d.ts +7 -0
- package/dist/test-fixtures/PrecedenceFixture.svelte.d.ts.map +1 -0
- package/dist/test-fixtures/TemplateFixture.svelte +18 -0
- package/dist/test-fixtures/TemplateFixture.svelte.d.ts +9 -0
- package/dist/test-fixtures/TemplateFixture.svelte.d.ts.map +1 -0
- package/dist/test-fixtures/capture-sink.d.ts +10 -0
- package/dist/test-fixtures/capture-sink.d.ts.map +1 -0
- package/dist/test-fixtures/capture-sink.js +5 -0
- package/dist/types.d.ts +99 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +26 -0
- package/dist/use-active-viewport.svelte.d.ts +14 -0
- package/dist/use-active-viewport.svelte.d.ts.map +1 -0
- package/dist/use-active-viewport.svelte.js +83 -0
- package/package.json +55 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
variant?: string;
|
|
3
|
+
priority?: string;
|
|
4
|
+
};
|
|
5
|
+
declare const ItemFixture: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
type ItemFixture = ReturnType<typeof ItemFixture>;
|
|
7
|
+
export default ItemFixture;
|
|
8
|
+
//# sourceMappingURL=ItemFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ItemFixture.svelte.d.ts","sourceRoot":"","sources":["../../src/test-fixtures/ItemFixture.svelte.ts"],"names":[],"mappings":"AAGC,KAAK,gBAAgB,GAAI;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAYJ,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
value?: string;
|
|
3
|
+
};
|
|
4
|
+
declare const PrecedenceFixture: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
5
|
+
type PrecedenceFixture = ReturnType<typeof PrecedenceFixture>;
|
|
6
|
+
export default PrecedenceFixture;
|
|
7
|
+
//# sourceMappingURL=PrecedenceFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrecedenceFixture.svelte.d.ts","sourceRoot":"","sources":["../../src/test-fixtures/PrecedenceFixture.svelte.ts"],"names":[],"mappings":"AAGC,KAAK,gBAAgB,GAAI;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAS7C,QAAA,MAAM,iBAAiB,sDAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
import { getDesignValues } from '../get-design-values.js';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
title,
|
|
8
|
+
children,
|
|
9
|
+
}: {
|
|
10
|
+
title?: string;
|
|
11
|
+
children: Snippet;
|
|
12
|
+
} = $props();
|
|
13
|
+
const design = $derived(getDesignValues());
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<main data-template="page" data-title={title} data-bg={design.cfBackground as string}>
|
|
17
|
+
{@render children()}
|
|
18
|
+
</main>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
title?: string;
|
|
4
|
+
children: Snippet;
|
|
5
|
+
};
|
|
6
|
+
declare const TemplateFixture: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type TemplateFixture = ReturnType<typeof TemplateFixture>;
|
|
8
|
+
export default TemplateFixture;
|
|
9
|
+
//# sourceMappingURL=TemplateFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateFixture.svelte.d.ts","sourceRoot":"","sources":["../../src/test-fixtures/TemplateFixture.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIrC,KAAK,gBAAgB,GAAI;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAmBJ,QAAA,MAAM,eAAe,sDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ContentfulComponent } from '../types.js';
|
|
2
|
+
import type { RenderContext } from '../types.js';
|
|
3
|
+
export interface Capture {
|
|
4
|
+
props: Record<string, unknown>;
|
|
5
|
+
experience: RenderContext;
|
|
6
|
+
contentful: ContentfulComponent | undefined;
|
|
7
|
+
designValues?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export declare const captureSink: Capture[];
|
|
10
|
+
//# sourceMappingURL=capture-sink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-sink.d.ts","sourceRoot":"","sources":["../../src/test-fixtures/capture-sink.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,UAAU,EAAE,aAAa,CAAC;IAC1B,UAAU,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,eAAO,MAAM,WAAW,EAAE,OAAO,EAAO,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { Component } from 'svelte';
|
|
2
|
+
import type { DesignPropValue, ExperienceContext, ResolveContext, ResolveToken, ViewportDef } from '@contentful/experiences-core';
|
|
3
|
+
export type { ResolveContext, ResolveToken };
|
|
4
|
+
/**
|
|
5
|
+
* The full Contentful-side payload for a single component instance, exposed
|
|
6
|
+
* via `getContentfulComponent()` to any descendant of a rendered Experience
|
|
7
|
+
* node. Useful for custom design-property resolution outside the SDK's
|
|
8
|
+
* cascade, branching by `componentTypeId` in a generic wrapper, keying
|
|
9
|
+
* analytics on `nodeId`, rendering a raw-payload panel in preview, or
|
|
10
|
+
* rendering non-`children` slots through the exported `<NodesRenderer />`.
|
|
11
|
+
*
|
|
12
|
+
* Design properties stay in their **raw envelope form** here (the same shape
|
|
13
|
+
* `ctx.design` carries inside `resolveData`). The viewport-cascaded, token-
|
|
14
|
+
* resolved values are what `getDesignValues()` returns.
|
|
15
|
+
*/
|
|
16
|
+
export interface ContentfulComponent {
|
|
17
|
+
componentTypeId: string;
|
|
18
|
+
nodeId?: string;
|
|
19
|
+
content: Record<string, unknown>;
|
|
20
|
+
design: Record<string, DesignPropValue>;
|
|
21
|
+
resolved?: Record<string, unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Raw per-slot node arrays from the payload. The default slot named
|
|
24
|
+
* `children` is rendered automatically and passed as a Snippet prop;
|
|
25
|
+
* additional slots (if any) are reachable here and can be rendered with
|
|
26
|
+
* `<NodesRenderer nodes={...} />`.
|
|
27
|
+
*/
|
|
28
|
+
slots: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Same shape as `ContentfulComponent`, but for the page-level template.
|
|
32
|
+
* Exposed via `getContentfulTemplate()` inside a template's component tree.
|
|
33
|
+
*/
|
|
34
|
+
export interface ContentfulTemplate {
|
|
35
|
+
templateId: string;
|
|
36
|
+
content: Record<string, unknown>;
|
|
37
|
+
design: Record<string, DesignPropValue>;
|
|
38
|
+
resolved?: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Render-time experience context. Extends the core `ExperienceContext` with
|
|
42
|
+
* the active viewport — a render-time value that resolvers cannot see.
|
|
43
|
+
* Exposed via `getExperience()`.
|
|
44
|
+
*/
|
|
45
|
+
export interface RenderContext extends ExperienceContext {
|
|
46
|
+
activeViewport: ViewportDef;
|
|
47
|
+
activeViewportIndex: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Customer-supplied configuration for a single component type. The `component`
|
|
51
|
+
* receives the merged prop bag (content + resolveData + `children` Snippet).
|
|
52
|
+
* Design values are not injected — a component reads them via
|
|
53
|
+
* `getDesignValues()`. Runtime context and raw payload come from
|
|
54
|
+
* `getExperience()` / `getContentfulComponent()`.
|
|
55
|
+
*/
|
|
56
|
+
export interface ComponentConfig<Props extends object = Record<string, unknown>> {
|
|
57
|
+
defaults?: Partial<Props>;
|
|
58
|
+
resolveData?: (ctx: ResolveContext) => Partial<Props> | Promise<Partial<Props>>;
|
|
59
|
+
component: Component<any>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Registry value. Register a bare Svelte component for the common case, or
|
|
63
|
+
* the full `ComponentConfig` shape when you need defaults or a `resolveData`
|
|
64
|
+
* hook.
|
|
65
|
+
*
|
|
66
|
+
* button: Button, // bare
|
|
67
|
+
* header: { component: Header, defaults: {...} }, // with defaults
|
|
68
|
+
* card: defineComponent<CardProps>({ component: Card, resolveData: ... }),
|
|
69
|
+
*/
|
|
70
|
+
export type Registration<Props extends object = Record<string, unknown>> = Component<any> | ComponentConfig<Props>;
|
|
71
|
+
export interface TemplateConfig<Props extends object = Record<string, unknown>> {
|
|
72
|
+
defaults?: Partial<Props>;
|
|
73
|
+
resolveData?: (ctx: ResolveContext) => Partial<Props> | Promise<Partial<Props>>;
|
|
74
|
+
component: Component<any>;
|
|
75
|
+
}
|
|
76
|
+
export type TemplateRegistration<Props extends object = Record<string, unknown>> = Component<any> | TemplateConfig<Props>;
|
|
77
|
+
export declare function defineTemplate<Props extends object = Record<string, unknown>>(config: TemplateConfig<Props>): TemplateConfig<Props>;
|
|
78
|
+
export declare function defineComponent<Props extends object = Record<string, unknown>>(config: ComponentConfig<Props>): ComponentConfig<Props>;
|
|
79
|
+
export type Components = Record<string, Registration<any>>;
|
|
80
|
+
export type Templates = Record<string, TemplateRegistration<any>>;
|
|
81
|
+
export interface Config {
|
|
82
|
+
components: Components;
|
|
83
|
+
templates?: Templates;
|
|
84
|
+
/**
|
|
85
|
+
* Resolves `DesignToken` envelopes to runtime values before they reach a
|
|
86
|
+
* component. If omitted, envelopes pass through unchanged. See `ResolveToken`
|
|
87
|
+
* in `@contentful/experiences-core` for the full contract.
|
|
88
|
+
*/
|
|
89
|
+
resolveToken?: ResolveToken;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Normalize a registry entry — bare Svelte component OR config object —
|
|
93
|
+
* into the common `ComponentConfig` shape used by the renderer. Svelte 5
|
|
94
|
+
* Components are callable functions; config objects are plain objects with
|
|
95
|
+
* a `component` field, so `typeof` is enough to discriminate.
|
|
96
|
+
*/
|
|
97
|
+
export declare function normalizeComponentRegistration<P extends object>(reg: Registration<P>): ComponentConfig<P>;
|
|
98
|
+
export declare function normalizeTemplateRegistration<P extends object>(reg: TemplateRegistration<P>): TemplateConfig<P>;
|
|
99
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function defineTemplate(config) {
|
|
2
|
+
return config;
|
|
3
|
+
}
|
|
4
|
+
export function defineComponent(config) {
|
|
5
|
+
return config;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Normalize a registry entry — bare Svelte component OR config object —
|
|
9
|
+
* into the common `ComponentConfig` shape used by the renderer. Svelte 5
|
|
10
|
+
* Components are callable functions; config objects are plain objects with
|
|
11
|
+
* a `component` field, so `typeof` is enough to discriminate.
|
|
12
|
+
*/
|
|
13
|
+
export function normalizeComponentRegistration(reg) {
|
|
14
|
+
if (typeof reg === 'function') {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
return { component: reg };
|
|
17
|
+
}
|
|
18
|
+
return reg;
|
|
19
|
+
}
|
|
20
|
+
export function normalizeTemplateRegistration(reg) {
|
|
21
|
+
if (typeof reg === 'function') {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
return { component: reg };
|
|
24
|
+
}
|
|
25
|
+
return reg;
|
|
26
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ViewportDef } from '@contentful/experiences-core';
|
|
2
|
+
export interface UseActiveViewportResult {
|
|
3
|
+
readonly activeViewportIndex: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Returns a reactive object whose `activeViewportIndex` updates as the
|
|
7
|
+
* window's matched media queries change. Mounts listeners via `$effect`
|
|
8
|
+
* and tears them down automatically when the calling component unmounts.
|
|
9
|
+
*
|
|
10
|
+
* Must be called at the top level of a `.svelte` component or a function
|
|
11
|
+
* that's itself called during component setup (because of `$effect`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function useActiveViewport(viewports: ViewportDef[], initialViewportId?: string): UseActiveViewportResult;
|
|
14
|
+
//# sourceMappingURL=use-active-viewport.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-active-viewport.svelte.d.ts","sourceRoot":"","sources":["../src/use-active-viewport.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAGhE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AA4BD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,WAAW,EAAE,EACxB,iBAAiB,CAAC,EAAE,MAAM,GACzB,uBAAuB,CAiDzB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Reactive viewport-matcher rune.
|
|
3
|
+
*
|
|
4
|
+
* "Active viewport" = the last-matching media query in the ordered viewports
|
|
5
|
+
* list. With desktop-first ordering (`*`, `<992px`, `<576px`), the narrowest
|
|
6
|
+
* matching query wins. With mobile-first ordering, the widest wins. Either
|
|
7
|
+
* way: the last `findLastIndex` of `mediaQueryMatches[i] === true`.
|
|
8
|
+
*
|
|
9
|
+
* Pass `initialViewportId` (typically derived from User-Agent on the server)
|
|
10
|
+
* to seed the first render so SSR + client agree on viewport before
|
|
11
|
+
* window.matchMedia takes over.
|
|
12
|
+
*/
|
|
13
|
+
import { getViewportIndex, toCssMediaQuery } from '@contentful/experiences-design';
|
|
14
|
+
function createMediaQueryMatchers(viewports) {
|
|
15
|
+
const mediaQueryMatches = new Array(viewports.length).fill(false);
|
|
16
|
+
// The first viewport is the wildcard "*" and always matches.
|
|
17
|
+
mediaQueryMatches[0] = true;
|
|
18
|
+
const mediaQueryMatchers = [];
|
|
19
|
+
if (typeof window === 'undefined') {
|
|
20
|
+
return [mediaQueryMatchers, mediaQueryMatches];
|
|
21
|
+
}
|
|
22
|
+
for (let index = 0; index < viewports.length; index++) {
|
|
23
|
+
const viewport = viewports[index];
|
|
24
|
+
if (!viewport)
|
|
25
|
+
continue;
|
|
26
|
+
const cssQuery = toCssMediaQuery(viewport);
|
|
27
|
+
if (!cssQuery)
|
|
28
|
+
continue;
|
|
29
|
+
const matcher = window.matchMedia(cssQuery);
|
|
30
|
+
mediaQueryMatches[index] = matcher.matches;
|
|
31
|
+
mediaQueryMatchers.push({ index, signal: matcher });
|
|
32
|
+
}
|
|
33
|
+
return [mediaQueryMatchers, mediaQueryMatches];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns a reactive object whose `activeViewportIndex` updates as the
|
|
37
|
+
* window's matched media queries change. Mounts listeners via `$effect`
|
|
38
|
+
* and tears them down automatically when the calling component unmounts.
|
|
39
|
+
*
|
|
40
|
+
* Must be called at the top level of a `.svelte` component or a function
|
|
41
|
+
* that's itself called during component setup (because of `$effect`).
|
|
42
|
+
*/
|
|
43
|
+
export function useActiveViewport(viewports, initialViewportId) {
|
|
44
|
+
const initialIndex = getViewportIndex(viewports, initialViewportId);
|
|
45
|
+
const [, initialMatches] = createMediaQueryMatchers(viewports);
|
|
46
|
+
let matches = $state(initialMatches);
|
|
47
|
+
let activeViewportIndex = $state(initialIndex);
|
|
48
|
+
$effect(() => {
|
|
49
|
+
const [matchers] = createMediaQueryMatchers(viewports);
|
|
50
|
+
// Sync once on mount in case the initial seed was server-side.
|
|
51
|
+
matches = matchers.reduce((acc, { index, signal }) => {
|
|
52
|
+
acc[index] = signal.matches;
|
|
53
|
+
return acc;
|
|
54
|
+
}, [...initialMatches]);
|
|
55
|
+
const listeners = matchers.map(({ index, signal }) => {
|
|
56
|
+
const onChange = () => {
|
|
57
|
+
const next = [...matches];
|
|
58
|
+
next[index] = signal.matches;
|
|
59
|
+
matches = next;
|
|
60
|
+
};
|
|
61
|
+
signal.addEventListener('change', onChange);
|
|
62
|
+
return onChange;
|
|
63
|
+
});
|
|
64
|
+
return () => {
|
|
65
|
+
listeners.forEach((listener, i) => {
|
|
66
|
+
const matcher = matchers[i];
|
|
67
|
+
if (matcher)
|
|
68
|
+
matcher.signal.removeEventListener('change', listener);
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
$effect(() => {
|
|
73
|
+
const currentIndex = matches.findLastIndex((isMatch) => isMatch);
|
|
74
|
+
if (currentIndex !== -1 && currentIndex !== activeViewportIndex) {
|
|
75
|
+
activeViewportIndex = currentIndex;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
get activeViewportIndex() {
|
|
80
|
+
return activeViewportIndex;
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contentful/experiences-svelte",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Svelte adapter for Contentful Experiences — Server and Client renderers over a PortableRenderPlan",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"svelte": "./dist/index.js",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"svelte": "./dist/index.js",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md",
|
|
22
|
+
"CHANGELOG.md"
|
|
23
|
+
],
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/contentful/experiences.git",
|
|
30
|
+
"directory": "packages/adapter-svelte"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "svelte-package -i src -o dist && publint",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"check": "svelte-check --tsconfig ./tsconfig.json"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@contentful/experiences-client": "0.1.1",
|
|
39
|
+
"@contentful/experiences-core": "0.5.1",
|
|
40
|
+
"@contentful/experiences-design": "0.5.1"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"svelte": "^5.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@sveltejs/package": "^2.3.0",
|
|
47
|
+
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
|
48
|
+
"@testing-library/jest-dom": "^6.5.0",
|
|
49
|
+
"@testing-library/svelte": "^5.2.0",
|
|
50
|
+
"jsdom": "^25.0.1",
|
|
51
|
+
"publint": "^0.2.0",
|
|
52
|
+
"svelte": "^5.0.0",
|
|
53
|
+
"svelte-check": "^4.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|