@c15t/svelte 3.0.0-alpha.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/AGENTS.md +88 -0
- package/README.md +136 -0
- package/SKILL.md +14 -0
- package/dist/actions/focus-trap.d.ts +8 -0
- package/dist/actions/focus-trap.js +23 -0
- package/dist/actions/portal.d.ts +8 -0
- package/dist/actions/portal.js +39 -0
- package/dist/actions/scroll-lock.d.ts +8 -0
- package/dist/actions/scroll-lock.js +23 -0
- package/dist/components/action-button.svelte +119 -0
- package/dist/components/action-button.svelte.d.ts +18 -0
- package/dist/components/branding.svelte +139 -0
- package/dist/components/branding.svelte.d.ts +13 -0
- package/dist/components/consent-dev-tools.svelte +58 -0
- package/dist/components/consent-dev-tools.svelte.d.ts +4 -0
- package/dist/components/frame.svelte +95 -0
- package/dist/components/frame.svelte.d.ts +12 -0
- package/dist/components/iab-panel.svelte +542 -0
- package/dist/components/iab-panel.svelte.d.ts +16 -0
- package/dist/components/iab-prompt.svelte +304 -0
- package/dist/components/iab-prompt.svelte.d.ts +14 -0
- package/dist/components/iab-purpose-item.svelte +511 -0
- package/dist/components/iab-purpose-item.svelte.d.ts +26 -0
- package/dist/components/iab-stack-item.svelte +146 -0
- package/dist/components/iab-stack-item.svelte.d.ts +19 -0
- package/dist/components/iab-vendor-list.svelte +900 -0
- package/dist/components/iab-vendor-list.svelte.d.ts +19 -0
- package/dist/components/icons/c15-t-icon-only.svelte +27 -0
- package/dist/components/icons/c15-t-icon-only.svelte.d.ts +9 -0
- package/dist/components/icons/chevron-down-icon.svelte +30 -0
- package/dist/components/icons/chevron-down-icon.svelte.d.ts +10 -0
- package/dist/components/icons/chevron-right-icon.svelte +36 -0
- package/dist/components/icons/chevron-right-icon.svelte.d.ts +12 -0
- package/dist/components/icons/close-icon.svelte +40 -0
- package/dist/components/icons/close-icon.svelte.d.ts +10 -0
- package/dist/components/icons/consent-icon-only.svelte +36 -0
- package/dist/components/icons/consent-icon-only.svelte.d.ts +9 -0
- package/dist/components/icons/external-link-icon.svelte +30 -0
- package/dist/components/icons/external-link-icon.svelte.d.ts +8 -0
- package/dist/components/icons/globe-icon.svelte +39 -0
- package/dist/components/icons/globe-icon.svelte.d.ts +9 -0
- package/dist/components/icons/info-icon.svelte +42 -0
- package/dist/components/icons/info-icon.svelte.d.ts +9 -0
- package/dist/components/icons/inth-logo.svelte +38 -0
- package/dist/components/icons/inth-logo.svelte.d.ts +9 -0
- package/dist/components/icons/layers-icon.svelte +25 -0
- package/dist/components/icons/layers-icon.svelte.d.ts +8 -0
- package/dist/components/icons/legitimate-interest-icon.svelte +29 -0
- package/dist/components/icons/legitimate-interest-icon.svelte.d.ts +10 -0
- package/dist/components/icons/lock-icon.svelte +31 -0
- package/dist/components/icons/lock-icon.svelte.d.ts +8 -0
- package/dist/components/icons/search-icon.svelte +33 -0
- package/dist/components/icons/search-icon.svelte.d.ts +8 -0
- package/dist/components/inline-legal-links.svelte +95 -0
- package/dist/components/inline-legal-links.svelte.d.ts +10 -0
- package/dist/components/manager-provider.svelte +459 -0
- package/dist/components/manager-provider.svelte.d.ts +27 -0
- package/dist/components/overlay.svelte +79 -0
- package/dist/components/overlay.svelte.d.ts +7 -0
- package/dist/components/panel-link.svelte +33 -0
- package/dist/components/panel-link.svelte.d.ts +10 -0
- package/dist/components/panel-trigger.svelte +237 -0
- package/dist/components/panel-trigger.svelte.d.ts +16 -0
- package/dist/components/panel.svelte +258 -0
- package/dist/components/panel.svelte.d.ts +22 -0
- package/dist/components/policy-actions-renderer.svelte +79 -0
- package/dist/components/policy-actions-renderer.svelte.d.ts +19 -0
- package/dist/components/preferences.svelte +320 -0
- package/dist/components/preferences.svelte.d.ts +8 -0
- package/dist/components/prompt.svelte +514 -0
- package/dist/components/prompt.svelte.d.ts +43 -0
- package/dist/context.svelte.d.ts +125 -0
- package/dist/context.svelte.js +354 -0
- package/dist/devtools-options.d.ts +7 -0
- package/dist/devtools-options.js +1 -0
- package/dist/devtools.d.ts +9 -0
- package/dist/devtools.js +7 -0
- package/dist/headless.d.ts +10 -0
- package/dist/headless.js +7 -0
- package/dist/iab/styles.css +11 -0
- package/dist/iab-loader.d.ts +30 -0
- package/dist/iab-loader.js +33 -0
- package/dist/iab-translations.d.ts +84 -0
- package/dist/iab-translations.js +45 -0
- package/dist/iab-types.d.ts +62 -0
- package/dist/iab-types.js +43 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +21 -0
- package/dist/kit/app.d.ts +35 -0
- package/dist/kit/handle.d.ts +34 -0
- package/dist/kit/handle.js +87 -0
- package/dist/kit/index.d.ts +30 -0
- package/dist/kit/index.js +5 -0
- package/dist/kit/load-consent.d.ts +57 -0
- package/dist/kit/load-consent.js +144 -0
- package/dist/kit/routes.d.ts +46 -0
- package/dist/kit/routes.js +203 -0
- package/dist/kit/types.d.ts +56 -0
- package/dist/kit/types.js +1 -0
- package/dist/primitives/accordion/accordion-item-content.svelte +35 -0
- package/dist/primitives/accordion/accordion-item-content.svelte.d.ts +9 -0
- package/dist/primitives/accordion/accordion-item-trigger.svelte +54 -0
- package/dist/primitives/accordion/accordion-item-trigger.svelte.d.ts +10 -0
- package/dist/primitives/accordion/accordion-item.svelte +61 -0
- package/dist/primitives/accordion/accordion-item.svelte.d.ts +11 -0
- package/dist/primitives/accordion/accordion-root.svelte +61 -0
- package/dist/primitives/accordion/accordion-root.svelte.d.ts +13 -0
- package/dist/primitives/accordion/context.d.ts +18 -0
- package/dist/primitives/accordion/context.js +23 -0
- package/dist/primitives/accordion/index.d.ts +29 -0
- package/dist/primitives/accordion/index.js +11 -0
- package/dist/primitives/collapsible/collapsible-content.svelte +36 -0
- package/dist/primitives/collapsible/collapsible-content.svelte.d.ts +9 -0
- package/dist/primitives/collapsible/collapsible-indicator.svelte +29 -0
- package/dist/primitives/collapsible/collapsible-indicator.svelte.d.ts +9 -0
- package/dist/primitives/collapsible/collapsible-root.svelte +70 -0
- package/dist/primitives/collapsible/collapsible-root.svelte.d.ts +11 -0
- package/dist/primitives/collapsible/collapsible-trigger.svelte +52 -0
- package/dist/primitives/collapsible/collapsible-trigger.svelte.d.ts +10 -0
- package/dist/primitives/collapsible/context.d.ts +10 -0
- package/dist/primitives/collapsible/context.js +12 -0
- package/dist/primitives/collapsible/index.d.ts +26 -0
- package/dist/primitives/collapsible/index.js +11 -0
- package/dist/primitives/dialog/context.d.ts +14 -0
- package/dist/primitives/dialog/context.js +12 -0
- package/dist/primitives/dialog/dialog-backdrop.svelte +39 -0
- package/dist/primitives/dialog/dialog-backdrop.svelte.d.ts +7 -0
- package/dist/primitives/dialog/dialog-close-trigger.svelte +48 -0
- package/dist/primitives/dialog/dialog-close-trigger.svelte.d.ts +11 -0
- package/dist/primitives/dialog/dialog-content.svelte +81 -0
- package/dist/primitives/dialog/dialog-content.svelte.d.ts +9 -0
- package/dist/primitives/dialog/dialog-description.svelte +28 -0
- package/dist/primitives/dialog/dialog-description.svelte.d.ts +9 -0
- package/dist/primitives/dialog/dialog-positioner.svelte +33 -0
- package/dist/primitives/dialog/dialog-positioner.svelte.d.ts +9 -0
- package/dist/primitives/dialog/dialog-root.svelte +117 -0
- package/dist/primitives/dialog/dialog-root.svelte.d.ts +14 -0
- package/dist/primitives/dialog/dialog-title.svelte +28 -0
- package/dist/primitives/dialog/dialog-title.svelte.d.ts +9 -0
- package/dist/primitives/dialog/index.d.ts +50 -0
- package/dist/primitives/dialog/index.js +19 -0
- package/dist/primitives/index.d.ts +7 -0
- package/dist/primitives/index.js +7 -0
- package/dist/primitives/portal/index.d.ts +4 -0
- package/dist/primitives/portal/index.js +2 -0
- package/dist/primitives/portal/portal.svelte +23 -0
- package/dist/primitives/portal/portal.svelte.d.ts +9 -0
- package/dist/primitives/preference-item/context.d.ts +11 -0
- package/dist/primitives/preference-item/context.js +12 -0
- package/dist/primitives/preference-item/index.d.ts +54 -0
- package/dist/primitives/preference-item/index.js +21 -0
- package/dist/primitives/preference-item/preference-item-auxiliary.svelte +33 -0
- package/dist/primitives/preference-item/preference-item-auxiliary.svelte.d.ts +9 -0
- package/dist/primitives/preference-item/preference-item-content.svelte +68 -0
- package/dist/primitives/preference-item/preference-item-content.svelte.d.ts +14 -0
- package/dist/primitives/preference-item/preference-item-control.svelte +33 -0
- package/dist/primitives/preference-item/preference-item-control.svelte.d.ts +9 -0
- package/dist/primitives/preference-item/preference-item-header.svelte +33 -0
- package/dist/primitives/preference-item/preference-item-header.svelte.d.ts +9 -0
- package/dist/primitives/preference-item/preference-item-leading.svelte +33 -0
- package/dist/primitives/preference-item/preference-item-leading.svelte.d.ts +9 -0
- package/dist/primitives/preference-item/preference-item-meta.svelte +33 -0
- package/dist/primitives/preference-item/preference-item-meta.svelte.d.ts +9 -0
- package/dist/primitives/preference-item/preference-item-root.svelte +82 -0
- package/dist/primitives/preference-item/preference-item-root.svelte.d.ts +12 -0
- package/dist/primitives/preference-item/preference-item-title.svelte +33 -0
- package/dist/primitives/preference-item/preference-item-title.svelte.d.ts +9 -0
- package/dist/primitives/preference-item/preference-item-trigger.svelte +62 -0
- package/dist/primitives/preference-item/preference-item-trigger.svelte.d.ts +10 -0
- package/dist/primitives/switch/context.d.ts +7 -0
- package/dist/primitives/switch/context.js +12 -0
- package/dist/primitives/switch/index.d.ts +25 -0
- package/dist/primitives/switch/index.js +11 -0
- package/dist/primitives/switch/switch-control.svelte +21 -0
- package/dist/primitives/switch/switch-control.svelte.d.ts +9 -0
- package/dist/primitives/switch/switch-hidden-input.svelte +31 -0
- package/dist/primitives/switch/switch-hidden-input.svelte.d.ts +8 -0
- package/dist/primitives/switch/switch-root.svelte +86 -0
- package/dist/primitives/switch/switch-root.svelte.d.ts +12 -0
- package/dist/primitives/switch/switch-thumb.svelte +14 -0
- package/dist/primitives/switch/switch-thumb.svelte.d.ts +7 -0
- package/dist/primitives/tabs/context.d.ts +11 -0
- package/dist/primitives/tabs/context.js +12 -0
- package/dist/primitives/tabs/index.d.ts +32 -0
- package/dist/primitives/tabs/index.js +11 -0
- package/dist/primitives/tabs/tabs-content.svelte +45 -0
- package/dist/primitives/tabs/tabs-content.svelte.d.ts +11 -0
- package/dist/primitives/tabs/tabs-list.svelte +38 -0
- package/dist/primitives/tabs/tabs-list.svelte.d.ts +10 -0
- package/dist/primitives/tabs/tabs-root.svelte +67 -0
- package/dist/primitives/tabs/tabs-root.svelte.d.ts +14 -0
- package/dist/primitives/tabs/tabs-trigger.svelte +108 -0
- package/dist/primitives/tabs/tabs-trigger.svelte.d.ts +11 -0
- package/dist/server/headers.d.ts +13 -0
- package/dist/server/headers.js +37 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.js +116 -0
- package/dist/server/normalize-url.d.ts +23 -0
- package/dist/server/normalize-url.js +46 -0
- package/dist/server/types.d.ts +25 -0
- package/dist/server/types.js +1 -0
- package/dist/styles.css +10 -0
- package/dist/transports/offline.d.ts +14 -0
- package/dist/transports/offline.js +22 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.js +1 -0
- package/dist/use-banner-visibility.svelte.d.ts +25 -0
- package/dist/use-banner-visibility.svelte.js +108 -0
- package/dist/utils.d.ts +25 -0
- package/dist/utils.js +32 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/docs/README.md +88 -0
- package/docs/assets/v3/brand-bar.png +0 -0
- package/docs/assets/v3/brand-card.png +0 -0
- package/docs/assets/v3/choice-wall.png +0 -0
- package/docs/assets/v3/mobile-card.png +0 -0
- package/docs/assets/v3/preferences.png +0 -0
- package/docs/customization/overview.md +45 -0
- package/docs/customization/recipes.md +79 -0
- package/docs/customization/slots.md +55 -0
- package/docs/customization/tokens.md +76 -0
- package/docs/customization/translations.md +49 -0
- package/docs/frameworks/svelte/quickstart.md +133 -0
- package/docs/frameworks/sveltekit/quickstart.md +144 -0
- package/docs/guides/consent-state.md +60 -0
- package/docs/guides/data-fetching.md +163 -0
- package/docs/guides/deployment-modes.md +63 -0
- package/docs/guides/troubleshooting.md +68 -0
- package/docs/guides/verify-consent.md +62 -0
- package/docs/integrations/adobe-analytics.md +294 -0
- package/docs/integrations/ahrefs-analytics.md +291 -0
- package/docs/integrations/amplitude.md +292 -0
- package/docs/integrations/building-integrations.md +47 -0
- package/docs/integrations/clearbit.md +291 -0
- package/docs/integrations/cloudflare-web-analytics.md +292 -0
- package/docs/integrations/crisp.md +294 -0
- package/docs/integrations/databuddy.md +311 -0
- package/docs/integrations/fathom-analytics.md +293 -0
- package/docs/integrations/google-maps.md +384 -0
- package/docs/integrations/google-tag-manager.md +306 -0
- package/docs/integrations/google-tag.md +305 -0
- package/docs/integrations/heap.md +292 -0
- package/docs/integrations/hightouch.md +293 -0
- package/docs/integrations/hotjar.md +292 -0
- package/docs/integrations/intercom.md +285 -0
- package/docs/integrations/linkedin-insights.md +291 -0
- package/docs/integrations/logrocket.md +293 -0
- package/docs/integrations/matomo-analytics.md +316 -0
- package/docs/integrations/meta-pixel.md +285 -0
- package/docs/integrations/microsoft-clarity.md +292 -0
- package/docs/integrations/microsoft-uet.md +291 -0
- package/docs/integrations/mixpanel-analytics.md +295 -0
- package/docs/integrations/openai-pixel.md +441 -0
- package/docs/integrations/overview.md +111 -0
- package/docs/integrations/pirsch.md +295 -0
- package/docs/integrations/plausible-analytics.md +295 -0
- package/docs/integrations/posthog.md +397 -0
- package/docs/integrations/promptwatch.md +291 -0
- package/docs/integrations/reddit-pixel.md +294 -0
- package/docs/integrations/rudderstack.md +328 -0
- package/docs/integrations/rybbit-analytics.md +296 -0
- package/docs/integrations/segment.md +292 -0
- package/docs/integrations/snapchat-pixel.md +293 -0
- package/docs/integrations/tiktok-pixel.md +291 -0
- package/docs/integrations/umami-analytics.md +295 -0
- package/docs/integrations/vercel-analytics.md +293 -0
- package/docs/integrations/x-pixel.md +291 -0
- package/docs/integrations/youtube.md +405 -0
- package/docs/upgrade-v3.md +334 -0
- package/iab/styles.css +1 -0
- package/package.json +153 -0
- package/readme.json +36 -0
- package/styles.css +1 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { deferInitGvlToRoute, serveGvlReference } from '@c15t/core';
|
|
2
|
+
/**
|
|
3
|
+
* Same-origin consent routes for SvelteKit.
|
|
4
|
+
*
|
|
5
|
+
* Manifest mode (RFC 0001) moves policy resolution off the browser's critical
|
|
6
|
+
* path: the host fetches one geo-independent, CDN-cacheable manifest and
|
|
7
|
+
* resolves `/init` locally per request. These handlers are the SvelteKit
|
|
8
|
+
* server piece — the same contract `createNextConsentRouteHandlers` and the
|
|
9
|
+
* Nuxt route factories implement.
|
|
10
|
+
*
|
|
11
|
+
* Cache discipline:
|
|
12
|
+
* - The manifest route forwards the backend's `Cache-Control`/`ETag`
|
|
13
|
+
* verbatim and answers `If-None-Match` with `304`. The edge caches it; this
|
|
14
|
+
* process only dedupes bursts (see `@c15t/core/server`).
|
|
15
|
+
* - The init route is per-request (geo, language, GPC) and therefore
|
|
16
|
+
* `private, no-store`.
|
|
17
|
+
*/
|
|
18
|
+
import { fetchCachedManifest, getManifestAge, MANIFEST_PASSTHROUGH_HEADERS, } from '@c15t/core/server';
|
|
19
|
+
import { consentInputsToOverrides, extractConsentRequestInputs, resolveBackendURL, resolveInitFromManifest, } from '@c15t/schema/types';
|
|
20
|
+
import { baseTranslations } from '@c15t/translations/all';
|
|
21
|
+
const INIT_CACHE_CONTROL = 'private, no-store';
|
|
22
|
+
const MANIFEST_ROUTE_SUFFIX = '/manifest';
|
|
23
|
+
/**
|
|
24
|
+
* Hands a promise to the `waitUntil` a SvelteKit adapter exposes on
|
|
25
|
+
* `event.platform.context` (Cloudflare Workers and Pages, Vercel edge), so a
|
|
26
|
+
* background refresh outlives the response on runtimes that would cancel
|
|
27
|
+
* it. A no-op where the adapter provides none.
|
|
28
|
+
*/
|
|
29
|
+
export const waitUntilFromEvent = function waitUntilFromEvent(revalidation, event) {
|
|
30
|
+
const context = event.platform?.context;
|
|
31
|
+
if (context && typeof context.waitUntil === 'function') {
|
|
32
|
+
context.waitUntil.call(context, revalidation);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const bindBackgroundRevalidate = function bindBackgroundRevalidate(options, event) {
|
|
36
|
+
const onBackgroundRevalidate = options.onBackgroundRevalidate ?? waitUntilFromEvent;
|
|
37
|
+
return (revalidation) => onBackgroundRevalidate(revalidation, event);
|
|
38
|
+
};
|
|
39
|
+
const getEnv = function getEnv(name) {
|
|
40
|
+
if (typeof process === 'undefined') {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
// `process.env` is typed narrowly in a Svelte app's TS project; this
|
|
44
|
+
// module also runs in plain Node and edge runtimes.
|
|
45
|
+
return process.env?.[name];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Resolves a possibly-relative backend URL against the request.
|
|
49
|
+
*
|
|
50
|
+
* Only `event.url` decides the origin. SvelteKit derives it from the
|
|
51
|
+
* adapter's trusted configuration (`ORIGIN`, or `PROTOCOL_HEADER`/
|
|
52
|
+
* `HOST_HEADER` where a proxy is declared), so seeding from it both fixes a
|
|
53
|
+
* relative URL on a plain `http://localhost` dev server and keeps a forged
|
|
54
|
+
* `x-forwarded-host` from steering this server-side fetch at a host of the
|
|
55
|
+
* caller's choosing.
|
|
56
|
+
*/
|
|
57
|
+
const resolveAgainstRequest = function resolveAgainstRequest(url, event) {
|
|
58
|
+
return resolveBackendURL(url, {
|
|
59
|
+
host: event.url.host,
|
|
60
|
+
'x-forwarded-proto': event.url.protocol.replace(':', ''),
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Resolves where the manifest lives for this request, honouring explicit
|
|
65
|
+
* options first and then the `C15T_MANIFEST_URL` / `C15T_BACKEND_URL`
|
|
66
|
+
* environment variables.
|
|
67
|
+
*/
|
|
68
|
+
const resolveManifestSource = function resolveManifestSource(event, options) {
|
|
69
|
+
const manifestURL = options.manifestURL ?? getEnv('C15T_MANIFEST_URL');
|
|
70
|
+
if (manifestURL) {
|
|
71
|
+
const resolved = resolveAgainstRequest(manifestURL, event);
|
|
72
|
+
if (!resolved) {
|
|
73
|
+
throw new Error('@c15t/svelte/kit: invalid manifest URL.');
|
|
74
|
+
}
|
|
75
|
+
return { manifestURL: resolved };
|
|
76
|
+
}
|
|
77
|
+
const backendURL = options.backendURL ?? getEnv('C15T_BACKEND_URL');
|
|
78
|
+
if (!backendURL) {
|
|
79
|
+
throw new Error('@c15t/svelte/kit: configure `backendURL`, `manifestURL`, or the C15T_BACKEND_URL environment variable.');
|
|
80
|
+
}
|
|
81
|
+
const resolved = resolveAgainstRequest(backendURL, event);
|
|
82
|
+
if (!resolved) {
|
|
83
|
+
throw new Error('@c15t/svelte/kit: invalid backend URL.');
|
|
84
|
+
}
|
|
85
|
+
return { manifestURL: `${resolved}${MANIFEST_ROUTE_SUFFIX}` };
|
|
86
|
+
};
|
|
87
|
+
const shouldFetchGvl = function shouldFetchGvl(manifest, payload) {
|
|
88
|
+
return (manifest.iab?.enabled === true &&
|
|
89
|
+
manifest.iab.gvl !== undefined &&
|
|
90
|
+
payload.policyResolution?.status === 'matched' &&
|
|
91
|
+
payload.policyResolution.policy.model === 'iab');
|
|
92
|
+
};
|
|
93
|
+
const defaultFetchGvl = async function defaultFetchGvl(input) {
|
|
94
|
+
const response = await input.fetch(input.reference.url, {
|
|
95
|
+
headers: { 'accept-language': input.language },
|
|
96
|
+
method: 'GET',
|
|
97
|
+
});
|
|
98
|
+
if (response.status === 204) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
throw new Error(`@c15t/svelte/kit: GVL responded ${response.status} ${response.statusText}`);
|
|
103
|
+
}
|
|
104
|
+
return (await response.json());
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Creates the SvelteKit request handlers for manifest mode.
|
|
108
|
+
*
|
|
109
|
+
* Two shapes are supported. A single catch-all route:
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
* // src/routes/api/c15t/[...path]/+server.ts
|
|
113
|
+
* import { createSvelteKitConsentRouteHandlers } from '@c15t/svelte/kit';
|
|
114
|
+
*
|
|
115
|
+
* export const { GET } = createSvelteKitConsentRouteHandlers({
|
|
116
|
+
* backendURL: process.env.C15T_BACKEND_URL,
|
|
117
|
+
* });
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* …or one file per route, using `init` and `manifest` directly.
|
|
121
|
+
*
|
|
122
|
+
* @param options - Manifest source, fetch implementation, GVL fetcher.
|
|
123
|
+
* @returns `init`, `manifest`, and a `GET` that dispatches between them.
|
|
124
|
+
*/
|
|
125
|
+
export const createSvelteKitConsentRouteHandlers = function createSvelteKitConsentRouteHandlers(options = {}) {
|
|
126
|
+
const init = async (event) => {
|
|
127
|
+
const { manifestURL } = resolveManifestSource(event, options);
|
|
128
|
+
const { manifest } = await fetchCachedManifest({
|
|
129
|
+
config: { manifestURL },
|
|
130
|
+
fetch: options.fetch,
|
|
131
|
+
onBackgroundRevalidate: bindBackgroundRevalidate(options, event),
|
|
132
|
+
});
|
|
133
|
+
const listResponse = await serveGvlReference(event.request, (language) => manifest.iab?.gvl
|
|
134
|
+
? (options.fetchGvl ?? defaultFetchGvl)({
|
|
135
|
+
fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
|
|
136
|
+
language,
|
|
137
|
+
reference: manifest.iab.gvl,
|
|
138
|
+
})
|
|
139
|
+
: Promise.resolve(null));
|
|
140
|
+
if (listResponse) {
|
|
141
|
+
return listResponse;
|
|
142
|
+
}
|
|
143
|
+
const inputs = extractConsentRequestInputs(event.request.headers);
|
|
144
|
+
const payload = resolveInitFromManifest(manifest, {
|
|
145
|
+
country: inputs.country,
|
|
146
|
+
gpc: inputs.gpc,
|
|
147
|
+
language: inputs.language ?? 'en',
|
|
148
|
+
region: inputs.region,
|
|
149
|
+
}, { baseTranslations });
|
|
150
|
+
if (shouldFetchGvl(manifest, payload) && manifest.iab?.gvl) {
|
|
151
|
+
const language = payload.translations.language.split('-')[0] || 'en';
|
|
152
|
+
payload.gvl = await (options.fetchGvl ?? defaultFetchGvl)({
|
|
153
|
+
fetch: (options.fetch ??
|
|
154
|
+
globalThis.fetch.bind(globalThis)),
|
|
155
|
+
language,
|
|
156
|
+
reference: manifest.iab.gvl,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// The resolver's inputs are the only place GPC survives on the SSR
|
|
160
|
+
// path — the browser never sends `Sec-GPC` to this route when the
|
|
161
|
+
// page was server-rendered. Echo them back so the kernel folds the
|
|
162
|
+
// same overrides it would have derived client-side.
|
|
163
|
+
payload.resolvedOverrides = consentInputsToOverrides({
|
|
164
|
+
country: inputs.country,
|
|
165
|
+
language: inputs.language,
|
|
166
|
+
region: inputs.region,
|
|
167
|
+
});
|
|
168
|
+
payload.resolvedPrivacySignals = { gpc: inputs.gpc };
|
|
169
|
+
return Response.json(deferInitGvlToRoute(payload, new URL(event.request.url).pathname), {
|
|
170
|
+
headers: { 'cache-control': INIT_CACHE_CONTROL },
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
const manifest = async (event) => {
|
|
174
|
+
const { manifestURL } = resolveManifestSource(event, options);
|
|
175
|
+
const query = event.url.searchParams.toString();
|
|
176
|
+
const result = await fetchCachedManifest({
|
|
177
|
+
config: { manifestURL },
|
|
178
|
+
fetch: options.fetch,
|
|
179
|
+
onBackgroundRevalidate: bindBackgroundRevalidate(options, event),
|
|
180
|
+
query,
|
|
181
|
+
});
|
|
182
|
+
const headers = new Headers({ 'content-type': 'application/json' });
|
|
183
|
+
for (const name of MANIFEST_PASSTHROUGH_HEADERS) {
|
|
184
|
+
const value = result.headers[name];
|
|
185
|
+
if (value) {
|
|
186
|
+
headers.set(name, value);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
headers.set('age', String(getManifestAge(result)));
|
|
190
|
+
const { etag } = result.headers;
|
|
191
|
+
if (etag && event.request.headers.get('if-none-match') === etag) {
|
|
192
|
+
return new Response(null, { headers, status: 304 });
|
|
193
|
+
}
|
|
194
|
+
return new Response(JSON.stringify(result.manifest), {
|
|
195
|
+
headers,
|
|
196
|
+
status: 200,
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
const GET = (event) => event.url.pathname.endsWith(MANIFEST_ROUTE_SUFFIX)
|
|
200
|
+
? manifest(event)
|
|
201
|
+
: init(event);
|
|
202
|
+
return { GET, init, manifest };
|
|
203
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { KernelConfig } from '@c15t/core';
|
|
2
|
+
import type { ManifestFetch, ManifestSourceConfig } from '@c15t/core/server';
|
|
3
|
+
import type { ConsentRequestHeaderInputs } from '@c15t/schema/types';
|
|
4
|
+
import type { RequestEvent } from '@sveltejs/kit';
|
|
5
|
+
/**
|
|
6
|
+
* What {@link c15tHandle} stores on `event.locals.c15t`.
|
|
7
|
+
*
|
|
8
|
+
* `config` is the serializable {@link KernelConfig} to hand the provider as
|
|
9
|
+
* `prefetch`; `inputs` is the normalized geo/language/GPC context the handle
|
|
10
|
+
* derived from the request, kept so downstream loads and route handlers do
|
|
11
|
+
* not re-parse headers.
|
|
12
|
+
*/
|
|
13
|
+
export interface C15tLocals {
|
|
14
|
+
/** Kernel config seeded from the consent cookie and request inputs. */
|
|
15
|
+
config: KernelConfig;
|
|
16
|
+
/** Normalized country / region / language / GPC for this request. */
|
|
17
|
+
inputs: ConsentRequestInputs;
|
|
18
|
+
/**
|
|
19
|
+
* The cookie name the handle actually read, when it was given one.
|
|
20
|
+
* `loadConsent` falls back to it so a per-call geo override does not
|
|
21
|
+
* silently re-read the default `c15t` key and lose persisted consent.
|
|
22
|
+
*/
|
|
23
|
+
cookieName?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Normalized consent request context. Re-exported for `App.Locals` users. */
|
|
26
|
+
export type ConsentRequestInputs = ConsentRequestHeaderInputs;
|
|
27
|
+
/** Shared options for reading the consent cookie and request context. */
|
|
28
|
+
export interface ConsentRequestOptions {
|
|
29
|
+
/**
|
|
30
|
+
* Cookie name holding persisted consent. Defaults to `c15t` — the
|
|
31
|
+
* persistence module's storage key. Set this only if you customized
|
|
32
|
+
* `storageConfig.storageKey` client-side; it must match.
|
|
33
|
+
*/
|
|
34
|
+
cookieName?: string;
|
|
35
|
+
/** Force the resolved country, ignoring geo headers. */
|
|
36
|
+
country?: string;
|
|
37
|
+
/** Force the resolved region, ignoring geo headers. */
|
|
38
|
+
region?: string;
|
|
39
|
+
/** Force the resolved language, ignoring `Accept-Language`. */
|
|
40
|
+
language?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Manifest-mode wiring shared by the route handlers and `loadConsent`. */
|
|
43
|
+
export interface ConsentManifestOptions extends ManifestSourceConfig {
|
|
44
|
+
/** Fetch implementation. Defaults to the global `fetch`. */
|
|
45
|
+
fetch?: ManifestFetch;
|
|
46
|
+
/**
|
|
47
|
+
* Receives the promise of a background manifest revalidation started by
|
|
48
|
+
* this request, with the request event, so the host can keep it alive
|
|
49
|
+
* past the response on runtimes that stop detached work once a response
|
|
50
|
+
* is sent. Defaults to handing it to `event.platform.context.waitUntil`
|
|
51
|
+
* when the adapter provides one (Cloudflare, Vercel edge); nothing is
|
|
52
|
+
* registered otherwise. The promise never rejects. Not called when the
|
|
53
|
+
* manifest is fresh or the request itself waits on the upstream.
|
|
54
|
+
*/
|
|
55
|
+
onBackgroundRevalidate?: (revalidation: Promise<void>, event: RequestEvent) => void;
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getOpenState } from '@c15t/ui/primitives';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
5
|
+
|
|
6
|
+
import { getAccordionItemContext } from './context';
|
|
7
|
+
|
|
8
|
+
const item = getAccordionItemContext();
|
|
9
|
+
|
|
10
|
+
const open = $derived(item.open);
|
|
11
|
+
const triggerId = $derived(item.triggerId);
|
|
12
|
+
const contentId = $derived(item.contentId);
|
|
13
|
+
const dataState = $derived(getOpenState(open));
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
children,
|
|
17
|
+
class: className,
|
|
18
|
+
...restProps
|
|
19
|
+
}: HTMLAttributes<HTMLElement> & {
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
class?: string;
|
|
22
|
+
} = $props();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<section
|
|
26
|
+
id={contentId}
|
|
27
|
+
class={className}
|
|
28
|
+
aria-hidden={!open}
|
|
29
|
+
aria-labelledby={triggerId}
|
|
30
|
+
data-slot="accordion-content"
|
|
31
|
+
data-state={dataState}
|
|
32
|
+
{...restProps}
|
|
33
|
+
>
|
|
34
|
+
{@render children?.()}
|
|
35
|
+
</section>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = HTMLAttributes<HTMLElement> & {
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
class?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const AccordionItemContent: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type AccordionItemContent = ReturnType<typeof AccordionItemContent>;
|
|
9
|
+
export default AccordionItemContent;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getDataDisabled, getOpenState } from '@c15t/ui/primitives';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
5
|
+
|
|
6
|
+
import { getAccordionItemContext, getAccordionRootContext } from './context';
|
|
7
|
+
|
|
8
|
+
const root = getAccordionRootContext();
|
|
9
|
+
const item = getAccordionItemContext();
|
|
10
|
+
|
|
11
|
+
const open = $derived(item.open);
|
|
12
|
+
const disabled = $derived(item.disabled);
|
|
13
|
+
const triggerId = $derived(item.triggerId);
|
|
14
|
+
const contentId = $derived(item.contentId);
|
|
15
|
+
const itemValue = $derived(item.value);
|
|
16
|
+
const dataState = $derived(getOpenState(open));
|
|
17
|
+
const dataDisabled = $derived(getDataDisabled(disabled));
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
children,
|
|
21
|
+
class: className,
|
|
22
|
+
onclick,
|
|
23
|
+
type = 'button',
|
|
24
|
+
...restProps
|
|
25
|
+
}: HTMLAttributes<HTMLButtonElement> & {
|
|
26
|
+
children?: Snippet;
|
|
27
|
+
class?: string;
|
|
28
|
+
type?: 'button' | 'submit' | 'reset';
|
|
29
|
+
} = $props();
|
|
30
|
+
|
|
31
|
+
const handleClick = function handleClick(
|
|
32
|
+
event: MouseEvent & { currentTarget: EventTarget & HTMLButtonElement }
|
|
33
|
+
) {
|
|
34
|
+
root.toggleItem(itemValue);
|
|
35
|
+
onclick?.(event);
|
|
36
|
+
};
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<button
|
|
40
|
+
{type}
|
|
41
|
+
id={triggerId}
|
|
42
|
+
class={className}
|
|
43
|
+
aria-controls={contentId}
|
|
44
|
+
aria-disabled={disabled || undefined}
|
|
45
|
+
aria-expanded={open}
|
|
46
|
+
data-slot="accordion-trigger"
|
|
47
|
+
data-state={dataState}
|
|
48
|
+
data-disabled={dataDisabled}
|
|
49
|
+
{disabled}
|
|
50
|
+
{...restProps}
|
|
51
|
+
onclick={handleClick}
|
|
52
|
+
>
|
|
53
|
+
{@render children?.()}
|
|
54
|
+
</button>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = HTMLAttributes<HTMLButtonElement> & {
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
class?: string;
|
|
6
|
+
type?: 'button' | 'submit' | 'reset';
|
|
7
|
+
};
|
|
8
|
+
declare const AccordionItemTrigger: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type AccordionItemTrigger = ReturnType<typeof AccordionItemTrigger>;
|
|
10
|
+
export default AccordionItemTrigger;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
getDataDisabled,
|
|
4
|
+
getOpenState,
|
|
5
|
+
isAccordionItemOpen,
|
|
6
|
+
} from '@c15t/ui/primitives';
|
|
7
|
+
import type { Snippet } from 'svelte';
|
|
8
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
9
|
+
|
|
10
|
+
import { getAccordionRootContext, setAccordionItemContext } from './context';
|
|
11
|
+
|
|
12
|
+
const componentId = $props.id();
|
|
13
|
+
const root = getAccordionRootContext();
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
children,
|
|
17
|
+
class: className,
|
|
18
|
+
disabled = false,
|
|
19
|
+
value,
|
|
20
|
+
...restProps
|
|
21
|
+
}: HTMLAttributes<HTMLDivElement> & {
|
|
22
|
+
children?: Snippet;
|
|
23
|
+
class?: string;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
value: string;
|
|
26
|
+
} = $props();
|
|
27
|
+
|
|
28
|
+
const open = $derived(isAccordionItemOpen(root.type, root.value, value));
|
|
29
|
+
const dataState = $derived(getOpenState(open));
|
|
30
|
+
const dataDisabled = $derived(getDataDisabled(disabled));
|
|
31
|
+
const triggerId = `c15t-accordion-trigger-${componentId}`;
|
|
32
|
+
const contentId = `c15t-accordion-content-${componentId}`;
|
|
33
|
+
|
|
34
|
+
setAccordionItemContext({
|
|
35
|
+
get contentId() {
|
|
36
|
+
return contentId;
|
|
37
|
+
},
|
|
38
|
+
get disabled() {
|
|
39
|
+
return disabled;
|
|
40
|
+
},
|
|
41
|
+
get open() {
|
|
42
|
+
return open;
|
|
43
|
+
},
|
|
44
|
+
get triggerId() {
|
|
45
|
+
return triggerId;
|
|
46
|
+
},
|
|
47
|
+
get value() {
|
|
48
|
+
return value;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<div
|
|
54
|
+
class={className}
|
|
55
|
+
data-slot="accordion-item"
|
|
56
|
+
data-state={dataState}
|
|
57
|
+
data-disabled={dataDisabled}
|
|
58
|
+
{...restProps}
|
|
59
|
+
>
|
|
60
|
+
{@render children?.()}
|
|
61
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
class?: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
value: string;
|
|
8
|
+
};
|
|
9
|
+
declare const AccordionItem: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type AccordionItem = ReturnType<typeof AccordionItem>;
|
|
11
|
+
export default AccordionItem;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { AccordionType } from '@c15t/ui/primitives';
|
|
3
|
+
import { toggleAccordionValue } from '@c15t/ui/primitives';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
6
|
+
|
|
7
|
+
import { setAccordionRootContext } from './context';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
children,
|
|
11
|
+
class: className,
|
|
12
|
+
collapsible = false,
|
|
13
|
+
type,
|
|
14
|
+
value = $bindable<string | string[] | undefined>(
|
|
15
|
+
type === 'multiple' ? [] : undefined
|
|
16
|
+
),
|
|
17
|
+
...restProps
|
|
18
|
+
}: HTMLAttributes<HTMLDivElement> & {
|
|
19
|
+
children?: Snippet;
|
|
20
|
+
class?: string;
|
|
21
|
+
collapsible?: boolean;
|
|
22
|
+
type: AccordionType;
|
|
23
|
+
value?: string | string[];
|
|
24
|
+
} = $props();
|
|
25
|
+
|
|
26
|
+
const setValue = function setValue(nextValue: string | string[] | undefined) {
|
|
27
|
+
value = nextValue;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const toggleItem = function toggleItem(itemValue: string) {
|
|
31
|
+
setValue(
|
|
32
|
+
toggleAccordionValue({
|
|
33
|
+
collapsible,
|
|
34
|
+
itemValue,
|
|
35
|
+
type,
|
|
36
|
+
value,
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
setAccordionRootContext({
|
|
42
|
+
get collapsible() {
|
|
43
|
+
return collapsible;
|
|
44
|
+
},
|
|
45
|
+
toggleItem,
|
|
46
|
+
get type() {
|
|
47
|
+
return type;
|
|
48
|
+
},
|
|
49
|
+
get value() {
|
|
50
|
+
return value;
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<div
|
|
56
|
+
class={className}
|
|
57
|
+
data-slot="accordion-root"
|
|
58
|
+
{...restProps}
|
|
59
|
+
>
|
|
60
|
+
{@render children?.()}
|
|
61
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AccordionType } from '@c15t/ui/primitives';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
class?: string;
|
|
7
|
+
collapsible?: boolean;
|
|
8
|
+
type: AccordionType;
|
|
9
|
+
value?: string | string[];
|
|
10
|
+
};
|
|
11
|
+
declare const AccordionRoot: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
12
|
+
type AccordionRoot = ReturnType<typeof AccordionRoot>;
|
|
13
|
+
export default AccordionRoot;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AccordionType } from '@c15t/ui/primitives';
|
|
2
|
+
export interface AccordionRootContextValue {
|
|
3
|
+
readonly collapsible: boolean;
|
|
4
|
+
readonly type: AccordionType;
|
|
5
|
+
readonly value: string | string[] | undefined;
|
|
6
|
+
toggleItem: (itemValue: string) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface AccordionItemContextValue {
|
|
9
|
+
readonly contentId: string;
|
|
10
|
+
readonly disabled: boolean;
|
|
11
|
+
readonly open: boolean;
|
|
12
|
+
readonly triggerId: string;
|
|
13
|
+
readonly value: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const setAccordionRootContext: (value: AccordionRootContextValue) => void;
|
|
16
|
+
export declare const getAccordionRootContext: () => AccordionRootContextValue;
|
|
17
|
+
export declare const setAccordionItemContext: (value: AccordionItemContextValue) => void;
|
|
18
|
+
export declare const getAccordionItemContext: () => AccordionItemContextValue;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
const ACCORDION_ROOT_CONTEXT_KEY = Symbol('c15t-svelte-accordion-root');
|
|
3
|
+
const ACCORDION_ITEM_CONTEXT_KEY = Symbol('c15t-svelte-accordion-item');
|
|
4
|
+
export const setAccordionRootContext = function setAccordionRootContext(value) {
|
|
5
|
+
setContext(ACCORDION_ROOT_CONTEXT_KEY, value);
|
|
6
|
+
};
|
|
7
|
+
export const getAccordionRootContext = function getAccordionRootContext() {
|
|
8
|
+
const context = getContext(ACCORDION_ROOT_CONTEXT_KEY);
|
|
9
|
+
if (!context) {
|
|
10
|
+
throw new Error('Accordion primitives must be used within Accordion.Root');
|
|
11
|
+
}
|
|
12
|
+
return context;
|
|
13
|
+
};
|
|
14
|
+
export const setAccordionItemContext = function setAccordionItemContext(value) {
|
|
15
|
+
setContext(ACCORDION_ITEM_CONTEXT_KEY, value);
|
|
16
|
+
};
|
|
17
|
+
export const getAccordionItemContext = function getAccordionItemContext() {
|
|
18
|
+
const context = getContext(ACCORDION_ITEM_CONTEXT_KEY);
|
|
19
|
+
if (!context) {
|
|
20
|
+
throw new Error('Accordion primitives must be used within Accordion.Item');
|
|
21
|
+
}
|
|
22
|
+
return context;
|
|
23
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import ItemContent from './accordion-item-content.svelte';
|
|
2
|
+
import ItemTrigger from './accordion-item-trigger.svelte';
|
|
3
|
+
import Item from './accordion-item.svelte';
|
|
4
|
+
import Root from './accordion-root.svelte';
|
|
5
|
+
export declare const Accordion: {
|
|
6
|
+
Item: import("svelte").Component<import("svelte/elements").HTMLAttributes<HTMLDivElement> & {
|
|
7
|
+
children?: import("svelte").Snippet;
|
|
8
|
+
class?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
value: string;
|
|
11
|
+
}, {}, "">;
|
|
12
|
+
ItemContent: import("svelte").Component<import("svelte/elements").HTMLAttributes<HTMLElement> & {
|
|
13
|
+
children?: import("svelte").Snippet;
|
|
14
|
+
class?: string;
|
|
15
|
+
}, {}, "">;
|
|
16
|
+
ItemTrigger: import("svelte").Component<import("svelte/elements").HTMLAttributes<HTMLButtonElement> & {
|
|
17
|
+
children?: import("svelte").Snippet;
|
|
18
|
+
class?: string;
|
|
19
|
+
type?: "button" | "submit" | "reset";
|
|
20
|
+
}, {}, "">;
|
|
21
|
+
Root: import("svelte").Component<import("svelte/elements").HTMLAttributes<HTMLDivElement> & {
|
|
22
|
+
children?: import("svelte").Snippet;
|
|
23
|
+
class?: string;
|
|
24
|
+
collapsible?: boolean;
|
|
25
|
+
type: import("@c15t/ui/primitives").AccordionType;
|
|
26
|
+
value?: string | string[];
|
|
27
|
+
}, {}, "value">;
|
|
28
|
+
};
|
|
29
|
+
export { Item, ItemContent, ItemTrigger, Root };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import ItemContent from './accordion-item-content.svelte';
|
|
2
|
+
import ItemTrigger from './accordion-item-trigger.svelte';
|
|
3
|
+
import Item from './accordion-item.svelte';
|
|
4
|
+
import Root from './accordion-root.svelte';
|
|
5
|
+
export const Accordion = {
|
|
6
|
+
Item,
|
|
7
|
+
ItemContent,
|
|
8
|
+
ItemTrigger,
|
|
9
|
+
Root,
|
|
10
|
+
};
|
|
11
|
+
export { Item, ItemContent, ItemTrigger, Root };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getCollapsibleState } from '@c15t/ui/primitives';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
5
|
+
|
|
6
|
+
import { getCollapsibleRootContext } from './context';
|
|
7
|
+
|
|
8
|
+
const root = getCollapsibleRootContext();
|
|
9
|
+
|
|
10
|
+
const open = $derived(root.open);
|
|
11
|
+
const contentId = $derived(root.contentId);
|
|
12
|
+
const triggerId = $derived(root.triggerId);
|
|
13
|
+
const dataState = $derived(getCollapsibleState(open));
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
children,
|
|
17
|
+
class: className,
|
|
18
|
+
...restProps
|
|
19
|
+
}: HTMLAttributes<HTMLDivElement> & {
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
class?: string;
|
|
22
|
+
} = $props();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div
|
|
26
|
+
id={contentId}
|
|
27
|
+
class={className}
|
|
28
|
+
aria-hidden={!open}
|
|
29
|
+
aria-labelledby={triggerId}
|
|
30
|
+
data-slot="collapsible-content"
|
|
31
|
+
data-state={dataState}
|
|
32
|
+
inert={!open}
|
|
33
|
+
{...restProps}
|
|
34
|
+
>
|
|
35
|
+
{@render children?.()}
|
|
36
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
class?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const CollapsibleContent: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type CollapsibleContent = ReturnType<typeof CollapsibleContent>;
|
|
9
|
+
export default CollapsibleContent;
|