@leabankab/component-library 7.1.1 → 7.3.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 +62 -0
- package/dist/component-library.es.js +2169 -1932
- package/dist/component-library.es.js.map +1 -1
- package/dist/component-library.umd.js +11 -18
- package/dist/component-library.umd.js.map +1 -1
- package/dist/components/buttons/button-base.d.ts +5 -5
- package/dist/components/buttons/button.d.ts +2 -2
- package/dist/components/buttons/icon-button.d.ts +1 -1
- package/dist/components/feedback/alert-parts.d.ts +328 -0
- package/dist/components/feedback/alert.d.ts +13 -18
- package/dist/components/feedback/dialog.d.ts +7 -0
- package/dist/components/feedback/global-alert.d.ts +24 -0
- package/dist/components/feedback/index.d.ts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/layout/container.d.ts +23 -0
- package/dist/components/layout/grid.d.ts +51 -0
- package/dist/components/layout/index.d.ts +4 -0
- package/dist/components/layout/responsive.d.ts +19 -0
- package/dist/components/layout/stack.d.ts +56 -0
- package/dist/components/navigation/index.d.ts +2 -0
- package/dist/components/navigation/linear-form-stepper.d.ts +58 -0
- package/dist/components/navigation/step-progress.d.ts +60 -0
- package/dist/components/ui/app-header.d.ts +21 -0
- package/dist/components/ui/brand-divider.d.ts +7 -1
- package/dist/components/ui/index.d.ts +1 -0
- package/dist/cookie-consent/consent-dialog.d.ts +15 -0
- package/dist/cookie-consent/constants.d.ts +11 -0
- package/dist/cookie-consent/copy.d.ts +19 -0
- package/dist/cookie-consent/core.d.ts +36 -0
- package/dist/cookie-consent/domain.d.ts +15 -0
- package/dist/cookie-consent/index.d.ts +4 -0
- package/dist/cookie-consent/react.d.ts +23 -0
- package/dist/cookie-consent/strapi-blocks.d.ts +65 -0
- package/dist/cookie-consent-core-C4MP7GlV.cjs +2 -0
- package/dist/cookie-consent-core-C4MP7GlV.cjs.map +1 -0
- package/dist/cookie-consent-core-mwVmy5nZ.mjs +124 -0
- package/dist/cookie-consent-core-mwVmy5nZ.mjs.map +1 -0
- package/dist/cookie-consent-react.cjs +2 -0
- package/dist/cookie-consent-react.cjs.map +1 -0
- package/dist/cookie-consent-react.mjs +433 -0
- package/dist/cookie-consent-react.mjs.map +1 -0
- package/dist/cookie-consent.cjs +1 -0
- package/dist/cookie-consent.css +1 -0
- package/dist/cookie-consent.mjs +2 -0
- package/dist/index.css +1 -1
- package/dist/tailwind.css +193 -0
- package/dist/theme/index.d.ts +1 -0
- package/dist/theme/tokens/breakpoints.d.ts +16 -0
- package/dist/theme/tokens/index.d.ts +2 -0
- package/dist/theme/tokens/opacity.d.ts +5 -0
- package/package.json +22 -3
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ProgressCircleColor } from './progress-circle';
|
|
3
|
+
import { StepperLabels } from './use-stepper-labels';
|
|
4
|
+
export type LinearFormStepperProps = {
|
|
5
|
+
/** Active step (1-based). */
|
|
6
|
+
currentStep: number;
|
|
7
|
+
/**
|
|
8
|
+
* Total number of steps. May change between renders, e.g. when the next step
|
|
9
|
+
* from the API reveals a different path; the bar animates to the new value.
|
|
10
|
+
*/
|
|
11
|
+
totalSteps: number;
|
|
12
|
+
/** Title of the current step. Rendered as a heading and names the progress bar. */
|
|
13
|
+
title: ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Called when the back button is pressed. The back button only renders when
|
|
16
|
+
* this is provided, so omit it on the first step or in forms without a back
|
|
17
|
+
* flow.
|
|
18
|
+
*/
|
|
19
|
+
onBack?: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Bar colour.
|
|
22
|
+
* @default "purple"
|
|
23
|
+
*/
|
|
24
|
+
color?: ProgressCircleColor;
|
|
25
|
+
/**
|
|
26
|
+
* Heading level of the title.
|
|
27
|
+
* @default "h1"
|
|
28
|
+
*/
|
|
29
|
+
headingLevel?: "h1" | "h2" | "h3";
|
|
30
|
+
/**
|
|
31
|
+
* Id applied to the title. Defaults to a generated id. Use it to move focus to
|
|
32
|
+
* the title when the step changes so the new step is announced. Must be
|
|
33
|
+
* unique in the document.
|
|
34
|
+
*/
|
|
35
|
+
titleId?: string;
|
|
36
|
+
/** Override the built-in translated labels per-instance. */
|
|
37
|
+
labels?: StepperLabels;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Header for a multi-step form whose steps aren't all known up front: a linear
|
|
41
|
+
* progress bar above the current step's title, with an optional back button.
|
|
42
|
+
* Use `FormStepper` instead when the full step list is known.
|
|
43
|
+
*
|
|
44
|
+
* The bar is a `progressbar` named by the title heading, with the step count
|
|
45
|
+
* (`"step X of Y"`) as its value text. The title carries `tabIndex={-1}`; move
|
|
46
|
+
* focus to it (via `titleId`) whenever the step changes so screen-reader users
|
|
47
|
+
* hear the new step.
|
|
48
|
+
*
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <LinearFormStepper
|
|
51
|
+
* currentStep={2}
|
|
52
|
+
* totalSteps={5}
|
|
53
|
+
* title="Refinancing"
|
|
54
|
+
* onBack={() => history.back()}
|
|
55
|
+
* />
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare const LinearFormStepper: ({ currentStep, totalSteps, title, onBack, color, headingLevel: Heading, titleId, labels, }: LinearFormStepperProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { LinearFormStepperProps } from './linear-form-stepper';
|
|
3
|
+
/**
|
|
4
|
+
* The step a flow is on, already resolved by the app. The library never
|
|
5
|
+
* defines steps: the app maps its own step (e.g. from the API) to a position
|
|
6
|
+
* and a translated title, then reports it.
|
|
7
|
+
*/
|
|
8
|
+
export type StepProgress = {
|
|
9
|
+
/** Active step (1-based). */
|
|
10
|
+
currentStep: number;
|
|
11
|
+
/** Total number of steps. May change as the flow reveals its path. */
|
|
12
|
+
totalSteps: number;
|
|
13
|
+
/** Translated title of the current step. */
|
|
14
|
+
title: string;
|
|
15
|
+
};
|
|
16
|
+
export type StepProgressProviderProps = {
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Progress to show on the first render, before any page has reported, e.g.
|
|
20
|
+
* so a server-rendered layout paints the bar straight away.
|
|
21
|
+
*/
|
|
22
|
+
initialProgress?: StepProgress;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Holds the step a persistent flow header shows. Put it in the flow layout,
|
|
26
|
+
* above the route's loading boundary, so the header survives step navigations
|
|
27
|
+
* instead of remounting with the page, and its bar animates between steps.
|
|
28
|
+
*
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <StepProgressProvider>
|
|
31
|
+
* <StepProgressHeader onBack={router.back} />
|
|
32
|
+
* {children}
|
|
33
|
+
* </StepProgressProvider>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const StepProgressProvider: ({ children, initialProgress, }: StepProgressProviderProps) => import("react").JSX.Element;
|
|
37
|
+
/**
|
|
38
|
+
* The last reported step, or `null` before anything has been reported or
|
|
39
|
+
* outside a `StepProgressProvider`. Use it to render `FormStepper` or a custom
|
|
40
|
+
* header from the same state.
|
|
41
|
+
*/
|
|
42
|
+
export declare const useStepProgress: () => StepProgress | null;
|
|
43
|
+
/**
|
|
44
|
+
* Publishes the current step to the nearest `StepProgressProvider`. Pass
|
|
45
|
+
* `null` while the step isn't resolved yet; nothing is reported then. Never
|
|
46
|
+
* clears on unmount, so the header holds its value while the next route's
|
|
47
|
+
* loading fallback is on screen.
|
|
48
|
+
*
|
|
49
|
+
* ```tsx
|
|
50
|
+
* useReportStepProgress({ currentStep: 2, totalSteps: 5, title: t("income") });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare const useReportStepProgress: (progress: StepProgress | null) => void;
|
|
54
|
+
export type StepProgressHeaderProps = Omit<LinearFormStepperProps, "currentStep" | "totalSteps" | "title">;
|
|
55
|
+
/**
|
|
56
|
+
* A `LinearFormStepper` driven by the nearest `StepProgressProvider`. Renders
|
|
57
|
+
* nothing until a step has been reported. Everything except the step itself
|
|
58
|
+
* (`onBack`, `color`, `headingLevel`, …) is passed as props.
|
|
59
|
+
*/
|
|
60
|
+
export declare const StepProgressHeader: (props: StepProgressHeaderProps) => import("react").JSX.Element | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type AppHeaderProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Shows the brand divider under the header. Without it, the header gets a
|
|
5
|
+
* bottom border instead.
|
|
6
|
+
* @default true
|
|
7
|
+
*/
|
|
8
|
+
brandDivider?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Lets the content span the full width instead of stopping at the `lg`
|
|
11
|
+
* breakpoint. The side padding stays.
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
fluid?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Content for the right-hand side, e.g. buttons. Without children the logo
|
|
17
|
+
* is centred.
|
|
18
|
+
*/
|
|
19
|
+
children?: ReactNode;
|
|
20
|
+
};
|
|
21
|
+
export declare const AppHeader: ({ brandDivider, fluid, children, }: AppHeaderProps) => import("react").JSX.Element;
|
|
@@ -3,4 +3,10 @@
|
|
|
3
3
|
* Brand Divider in Lea colors
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
6
|
+
export type BrandDividerProps = {
|
|
7
|
+
/**
|
|
8
|
+
* The size of the divider.
|
|
9
|
+
*/
|
|
10
|
+
size?: "sm" | "md" | "lg";
|
|
11
|
+
};
|
|
12
|
+
export declare const BrandDivider: ({ size }: BrandDividerProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ConsentState, CookieConsentCategory } from './constants';
|
|
2
|
+
import { CookieConsentCopy } from './copy';
|
|
3
|
+
import { ResolveHref } from './strapi-blocks';
|
|
4
|
+
export interface ConsentDialogProps {
|
|
5
|
+
open: boolean;
|
|
6
|
+
/** The stored choice. While `null`, the dialog can't be dismissed. */
|
|
7
|
+
consent: ConsentState | null;
|
|
8
|
+
copy: CookieConsentCopy;
|
|
9
|
+
resolveHref?: ResolveHref;
|
|
10
|
+
onAcceptAll: () => void;
|
|
11
|
+
onAcceptNecessary: () => void;
|
|
12
|
+
onSave: (categories: CookieConsentCategory[]) => void;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function ConsentDialog({ open, consent, copy, resolveHref, onAcceptAll, onAcceptNecessary, onSave, onClose, }: ConsentDialogProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bumping the revision invalidates every visitor's consent on every Lea Bank
|
|
3
|
+
* app at once. Only change it here, then release all apps together.
|
|
4
|
+
*/
|
|
5
|
+
export declare const COOKIE_CONSENT_REVISION = 3;
|
|
6
|
+
export declare const COOKIE_CONSENT_CATEGORIES: readonly ["necessary", "preferences", "analytics", "marketing"];
|
|
7
|
+
export type CookieConsentCategory = (typeof COOKIE_CONSENT_CATEGORIES)[number];
|
|
8
|
+
export type ConsentState = Record<CookieConsentCategory, boolean>;
|
|
9
|
+
export type Market = "se" | "fi" | "no" | "es";
|
|
10
|
+
export declare const MARKET_DOMAINS: Record<Market, string>;
|
|
11
|
+
export declare const COOKIE_NAME = "cc_cookie";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CookieConsentCategory } from './constants';
|
|
2
|
+
import { StrapiBlocksNode } from './strapi-blocks';
|
|
3
|
+
/** Consent copy as resolved by the app from Strapi, fallbacks applied. */
|
|
4
|
+
export interface CookieConsentCopy {
|
|
5
|
+
modalTitle: string;
|
|
6
|
+
intro: StrapiBlocksNode[];
|
|
7
|
+
policyLinkLabel: string;
|
|
8
|
+
policyLinkUrl: string;
|
|
9
|
+
btnAcceptAll: string;
|
|
10
|
+
btnAcceptNecessary: string;
|
|
11
|
+
btnSaveSettings: string;
|
|
12
|
+
/** Unused: the settings open directly, without a separate first modal. */
|
|
13
|
+
btnShowPreferences?: string;
|
|
14
|
+
closeIconLabel: string;
|
|
15
|
+
categories: Record<CookieConsentCategory, {
|
|
16
|
+
title: string;
|
|
17
|
+
description: string;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ConsentState, CookieConsentCategory, Market } from './constants';
|
|
2
|
+
export interface InitCookieConsentOptions {
|
|
3
|
+
market: Market;
|
|
4
|
+
/**
|
|
5
|
+
* Called with the visitor's choice once the library has loaded, when there
|
|
6
|
+
* is a valid consent, and again whenever the choice changes.
|
|
7
|
+
*/
|
|
8
|
+
onConsentChange?: (state: ConsentState) => void;
|
|
9
|
+
}
|
|
10
|
+
export interface ConsentSnapshot {
|
|
11
|
+
consent: ConsentState | null;
|
|
12
|
+
/** Whether the settings dialog should be shown. */
|
|
13
|
+
settingsOpen: boolean;
|
|
14
|
+
/** The stored consent has been read and the choice can be changed. */
|
|
15
|
+
ready: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** `null` on the server, before the visitor has chosen, or after a revision bump. */
|
|
18
|
+
export declare function getConsentState(): ConsentState | null;
|
|
19
|
+
/**
|
|
20
|
+
* Reads the shared consent and keeps it up to date. Only the first call has an
|
|
21
|
+
* effect, and it is a no-op on the server. It shows nothing by itself: the
|
|
22
|
+
* settings dialog is rendered by `CookieConsentProvider`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function initCookieConsent({ market, onConsentChange, }: InitCookieConsentOptions): void;
|
|
25
|
+
/**
|
|
26
|
+
* Stores the visitor's choice. `necessary` is always kept. Does nothing until
|
|
27
|
+
* `initCookieConsent` has read the stored consent.
|
|
28
|
+
*/
|
|
29
|
+
export declare function setConsent(categories: readonly CookieConsentCategory[] | "all"): void;
|
|
30
|
+
/** Opens the settings dialog of the mounted `CookieConsentProvider`. */
|
|
31
|
+
export declare function openCookieSettings(): void;
|
|
32
|
+
/** Closes the settings dialog, unless the visitor has yet to choose. */
|
|
33
|
+
export declare function closeCookieSettings(): void;
|
|
34
|
+
export declare function subscribe(listener: () => void): () => void;
|
|
35
|
+
export declare function getSnapshot(): ConsentSnapshot;
|
|
36
|
+
export declare function getServerSnapshot(): ConsentSnapshot;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Market } from './constants';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the market's registrable domain when the page is served from it or
|
|
4
|
+
* one of its subdomains. Anywhere else (localhost, `*.azurewebsites.net`,
|
|
5
|
+
* which is on the Public Suffix List) the browser would reject the cookie, so
|
|
6
|
+
* it stays host-only.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveCookieDomain(hostname: string, market: Market): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Erases a host-only consent cookie left by an earlier, domain-less setup.
|
|
11
|
+
* Without this it coexists with the domain cookie under the same name and a
|
|
12
|
+
* stale value can win. A cookie written without `domain` only matches the
|
|
13
|
+
* host-only one, so the shared cookie is kept.
|
|
14
|
+
*/
|
|
15
|
+
export declare function clearHostOnlyCookie(): void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { COOKIE_CONSENT_CATEGORIES, COOKIE_CONSENT_REVISION, type ConsentState, type CookieConsentCategory, type Market, } from './constants';
|
|
2
|
+
export type { CookieConsentCopy } from './copy';
|
|
3
|
+
export { getConsentState, initCookieConsent, openCookieSettings, setConsent, type InitCookieConsentOptions, } from './core';
|
|
4
|
+
export type { ResolveHref, StrapiBlocksNode, StrapiHeadingNode, StrapiInlineNode, StrapiLinkNode, StrapiListItemNode, StrapiListNode, StrapiParagraphNode, StrapiTextNode, } from './strapi-blocks';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ConsentState, Market } from './constants';
|
|
3
|
+
import { CookieConsentCopy } from './copy';
|
|
4
|
+
import { ResolveHref } from './strapi-blocks';
|
|
5
|
+
import "../theme/tokens.css";
|
|
6
|
+
export interface CookieConsentContextValue {
|
|
7
|
+
/** `null` until the visitor has made a valid choice, and on the server. */
|
|
8
|
+
consent: ConsentState | null;
|
|
9
|
+
openSettings: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface CookieConsentProviderProps {
|
|
12
|
+
market: Market;
|
|
13
|
+
copy: CookieConsentCopy;
|
|
14
|
+
/** Rewrites link URLs in the copy, e.g. to make CMS-relative paths absolute. */
|
|
15
|
+
resolveHref?: ResolveHref;
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Reads the shared consent after mount and renders the settings dialog, which
|
|
20
|
+
* opens by itself until the visitor has chosen. `market` is read once.
|
|
21
|
+
*/
|
|
22
|
+
export declare function CookieConsentProvider({ market, copy, resolveHref, children, }: CookieConsentProviderProps): import("react").JSX.Element;
|
|
23
|
+
export declare function useCookieConsent(): CookieConsentContextValue;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface StrapiTextNode {
|
|
3
|
+
type: "text";
|
|
4
|
+
text: string;
|
|
5
|
+
bold?: boolean;
|
|
6
|
+
italic?: boolean;
|
|
7
|
+
underline?: boolean;
|
|
8
|
+
strikethrough?: boolean;
|
|
9
|
+
code?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface StrapiLinkNode {
|
|
12
|
+
type: "link";
|
|
13
|
+
url: string;
|
|
14
|
+
children: StrapiTextNode[];
|
|
15
|
+
}
|
|
16
|
+
export type StrapiInlineNode = StrapiTextNode | StrapiLinkNode;
|
|
17
|
+
export interface StrapiParagraphNode {
|
|
18
|
+
type: "paragraph";
|
|
19
|
+
children: StrapiInlineNode[];
|
|
20
|
+
}
|
|
21
|
+
export interface StrapiHeadingNode {
|
|
22
|
+
type: "heading";
|
|
23
|
+
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
24
|
+
children: StrapiInlineNode[];
|
|
25
|
+
}
|
|
26
|
+
export interface StrapiListItemNode {
|
|
27
|
+
type: "list-item";
|
|
28
|
+
children: StrapiInlineNode[];
|
|
29
|
+
}
|
|
30
|
+
export interface StrapiListNode {
|
|
31
|
+
type: "list";
|
|
32
|
+
format: "ordered" | "unordered";
|
|
33
|
+
children: (StrapiListItemNode | StrapiListNode)[];
|
|
34
|
+
}
|
|
35
|
+
export type StrapiBlocksNode = StrapiParagraphNode | StrapiHeadingNode | StrapiListNode;
|
|
36
|
+
/**
|
|
37
|
+
* Rewrites a link's URL, e.g. to make CMS-relative paths absolute. Return
|
|
38
|
+
* `null` or `undefined` to render the link's label as plain text. The result
|
|
39
|
+
* must still be `https:`, `mailto:` or relative to become a link.
|
|
40
|
+
*/
|
|
41
|
+
export type ResolveHref = (href: string) => string | null | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Allows `https:`, `mailto:` and URLs relative to the current origin. The URL
|
|
44
|
+
* parser strips the whitespace and control characters browsers ignore, so
|
|
45
|
+
* `" javascript:"` and `"java\tscript:"` are caught, and a protocol-relative
|
|
46
|
+
* `//host` (or `/\host`) resolves to a foreign origin and is rejected.
|
|
47
|
+
*/
|
|
48
|
+
export declare function isSafeHref(href: string): boolean;
|
|
49
|
+
export interface SafeLinkProps {
|
|
50
|
+
href: string;
|
|
51
|
+
resolveHref?: ResolveHref;
|
|
52
|
+
children: ReactNode;
|
|
53
|
+
}
|
|
54
|
+
/** A new-tab link, or its label as plain text when the URL isn't allowed. */
|
|
55
|
+
export declare function SafeLink({ href, resolveHref, children, }: SafeLinkProps): import("react").JSX.Element;
|
|
56
|
+
export interface StrapiBlocksProps {
|
|
57
|
+
nodes: StrapiBlocksNode[];
|
|
58
|
+
resolveHref?: ResolveHref;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Renders Strapi Blocks rich text with only `p`, `strong`, `em`, `u`, `ul`,
|
|
62
|
+
* `ol`, `li` and `a`. Headings become a bold paragraph, so they can't break
|
|
63
|
+
* the dialog's heading order; any other node type is dropped.
|
|
64
|
+
*/
|
|
65
|
+
export declare function StrapiBlocks({ nodes, resolveHref }: StrapiBlocksProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));let c=require("vanilla-cookieconsent");c=s(c);var l=3,u=[`necessary`,`preferences`,`analytics`,`marketing`],d={se:`leabank.se`,fi:`leabank.fi`,no:`leabank.no`,es:`leabank.es`},f=`cc_cookie`;function p(e,t){let n=d[t],r=e.toLowerCase();return r===n||r.endsWith(`.${n}`)?n:void 0}function m(){document.cookie=`${f}=; path=/; max-age=0`}var h={consent:null,settingsOpen:!1,ready:!1},g=!1,_=h,v=new Set;function y(e){_={..._,...e},v.forEach(e=>e())}function b(){if(typeof window>`u`||!c.validConsent())return null;let e=new Set(c.getUserPreferences().acceptedCategories);return Object.fromEntries(u.map(t=>[t,e.has(t)]))}function x({market:e,onConsentChange:t}){if(typeof window>`u`||g)return;g=!0;let n=p(window.location.hostname,e);n&&m();let r=()=>{let e=b();y({consent:e}),e&&t?.(e)};c.run({root:document.createElement(`div`),autoShow:!1,language:{default:`en`,translations:{en:{consentModal:{},preferencesModal:{sections:[]}}}},revision:3,cookie:{name:f,sameSite:`Lax`,secure:!0,...n&&{domain:n}},categories:{necessary:{enabled:!0,readOnly:!0},preferences:{enabled:!1,readOnly:!1},analytics:{enabled:!1,readOnly:!1,autoClear:{cookies:[{name:/^(_ga|_gid|_gat)/}]}},marketing:{enabled:!1,readOnly:!1,autoClear:{cookies:[{name:/^(_fbp|_fbc)/},{name:/^(_gcl_)/}]}}},onFirstConsent:r,onChange:r}).then(()=>{let e=b();y({consent:e,ready:!0,settingsOpen:_.settingsOpen||e===null}),e&&t?.(e)})}function S(e){_.ready&&(c.acceptCategory(e===`all`?`all`:[`necessary`,...e.filter(e=>e!==`necessary`)]),y({consent:b(),settingsOpen:!1}))}function C(){typeof window>`u`||y({settingsOpen:!0})}function w(){_.consent!==null&&y({settingsOpen:!1})}function T(e){return v.add(e),()=>{v.delete(e)}}function E(){return _}function D(){return h}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return l}});
|
|
2
|
+
//# sourceMappingURL=cookie-consent-core-C4MP7GlV.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookie-consent-core-C4MP7GlV.cjs","names":[],"sources":["../src/cookie-consent/constants.ts","../src/cookie-consent/domain.ts","../src/cookie-consent/core.ts"],"sourcesContent":["/**\n * Bumping the revision invalidates every visitor's consent on every Lea Bank\n * app at once. Only change it here, then release all apps together.\n */\nexport const COOKIE_CONSENT_REVISION = 3;\n\nexport const COOKIE_CONSENT_CATEGORIES = [\n \"necessary\",\n \"preferences\",\n \"analytics\",\n \"marketing\",\n] as const;\n\nexport type CookieConsentCategory = (typeof COOKIE_CONSENT_CATEGORIES)[number];\n\nexport type ConsentState = Record<CookieConsentCategory, boolean>;\n\nexport type Market = \"se\" | \"fi\" | \"no\" | \"es\";\n\nexport const MARKET_DOMAINS: Record<Market, string> = {\n se: \"leabank.se\",\n fi: \"leabank.fi\",\n no: \"leabank.no\",\n es: \"leabank.es\",\n};\n\nexport const COOKIE_NAME = \"cc_cookie\";\n","import { COOKIE_NAME, MARKET_DOMAINS, type Market } from \"./constants\";\n\n/**\n * Returns the market's registrable domain when the page is served from it or\n * one of its subdomains. Anywhere else (localhost, `*.azurewebsites.net`,\n * which is on the Public Suffix List) the browser would reject the cookie, so\n * it stays host-only.\n */\nexport function resolveCookieDomain(\n hostname: string,\n market: Market,\n): string | undefined {\n const domain = MARKET_DOMAINS[market];\n const host = hostname.toLowerCase();\n\n return host === domain || host.endsWith(`.${domain}`) ? domain : undefined;\n}\n\n/**\n * Erases a host-only consent cookie left by an earlier, domain-less setup.\n * Without this it coexists with the domain cookie under the same name and a\n * stale value can win. A cookie written without `domain` only matches the\n * host-only one, so the shared cookie is kept.\n */\nexport function clearHostOnlyCookie(): void {\n document.cookie = `${COOKIE_NAME}=; path=/; max-age=0`;\n}\n","import * as CookieConsent from \"vanilla-cookieconsent\";\n\nimport {\n COOKIE_CONSENT_CATEGORIES,\n COOKIE_CONSENT_REVISION,\n COOKIE_NAME,\n type ConsentState,\n type CookieConsentCategory,\n type Market,\n} from \"./constants\";\nimport { clearHostOnlyCookie, resolveCookieDomain } from \"./domain\";\n\nexport interface InitCookieConsentOptions {\n market: Market;\n /**\n * Called with the visitor's choice once the library has loaded, when there\n * is a valid consent, and again whenever the choice changes.\n */\n onConsentChange?: (state: ConsentState) => void;\n}\n\nexport interface ConsentSnapshot {\n consent: ConsentState | null;\n /** Whether the settings dialog should be shown. */\n settingsOpen: boolean;\n /** The stored consent has been read and the choice can be changed. */\n ready: boolean;\n}\n\nconst serverSnapshot: ConsentSnapshot = {\n consent: null,\n settingsOpen: false,\n ready: false,\n};\n\nlet started = false;\nlet snapshot = serverSnapshot;\nconst listeners = new Set<() => void>();\n\nfunction update(patch: Partial<ConsentSnapshot>) {\n snapshot = { ...snapshot, ...patch };\n listeners.forEach((listener) => listener());\n}\n\n/** `null` on the server, before the visitor has chosen, or after a revision bump. */\nexport function getConsentState(): ConsentState | null {\n if (typeof window === \"undefined\" || !CookieConsent.validConsent()) {\n return null;\n }\n\n const accepted = new Set(CookieConsent.getUserPreferences().acceptedCategories);\n return Object.fromEntries(\n COOKIE_CONSENT_CATEGORIES.map((category) => [category, accepted.has(category)]),\n ) as ConsentState;\n}\n\n/**\n * Reads the shared consent and keeps it up to date. Only the first call has an\n * effect, and it is a no-op on the server. It shows nothing by itself: the\n * settings dialog is rendered by `CookieConsentProvider`.\n */\nexport function initCookieConsent({\n market,\n onConsentChange,\n}: InitCookieConsentOptions): void {\n if (typeof window === \"undefined\" || started) return;\n started = true;\n\n const domain = resolveCookieDomain(window.location.hostname, market);\n if (domain) clearHostOnlyCookie();\n\n const applyConsent = () => {\n const consent = getConsentState();\n update({ consent });\n if (consent) onConsentChange?.(consent);\n };\n\n // The full build with its UI unused: `run` still builds an empty consent\n // modal when consent is missing, so it goes into a detached `root` that never\n // reaches the page. The UI-less core build of 3.1.0 can't be used, because\n // its `run` throws.\n void CookieConsent.run({\n root: document.createElement(\"div\"),\n autoShow: false,\n language: {\n default: \"en\",\n translations: { en: { consentModal: {}, preferencesModal: { sections: [] } } },\n },\n revision: COOKIE_CONSENT_REVISION,\n cookie: {\n name: COOKIE_NAME,\n sameSite: \"Lax\",\n secure: true,\n ...(domain && { domain }),\n },\n categories: {\n necessary: { enabled: true, readOnly: true },\n preferences: { enabled: false, readOnly: false },\n analytics: {\n enabled: false,\n readOnly: false,\n autoClear: { cookies: [{ name: /^(_ga|_gid|_gat)/ }] },\n },\n marketing: {\n enabled: false,\n readOnly: false,\n autoClear: {\n cookies: [{ name: /^(_fbp|_fbc)/ }, { name: /^(_gcl_)/ }],\n },\n },\n },\n onFirstConsent: applyConsent,\n onChange: applyConsent,\n }).then(() => {\n const consent = getConsentState();\n update({\n consent,\n ready: true,\n settingsOpen: snapshot.settingsOpen || consent === null,\n });\n if (consent) onConsentChange?.(consent);\n });\n}\n\n/**\n * Stores the visitor's choice. `necessary` is always kept. Does nothing until\n * `initCookieConsent` has read the stored consent.\n */\nexport function setConsent(\n categories: readonly CookieConsentCategory[] | \"all\",\n): void {\n if (!snapshot.ready) return;\n\n CookieConsent.acceptCategory(\n categories === \"all\"\n ? \"all\"\n : [\"necessary\", ...categories.filter((category) => category !== \"necessary\")],\n );\n update({ consent: getConsentState(), settingsOpen: false });\n}\n\n/** Opens the settings dialog of the mounted `CookieConsentProvider`. */\nexport function openCookieSettings(): void {\n if (typeof window === \"undefined\") return;\n update({ settingsOpen: true });\n}\n\n/** Closes the settings dialog, unless the visitor has yet to choose. */\nexport function closeCookieSettings(): void {\n if (snapshot.consent === null) return;\n update({ settingsOpen: false });\n}\n\nexport function subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function getSnapshot(): ConsentSnapshot {\n return snapshot;\n}\n\nexport function getServerSnapshot(): ConsentSnapshot {\n return serverSnapshot;\n}\n"],"mappings":"kiBAIA,IAAa,EAA0B,EAE1B,EAA4B,CACvC,YACA,cACA,YACA,WACF,EAQa,EAAyC,CACpD,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,YACN,EAEa,EAAc,YClB3B,SAAgB,EACd,EACA,EACoB,CACpB,IAAM,EAAS,EAAe,GACxB,EAAO,EAAS,YAAY,EAElC,OAAO,IAAS,GAAU,EAAK,SAAS,IAAI,GAAQ,EAAI,EAAS,IAAA,EACnE,CAQA,SAAgB,GAA4B,CAC1C,SAAS,OAAS,GAAG,EAAY,qBACnC,CCGA,IAAM,EAAkC,CACtC,QAAS,KACT,aAAc,GACd,MAAO,EACT,EAEI,EAAU,GACV,EAAW,EACT,EAAY,IAAI,IAEtB,SAAS,EAAO,EAAiC,CAC/C,EAAW,CAAE,GAAG,EAAU,GAAG,CAAM,EACnC,EAAU,QAAS,GAAa,EAAS,CAAC,CAC5C,CAGA,SAAgB,GAAuC,CACrD,GAAI,OAAO,OAAW,KAAe,CAAC,EAAc,aAAa,EAC/D,OAAO,KAGT,IAAM,EAAW,IAAI,IAAI,EAAc,mBAAmB,CAAC,CAAC,kBAAkB,EAC9E,OAAO,OAAO,YACZ,EAA0B,IAAK,GAAa,CAAC,EAAU,EAAS,IAAI,CAAQ,CAAC,CAAC,CAChF,CACF,CAOA,SAAgB,EAAkB,CAChC,SACA,mBACiC,CACjC,GAAI,OAAO,OAAW,KAAe,EAAS,OAC9C,EAAU,GAEV,IAAM,EAAS,EAAoB,OAAO,SAAS,SAAU,CAAM,EAC/D,GAAQ,EAAoB,EAEhC,IAAM,MAAqB,CACzB,IAAM,EAAU,EAAgB,EAChC,EAAO,CAAE,SAAQ,CAAC,EACd,GAAS,IAAkB,CAAO,CACxC,EAMA,EAAmB,IAAI,CACrB,KAAM,SAAS,cAAc,KAAK,EAClC,SAAU,GACV,SAAU,CACR,QAAS,KACT,aAAc,CAAE,GAAI,CAAE,aAAc,CAAC,EAAG,iBAAkB,CAAE,SAAU,CAAC,CAAE,CAAE,CAAE,CAC/E,EACA,SAAA,EACA,OAAQ,CACN,KAAM,EACN,SAAU,MACV,OAAQ,GACR,GAAI,GAAU,CAAE,QAAO,CACzB,EACA,WAAY,CACV,UAAW,CAAE,QAAS,GAAM,SAAU,EAAK,EAC3C,YAAa,CAAE,QAAS,GAAO,SAAU,EAAM,EAC/C,UAAW,CACT,QAAS,GACT,SAAU,GACV,UAAW,CAAE,QAAS,CAAC,CAAE,KAAM,kBAAmB,CAAC,CAAE,CACvD,EACA,UAAW,CACT,QAAS,GACT,SAAU,GACV,UAAW,CACT,QAAS,CAAC,CAAE,KAAM,cAAe,EAAG,CAAE,KAAM,UAAW,CAAC,CAC1D,CACF,CACF,EACA,eAAgB,EAChB,SAAU,CACZ,CAAC,CAAC,CAAC,SAAW,CACZ,IAAM,EAAU,EAAgB,EAChC,EAAO,CACL,UACA,MAAO,GACP,aAAc,EAAS,cAAgB,IAAY,IACrD,CAAC,EACG,GAAS,IAAkB,CAAO,CACxC,CAAC,CACH,CAMA,SAAgB,EACd,EACM,CACD,EAAS,QAEd,EAAc,eACZ,IAAe,MACX,MACA,CAAC,YAAa,GAAG,EAAW,OAAQ,GAAa,IAAa,WAAW,CAAC,CAChF,EACA,EAAO,CAAE,QAAS,EAAgB,EAAG,aAAc,EAAM,CAAC,EAC5D,CAGA,SAAgB,GAA2B,CACrC,OAAO,OAAW,KACtB,EAAO,CAAE,aAAc,EAAK,CAAC,CAC/B,CAGA,SAAgB,GAA4B,CACtC,EAAS,UAAY,MACzB,EAAO,CAAE,aAAc,EAAM,CAAC,CAChC,CAEA,SAAgB,EAAU,EAAkC,CAE1D,OADA,EAAU,IAAI,CAAQ,MACT,CACX,EAAU,OAAO,CAAQ,CAC3B,CACF,CAEA,SAAgB,GAA+B,CAC7C,OAAO,CACT,CAEA,SAAgB,GAAqC,CACnD,OAAO,CACT"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as e from "vanilla-cookieconsent";
|
|
2
|
+
//#region src/cookie-consent/constants.ts
|
|
3
|
+
var t = 3, n = [
|
|
4
|
+
"necessary",
|
|
5
|
+
"preferences",
|
|
6
|
+
"analytics",
|
|
7
|
+
"marketing"
|
|
8
|
+
], r = {
|
|
9
|
+
se: "leabank.se",
|
|
10
|
+
fi: "leabank.fi",
|
|
11
|
+
no: "leabank.no",
|
|
12
|
+
es: "leabank.es"
|
|
13
|
+
}, i = "cc_cookie";
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/cookie-consent/domain.ts
|
|
16
|
+
function a(e, t) {
|
|
17
|
+
let n = r[t], i = e.toLowerCase();
|
|
18
|
+
return i === n || i.endsWith(`.${n}`) ? n : void 0;
|
|
19
|
+
}
|
|
20
|
+
function o() {
|
|
21
|
+
document.cookie = `${i}=; path=/; max-age=0`;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/cookie-consent/core.ts
|
|
25
|
+
var s = {
|
|
26
|
+
consent: null,
|
|
27
|
+
settingsOpen: !1,
|
|
28
|
+
ready: !1
|
|
29
|
+
}, c = !1, l = s, u = /* @__PURE__ */ new Set();
|
|
30
|
+
function d(e) {
|
|
31
|
+
l = {
|
|
32
|
+
...l,
|
|
33
|
+
...e
|
|
34
|
+
}, u.forEach((e) => e());
|
|
35
|
+
}
|
|
36
|
+
function f() {
|
|
37
|
+
if (typeof window > "u" || !e.validConsent()) return null;
|
|
38
|
+
let t = new Set(e.getUserPreferences().acceptedCategories);
|
|
39
|
+
return Object.fromEntries(n.map((e) => [e, t.has(e)]));
|
|
40
|
+
}
|
|
41
|
+
function p({ market: t, onConsentChange: n }) {
|
|
42
|
+
if (typeof window > "u" || c) return;
|
|
43
|
+
c = !0;
|
|
44
|
+
let r = a(window.location.hostname, t);
|
|
45
|
+
r && o();
|
|
46
|
+
let s = () => {
|
|
47
|
+
let e = f();
|
|
48
|
+
d({ consent: e }), e && n?.(e);
|
|
49
|
+
};
|
|
50
|
+
e.run({
|
|
51
|
+
root: document.createElement("div"),
|
|
52
|
+
autoShow: !1,
|
|
53
|
+
language: {
|
|
54
|
+
default: "en",
|
|
55
|
+
translations: { en: {
|
|
56
|
+
consentModal: {},
|
|
57
|
+
preferencesModal: { sections: [] }
|
|
58
|
+
} }
|
|
59
|
+
},
|
|
60
|
+
revision: 3,
|
|
61
|
+
cookie: {
|
|
62
|
+
name: i,
|
|
63
|
+
sameSite: "Lax",
|
|
64
|
+
secure: !0,
|
|
65
|
+
...r && { domain: r }
|
|
66
|
+
},
|
|
67
|
+
categories: {
|
|
68
|
+
necessary: {
|
|
69
|
+
enabled: !0,
|
|
70
|
+
readOnly: !0
|
|
71
|
+
},
|
|
72
|
+
preferences: {
|
|
73
|
+
enabled: !1,
|
|
74
|
+
readOnly: !1
|
|
75
|
+
},
|
|
76
|
+
analytics: {
|
|
77
|
+
enabled: !1,
|
|
78
|
+
readOnly: !1,
|
|
79
|
+
autoClear: { cookies: [{ name: /^(_ga|_gid|_gat)/ }] }
|
|
80
|
+
},
|
|
81
|
+
marketing: {
|
|
82
|
+
enabled: !1,
|
|
83
|
+
readOnly: !1,
|
|
84
|
+
autoClear: { cookies: [{ name: /^(_fbp|_fbc)/ }, { name: /^(_gcl_)/ }] }
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
onFirstConsent: s,
|
|
88
|
+
onChange: s
|
|
89
|
+
}).then(() => {
|
|
90
|
+
let e = f();
|
|
91
|
+
d({
|
|
92
|
+
consent: e,
|
|
93
|
+
ready: !0,
|
|
94
|
+
settingsOpen: l.settingsOpen || e === null
|
|
95
|
+
}), e && n?.(e);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function m(t) {
|
|
99
|
+
l.ready && (e.acceptCategory(t === "all" ? "all" : ["necessary", ...t.filter((e) => e !== "necessary")]), d({
|
|
100
|
+
consent: f(),
|
|
101
|
+
settingsOpen: !1
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
function h() {
|
|
105
|
+
typeof window > "u" || d({ settingsOpen: !0 });
|
|
106
|
+
}
|
|
107
|
+
function g() {
|
|
108
|
+
l.consent !== null && d({ settingsOpen: !1 });
|
|
109
|
+
}
|
|
110
|
+
function _(e) {
|
|
111
|
+
return u.add(e), () => {
|
|
112
|
+
u.delete(e);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function v() {
|
|
116
|
+
return l;
|
|
117
|
+
}
|
|
118
|
+
function y() {
|
|
119
|
+
return s;
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
export { p as a, _ as c, v as i, n as l, f as n, h as o, y as r, m as s, g as t, t as u };
|
|
123
|
+
|
|
124
|
+
//# sourceMappingURL=cookie-consent-core-mwVmy5nZ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookie-consent-core-mwVmy5nZ.mjs","names":[],"sources":["../src/cookie-consent/constants.ts","../src/cookie-consent/domain.ts","../src/cookie-consent/core.ts"],"sourcesContent":["/**\n * Bumping the revision invalidates every visitor's consent on every Lea Bank\n * app at once. Only change it here, then release all apps together.\n */\nexport const COOKIE_CONSENT_REVISION = 3;\n\nexport const COOKIE_CONSENT_CATEGORIES = [\n \"necessary\",\n \"preferences\",\n \"analytics\",\n \"marketing\",\n] as const;\n\nexport type CookieConsentCategory = (typeof COOKIE_CONSENT_CATEGORIES)[number];\n\nexport type ConsentState = Record<CookieConsentCategory, boolean>;\n\nexport type Market = \"se\" | \"fi\" | \"no\" | \"es\";\n\nexport const MARKET_DOMAINS: Record<Market, string> = {\n se: \"leabank.se\",\n fi: \"leabank.fi\",\n no: \"leabank.no\",\n es: \"leabank.es\",\n};\n\nexport const COOKIE_NAME = \"cc_cookie\";\n","import { COOKIE_NAME, MARKET_DOMAINS, type Market } from \"./constants\";\n\n/**\n * Returns the market's registrable domain when the page is served from it or\n * one of its subdomains. Anywhere else (localhost, `*.azurewebsites.net`,\n * which is on the Public Suffix List) the browser would reject the cookie, so\n * it stays host-only.\n */\nexport function resolveCookieDomain(\n hostname: string,\n market: Market,\n): string | undefined {\n const domain = MARKET_DOMAINS[market];\n const host = hostname.toLowerCase();\n\n return host === domain || host.endsWith(`.${domain}`) ? domain : undefined;\n}\n\n/**\n * Erases a host-only consent cookie left by an earlier, domain-less setup.\n * Without this it coexists with the domain cookie under the same name and a\n * stale value can win. A cookie written without `domain` only matches the\n * host-only one, so the shared cookie is kept.\n */\nexport function clearHostOnlyCookie(): void {\n document.cookie = `${COOKIE_NAME}=; path=/; max-age=0`;\n}\n","import * as CookieConsent from \"vanilla-cookieconsent\";\n\nimport {\n COOKIE_CONSENT_CATEGORIES,\n COOKIE_CONSENT_REVISION,\n COOKIE_NAME,\n type ConsentState,\n type CookieConsentCategory,\n type Market,\n} from \"./constants\";\nimport { clearHostOnlyCookie, resolveCookieDomain } from \"./domain\";\n\nexport interface InitCookieConsentOptions {\n market: Market;\n /**\n * Called with the visitor's choice once the library has loaded, when there\n * is a valid consent, and again whenever the choice changes.\n */\n onConsentChange?: (state: ConsentState) => void;\n}\n\nexport interface ConsentSnapshot {\n consent: ConsentState | null;\n /** Whether the settings dialog should be shown. */\n settingsOpen: boolean;\n /** The stored consent has been read and the choice can be changed. */\n ready: boolean;\n}\n\nconst serverSnapshot: ConsentSnapshot = {\n consent: null,\n settingsOpen: false,\n ready: false,\n};\n\nlet started = false;\nlet snapshot = serverSnapshot;\nconst listeners = new Set<() => void>();\n\nfunction update(patch: Partial<ConsentSnapshot>) {\n snapshot = { ...snapshot, ...patch };\n listeners.forEach((listener) => listener());\n}\n\n/** `null` on the server, before the visitor has chosen, or after a revision bump. */\nexport function getConsentState(): ConsentState | null {\n if (typeof window === \"undefined\" || !CookieConsent.validConsent()) {\n return null;\n }\n\n const accepted = new Set(CookieConsent.getUserPreferences().acceptedCategories);\n return Object.fromEntries(\n COOKIE_CONSENT_CATEGORIES.map((category) => [category, accepted.has(category)]),\n ) as ConsentState;\n}\n\n/**\n * Reads the shared consent and keeps it up to date. Only the first call has an\n * effect, and it is a no-op on the server. It shows nothing by itself: the\n * settings dialog is rendered by `CookieConsentProvider`.\n */\nexport function initCookieConsent({\n market,\n onConsentChange,\n}: InitCookieConsentOptions): void {\n if (typeof window === \"undefined\" || started) return;\n started = true;\n\n const domain = resolveCookieDomain(window.location.hostname, market);\n if (domain) clearHostOnlyCookie();\n\n const applyConsent = () => {\n const consent = getConsentState();\n update({ consent });\n if (consent) onConsentChange?.(consent);\n };\n\n // The full build with its UI unused: `run` still builds an empty consent\n // modal when consent is missing, so it goes into a detached `root` that never\n // reaches the page. The UI-less core build of 3.1.0 can't be used, because\n // its `run` throws.\n void CookieConsent.run({\n root: document.createElement(\"div\"),\n autoShow: false,\n language: {\n default: \"en\",\n translations: { en: { consentModal: {}, preferencesModal: { sections: [] } } },\n },\n revision: COOKIE_CONSENT_REVISION,\n cookie: {\n name: COOKIE_NAME,\n sameSite: \"Lax\",\n secure: true,\n ...(domain && { domain }),\n },\n categories: {\n necessary: { enabled: true, readOnly: true },\n preferences: { enabled: false, readOnly: false },\n analytics: {\n enabled: false,\n readOnly: false,\n autoClear: { cookies: [{ name: /^(_ga|_gid|_gat)/ }] },\n },\n marketing: {\n enabled: false,\n readOnly: false,\n autoClear: {\n cookies: [{ name: /^(_fbp|_fbc)/ }, { name: /^(_gcl_)/ }],\n },\n },\n },\n onFirstConsent: applyConsent,\n onChange: applyConsent,\n }).then(() => {\n const consent = getConsentState();\n update({\n consent,\n ready: true,\n settingsOpen: snapshot.settingsOpen || consent === null,\n });\n if (consent) onConsentChange?.(consent);\n });\n}\n\n/**\n * Stores the visitor's choice. `necessary` is always kept. Does nothing until\n * `initCookieConsent` has read the stored consent.\n */\nexport function setConsent(\n categories: readonly CookieConsentCategory[] | \"all\",\n): void {\n if (!snapshot.ready) return;\n\n CookieConsent.acceptCategory(\n categories === \"all\"\n ? \"all\"\n : [\"necessary\", ...categories.filter((category) => category !== \"necessary\")],\n );\n update({ consent: getConsentState(), settingsOpen: false });\n}\n\n/** Opens the settings dialog of the mounted `CookieConsentProvider`. */\nexport function openCookieSettings(): void {\n if (typeof window === \"undefined\") return;\n update({ settingsOpen: true });\n}\n\n/** Closes the settings dialog, unless the visitor has yet to choose. */\nexport function closeCookieSettings(): void {\n if (snapshot.consent === null) return;\n update({ settingsOpen: false });\n}\n\nexport function subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function getSnapshot(): ConsentSnapshot {\n return snapshot;\n}\n\nexport function getServerSnapshot(): ConsentSnapshot {\n return serverSnapshot;\n}\n"],"mappings":";;AAIA,IAAa,IAA0B,GAE1B,IAA4B;CACvC;CACA;CACA;CACA;AACF,GAQa,IAAyC;CACpD,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEa,IAAc;;;AClB3B,SAAgB,EACd,GACA,GACoB;CACpB,IAAM,IAAS,EAAe,IACxB,IAAO,EAAS,YAAY;CAElC,OAAO,MAAS,KAAU,EAAK,SAAS,IAAI,GAAQ,IAAI,IAAS,KAAA;AACnE;AAQA,SAAgB,IAA4B;CAC1C,SAAS,SAAS,GAAG,EAAY;AACnC;;;ACGA,IAAM,IAAkC;CACtC,SAAS;CACT,cAAc;CACd,OAAO;AACT,GAEI,IAAU,IACV,IAAW,GACT,oBAAY,IAAI,IAAgB;AAEtC,SAAS,EAAO,GAAiC;CAE/C,AADA,IAAW;EAAE,GAAG;EAAU,GAAG;CAAM,GACnC,EAAU,SAAS,MAAa,EAAS,CAAC;AAC5C;AAGA,SAAgB,IAAuC;CACrD,IAAI,OAAO,SAAW,OAAe,CAAC,EAAc,aAAa,GAC/D,OAAO;CAGT,IAAM,IAAW,IAAI,IAAI,EAAc,mBAAmB,CAAC,CAAC,kBAAkB;CAC9E,OAAO,OAAO,YACZ,EAA0B,KAAK,MAAa,CAAC,GAAU,EAAS,IAAI,CAAQ,CAAC,CAAC,CAChF;AACF;AAOA,SAAgB,EAAkB,EAChC,WACA,sBACiC;CACjC,IAAI,OAAO,SAAW,OAAe,GAAS;CAC9C,IAAU;CAEV,IAAM,IAAS,EAAoB,OAAO,SAAS,UAAU,CAAM;CACnE,AAAI,KAAQ,EAAoB;CAEhC,IAAM,UAAqB;EACzB,IAAM,IAAU,EAAgB;EAEhC,AADA,EAAO,EAAE,WAAQ,CAAC,GACd,KAAS,IAAkB,CAAO;CACxC;CAMA,EAAmB,IAAI;EACrB,MAAM,SAAS,cAAc,KAAK;EAClC,UAAU;EACV,UAAU;GACR,SAAS;GACT,cAAc,EAAE,IAAI;IAAE,cAAc,CAAC;IAAG,kBAAkB,EAAE,UAAU,CAAC,EAAE;GAAE,EAAE;EAC/E;EACA,UAAA;EACA,QAAQ;GACN,MAAM;GACN,UAAU;GACV,QAAQ;GACR,GAAI,KAAU,EAAE,UAAO;EACzB;EACA,YAAY;GACV,WAAW;IAAE,SAAS;IAAM,UAAU;GAAK;GAC3C,aAAa;IAAE,SAAS;IAAO,UAAU;GAAM;GAC/C,WAAW;IACT,SAAS;IACT,UAAU;IACV,WAAW,EAAE,SAAS,CAAC,EAAE,MAAM,mBAAmB,CAAC,EAAE;GACvD;GACA,WAAW;IACT,SAAS;IACT,UAAU;IACV,WAAW,EACT,SAAS,CAAC,EAAE,MAAM,eAAe,GAAG,EAAE,MAAM,WAAW,CAAC,EAC1D;GACF;EACF;EACA,gBAAgB;EAChB,UAAU;CACZ,CAAC,CAAC,CAAC,WAAW;EACZ,IAAM,IAAU,EAAgB;EAMhC,AALA,EAAO;GACL;GACA,OAAO;GACP,cAAc,EAAS,gBAAgB,MAAY;EACrD,CAAC,GACG,KAAS,IAAkB,CAAO;CACxC,CAAC;AACH;AAMA,SAAgB,EACd,GACM;CACD,EAAS,UAEd,EAAc,eACZ,MAAe,QACX,QACA,CAAC,aAAa,GAAG,EAAW,QAAQ,MAAa,MAAa,WAAW,CAAC,CAChF,GACA,EAAO;EAAE,SAAS,EAAgB;EAAG,cAAc;CAAM,CAAC;AAC5D;AAGA,SAAgB,IAA2B;CACrC,OAAO,SAAW,OACtB,EAAO,EAAE,cAAc,GAAK,CAAC;AAC/B;AAGA,SAAgB,IAA4B;CACtC,EAAS,YAAY,QACzB,EAAO,EAAE,cAAc,GAAM,CAAC;AAChC;AAEA,SAAgB,EAAU,GAAkC;CAE1D,OADA,EAAU,IAAI,CAAQ,SACT;EACX,EAAU,OAAO,CAAQ;CAC3B;AACF;AAEA,SAAgB,IAA+B;CAC7C,OAAO;AACT;AAEA,SAAgB,IAAqC;CACnD,OAAO;AACT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});require('./cookie-consent.css');const e=require("./cookie-consent-core-C4MP7GlV.cjs");let t=require("react"),n=require("@base-ui/react/button"),r=require("@base-ui/react/use-render"),i=require("react/jsx-runtime"),a=require("@base-ui/react/dialog"),o=require("lucide-react"),s=require("@base-ui/react/switch"),c=require("@base-ui/react/accordion");var l=(e,t)=>n=>[e,typeof t==`function`?t(n):t].filter(Boolean).join(` `),u={Button:`_Button_sgjjo_9`,IconButton:`_IconButton_sgjjo_140`,Spinner:`_Spinner_sgjjo_167`,"button-spin":`_button-spin_sgjjo_1`,SrOnly:`_SrOnly_sgjjo_185`},d=e=>(0,t.isValidElement)(e)&&(e.props.href!=null||e.props.to!=null),f=e=>e.preventDefault(),p=(0,t.forwardRef)(function({variant:e=`solid`,color:t=`accent`,size:a=`md`,loading:o=!1,disabled:s,className:c,render:p,nativeButton:m,focusableWhenDisabled:h,...g},_){let v=!!(s||o),y=d(p),b={"aria-busy":o||void 0,"data-variant":e,"data-color":t,"data-size":a,"data-loading":o||void 0};return(0,r.useRender)({enabled:y,render:y?p:void 0,ref:_,defaultTagName:`a`,props:{...g,...b,"aria-disabled":v||void 0,"data-disabled":v?``:void 0,className:l(u.Button,c)({disabled:v}),onClick:v?f:g.onClick}})||(0,i.jsx)(n.Button,{...g,...b,ref:_,render:p,nativeButton:m,focusableWhenDisabled:h,disabled:v,className:l(u.Button,c)})}),m=(0,t.forwardRef)(function({startIcon:e,endIcon:t,loading:n=!1,loadingLabel:r,children:a,...o},s){return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(p,{...o,ref:s,loading:n,"data-start-icon":n||e!=null||void 0,"data-end-icon":t!=null||void 0,children:[n?(0,i.jsx)(`span`,{className:u.Spinner,"aria-hidden":!0}):e,a,t]}),r!=null&&(0,i.jsx)(`span`,{role:`status`,className:u.SrOnly,children:n?r:null})]})}),h={Backdrop:`_Backdrop_1tudt_8`,Viewport:`_Viewport_1tudt_22`,Popup:`_Popup_1tudt_38`,Header:`_Header_1tudt_78`,Title:`_Title_1tudt_88`,Description:`_Description_1tudt_96`,Content:`_Content_1tudt_110`,Footer:`_Footer_1tudt_118`,CloseButton:`_CloseButton_1tudt_134`},g=(0,t.createContext)(`no`),_=()=>(0,t.useContext)(g);function v(e){return function(){let t=_(),n={};return Object.keys(e).forEach(r=>{let i=e[r];n[r]=i[t]??i.no}),n}}var y=v({close:{no:`Lukk`,se:`Stäng`,fi:`Sulje`,es:`Cerrar`}}),b=a.Dialog.Root;a.Dialog.Trigger;var x=a.Dialog.Portal;function S({className:e,...t}){return(0,i.jsx)(a.Dialog.Backdrop,{...t,className:l(h.Backdrop,e)})}function C({className:e,...t}){return(0,i.jsx)(a.Dialog.Viewport,{...t,className:l(h.Viewport,e)})}function w({size:e=`sm`,fullScreenOnMobile:t,className:n,...r}){return(0,i.jsx)(a.Dialog.Popup,{...r,"data-size":e,"data-full-screen-on-mobile":t||void 0,className:l(h.Popup,n)})}function T({className:e,...t}){return(0,i.jsx)(`div`,{...t,className:[h.Header,e].filter(Boolean).join(` `)})}function E({className:e,...t}){return(0,i.jsx)(a.Dialog.Title,{...t,className:l(h.Title,e)})}function D({className:e,...t}){return(0,i.jsx)(a.Dialog.Description,{...t,className:l(h.Description,e)})}function O({className:e,...t}){return(0,i.jsx)(`div`,{...t,className:[h.Content,e].filter(Boolean).join(` `)})}function k({className:e,...t}){return(0,i.jsx)(`div`,{...t,className:[h.Footer,e].filter(Boolean).join(` `)})}a.Dialog.Close;function A({label:e,className:t,...n}){let r=y();return(0,i.jsx)(a.Dialog.Close,{...n,"aria-label":e??r.close,className:l(h.CloseButton,t),children:(0,i.jsx)(o.X,{size:20,"aria-hidden":!0})})}var j={Switch:`_Switch_d3xdl_7`,Thumb:`_Thumb_d3xdl_36`};function M({className:e,...t}){return(0,i.jsx)(s.Switch.Root,{...t,className:l(j.Switch,e),children:(0,i.jsx)(s.Switch.Thumb,{className:j.Thumb})})}var N={Root:`_Root_i17mg_13`,Item:`_Item_i17mg_10`,Header:`_Header_i17mg_10`,Trigger:`_Trigger_i17mg_95`,Label:`_Label_i17mg_135`,Icon:`_Icon_i17mg_139`,Panel:`_Panel_i17mg_157`,Content:`_Content_i17mg_168`};function P({variant:e=`outline`,iconPosition:t=`end`,className:n,...r}){return(0,i.jsx)(c.Accordion.Root,{...r,"data-variant":e,"data-icon-position":t,className:l(N.Root,n)})}function F({className:e,...t}){return(0,i.jsx)(c.Accordion.Item,{...t,className:l(N.Item,e)})}function I({className:e,...t}){return(0,i.jsx)(c.Accordion.Header,{...t,className:l(N.Header,e)})}function L({children:e,className:t,...n}){return(0,i.jsxs)(c.Accordion.Trigger,{...n,className:l(N.Trigger,t),children:[(0,i.jsx)(`span`,{className:N.Label,children:e}),(0,i.jsx)(o.ChevronDown,{className:N.Icon,size:20,"aria-hidden":!0})]})}function R({children:e,className:t,...n}){return(0,i.jsx)(c.Accordion.Panel,{...n,className:l(N.Panel,t),children:(0,i.jsx)(`div`,{className:N.Content,children:e})})}var z={Intro:`_Intro_1lxh4_7`,Categories:`_Categories_1lxh4_39`,CategoryDescription:`_CategoryDescription_1lxh4_43`,Actions:`_Actions_1lxh4_49`,Save:`_Save_1lxh4_60`},B=`https://relative.invalid`;function V(e,t){try{return new URL(e,t)}catch{return null}}function H(e){let t=e.trim();if(!t)return!1;let n=V(t);return n?n.protocol===`https:`||n.protocol===`mailto:`:V(t,B)?.origin===B}function U({href:e,resolveHref:t=e=>e,children:n}){let r=t(e);return!r||!H(r)?(0,i.jsx)(i.Fragment,{children:n}):(0,i.jsx)(`a`,{href:r.trim(),target:`_blank`,rel:`noopener noreferrer`,children:n})}function W({node:e}){let t=e.text;return e.underline&&(t=(0,i.jsx)(`u`,{children:t})),e.italic&&(t=(0,i.jsx)(`em`,{children:t})),e.bold&&(t=(0,i.jsx)(`strong`,{children:t})),(0,i.jsx)(i.Fragment,{children:t})}function G({nodes:e,resolveHref:t}){return(0,i.jsx)(i.Fragment,{children:(e??[]).map((e,n)=>e.type===`text`?(0,i.jsx)(W,{node:e},n):e.type===`link`?(0,i.jsx)(U,{href:e.url??``,resolveHref:t,children:(e.children??[]).filter(e=>e.type===`text`).map((e,t)=>(0,i.jsx)(W,{node:e},t))},n):null)})}function K({node:e,resolveHref:t}){let n=e.format===`ordered`?`ol`:`ul`;return(0,i.jsx)(n,{children:(e.children??[]).map((e,n)=>e.type===`list`?(0,i.jsx)(`li`,{children:(0,i.jsx)(K,{node:e,resolveHref:t})},n):e.type===`list-item`?(0,i.jsx)(`li`,{children:(0,i.jsx)(G,{nodes:e.children,resolveHref:t})},n):null)})}function q({nodes:e,resolveHref:t}){return(0,i.jsx)(i.Fragment,{children:e.map((e,n)=>{switch(e.type){case`paragraph`:return(0,i.jsx)(`p`,{children:(0,i.jsx)(G,{nodes:e.children,resolveHref:t})},n);case`heading`:return(0,i.jsx)(`p`,{children:(0,i.jsx)(`strong`,{children:(0,i.jsx)(G,{nodes:e.children,resolveHref:t})})},n);case`list`:return(0,i.jsx)(K,{node:e,resolveHref:t},n);default:return null}})})}function J(e){return{necessary:!0,preferences:e?.preferences??!1,analytics:e?.analytics??!1,marketing:e?.marketing??!1}}function Y({category:e,copy:n,checked:r,onCheckedChange:a}){let o=(0,t.useId)(),s=(0,t.useId)(),{title:c,description:l}=n.categories[e];return(0,i.jsxs)(F,{value:e,children:[(0,i.jsxs)(I,{children:[(0,i.jsx)(L,{children:(0,i.jsx)(`span`,{id:o,children:c})}),(0,i.jsx)(M,{"aria-labelledby":o,"aria-describedby":l?s:void 0,checked:r,disabled:e===`necessary`,onCheckedChange:a})]}),(0,i.jsx)(R,{keepMounted:!0,children:l&&(0,i.jsx)(`p`,{id:s,className:z.CategoryDescription,children:l})})]})}function X({open:n,consent:r,copy:a,resolveHref:o,onAcceptAll:s,onAcceptNecessary:c,onSave:l,onClose:u}){let d=r!==null,[f,p]=(0,t.useState)(()=>J(r)),[h,g]=(0,t.useState)(n);return n!==h&&(g(n),n&&p(J(r))),(0,i.jsx)(b,{open:n,onOpenChange:e=>{!e&&d&&u()},disablePointerDismissal:!d,children:(0,i.jsxs)(x,{children:[(0,i.jsx)(S,{}),(0,i.jsx)(C,{children:(0,i.jsxs)(w,{fullScreenOnMobile:!0,size:`md`,children:[(0,i.jsxs)(T,{children:[(0,i.jsx)(E,{children:a.modalTitle}),d&&(0,i.jsx)(A,{label:a.closeIconLabel})]}),(0,i.jsxs)(O,{children:[(0,i.jsx)(D,{render:(0,i.jsx)(`div`,{}),className:z.Intro,children:(0,i.jsx)(q,{nodes:a.intro,resolveHref:o})}),(0,i.jsx)(P,{variant:`solid`,iconPosition:`start`,multiple:!0,className:z.Categories,children:e.l.map(e=>(0,i.jsx)(Y,{category:e,copy:a,checked:f[e],onCheckedChange:t=>p(n=>({...n,[e]:t}))},e))})]}),(0,i.jsxs)(k,{className:z.Actions,children:[(0,i.jsx)(m,{onClick:s,color:`neutral`,size:`sm`,children:a.btnAcceptAll}),(0,i.jsx)(m,{onClick:c,color:`neutral`,size:`sm`,children:a.btnAcceptNecessary}),(0,i.jsx)(m,{variant:`outline`,color:`neutral`,size:`sm`,className:z.Save,onClick:()=>l(e.l.filter(e=>f[e])),children:a.btnSaveSettings})]})]})})]})})}var Z=(0,t.createContext)(null);function Q({market:n,copy:r,resolveHref:a,children:o}){let{consent:s,settingsOpen:c,ready:l}=(0,t.useSyncExternalStore)(e.c,e.i,e.r);(0,t.useEffect)(()=>{e.a({market:n})},[]);let u=(0,t.useMemo)(()=>({consent:s,openSettings:e.o}),[s]);return(0,i.jsxs)(Z.Provider,{value:u,children:[o,l&&(0,i.jsx)(X,{open:c,consent:s,copy:r,resolveHref:a,onAcceptAll:()=>e.s(`all`),onAcceptNecessary:()=>e.s([]),onSave:e.s,onClose:e.t})]})}function $(){let e=(0,t.useContext)(Z);if(!e)throw Error(`useCookieConsent must be used inside a CookieConsentProvider.`);return e}exports.CookieConsentProvider=Q,exports.useCookieConsent=$;
|
|
2
|
+
//# sourceMappingURL=cookie-consent-react.cjs.map
|