@zappie/foundations 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # @zappie/foundations
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 38f23ac: `VERSION` (`@zappie/sdk`) and `FOUNDATIONS_VERSION` (`@zappie/foundations`) report the installed version. In 0.1.0 they said `"0.0.0"`. Verify reports now carry the real `verifyVersion`, and the test-mode debug channel the real SDK version.
8
+ - 1e6f420: Each package now has a README written for people installing it from npm: what it does, how to install and use it, its entry points, and links to docs.zappie.ai. `@zappie/kit` gains its first README.
9
+ - Updated dependencies [38f23ac]
10
+ - Updated dependencies [1e6f420]
11
+ - @zappie/sdk@0.1.1
12
+
13
+ ## 0.1.0
14
+
15
+ ### Minor Changes
16
+
17
+ - - `@zappie/tokens`: Publish the semantic storefront token contract, CSS aliases, validation and compilation tools.
18
+ - `@zappie/sdk`: Publish the framework-agnostic storefront client and its React, server, checkout, customer, places, visits and URL entries.
19
+ - `@zappie/foundations`: Publish accessible, unstyled React primitives for storefront catalogue, item, fulfilment and cart experiences.
20
+ - `@zappie/theme-base`: Publish the reusable base storefront theme and its catalogue, item and cart surfaces.
21
+ - `@zappie/kit`: Publish the built component registry consumed by the Zappie CLI.
22
+ - `zappie`: Publish the component CLI with `add`, `list` and `diff`.
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies
27
+ - @zappie/sdk@0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zappie
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,51 @@
1
- # Temporary Holding Version
1
+ # @zappie/foundations
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Unstyled React parts for storefronts. They handle the behaviour, state and accessibility of commerce UI: overlays, item options, quantities, the cart and its totals, fulfilment, addresses, schedules, search, payment methods, one-time codes, images, money and opening hours. You bring the styles.
4
+
5
+ ```sh
6
+ npm install @zappie/foundations @zappie/sdk react react-dom
7
+ ```
8
+
9
+ React 18.2 or 19 is a peer dependency.
10
+
11
+ ## Use it
12
+
13
+ The parts read Zappie data through `@zappie/sdk`, so wrap them in its `ZappieProvider`. Each part renders a plain element you can style, or takes a render function:
14
+
15
+ ```tsx
16
+ import type { Branch } from "@zappie/sdk";
17
+ import { OpenStatus } from "@zappie/foundations";
18
+
19
+ export function Hours({ branch }: { branch: Branch }) {
20
+ return (
21
+ <OpenStatus branch={branch} className="hours">
22
+ {(status) => status.label}
23
+ </OpenStatus>
24
+ );
25
+ }
26
+ ```
27
+
28
+ The label reads like "Open until 10pm", "Opens 8am tomorrow" or "Closed", and it updates when the branch opens or closes. Parts expose their state as `data-*` attributes, such as `data-state="open"`, so you can style each state in CSS.
29
+
30
+ Want ready-made, styled components instead? Copy them into your project from the kit with `npx zappie add <name>`.
31
+
32
+ ## Entry points
33
+
34
+ | Import | For |
35
+ | ------------------------------- | --------------------------------------------------------------- |
36
+ | `@zappie/foundations` | Every part |
37
+ | `@zappie/foundations/next` | Keeping overlays in step with Back and Forward in a Next.js app |
38
+ | `@zappie/foundations/rich-text` | Sanitising and parsing merchant rich text before you render it |
39
+
40
+ ## Docs
41
+
42
+ - [Foundations reference](https://docs.zappie.ai/foundations/core)
43
+ - [Build a storefront](https://docs.zappie.ai/guides/build-a-storefront)
44
+
45
+ ## Status
46
+
47
+ Foundations is at `0.x`. Its API can change in a minor release while it settles. Each change is listed in `CHANGELOG.md`.
48
+
49
+ ## License
50
+
51
+ MIT
@@ -0,0 +1,97 @@
1
+ // src/overlay/history.ts
2
+ var LOCATION_EVENT = "zappie:location";
3
+ function getCurrentOverlayEntry() {
4
+ if (typeof window === "undefined") {
5
+ return null;
6
+ }
7
+ const entry = window.history.state?.__zappieOverlay;
8
+ if (!entry || typeof entry.param !== "string" || typeof entry.id !== "string") {
9
+ return null;
10
+ }
11
+ return {
12
+ param: entry.param,
13
+ id: entry.id,
14
+ stack: Array.isArray(entry.stack) ? entry.stack.filter((key) => typeof key === "string") : []
15
+ };
16
+ }
17
+ function subscribeLocation(listener) {
18
+ window.addEventListener("popstate", listener);
19
+ window.addEventListener(LOCATION_EVENT, listener);
20
+ return () => {
21
+ window.removeEventListener("popstate", listener);
22
+ window.removeEventListener(LOCATION_EVENT, listener);
23
+ };
24
+ }
25
+ function locationSnapshot() {
26
+ return window.location.search;
27
+ }
28
+ function applyQuery(url, query) {
29
+ for (const [key, value] of Object.entries(query)) {
30
+ if (value == null) {
31
+ url.searchParams.delete(key);
32
+ } else {
33
+ url.searchParams.set(key, value);
34
+ }
35
+ }
36
+ }
37
+ function write(type, url, overlay) {
38
+ const state = { ...window.history.state };
39
+ delete state.__zappieOverlay;
40
+ if (overlay) {
41
+ state.__zappieOverlay = overlay;
42
+ }
43
+ state.__zappieBase ?? (state.__zappieBase = window.location.pathname);
44
+ if (url.pathname !== window.location.pathname) {
45
+ delete state.__NA;
46
+ delete state.__PRIVATE_NEXTJS_INTERNALS_TREE;
47
+ }
48
+ const prototype = Object.getPrototypeOf(window.history);
49
+ prototype[type].call(window.history, state, "", url.href);
50
+ window.dispatchEvent(new Event(LOCATION_EVENT));
51
+ }
52
+ function openOverlay(param, id, query = {}) {
53
+ const url = new URL(window.location.href);
54
+ applyQuery(url, query);
55
+ url.searchParams.set(param, id);
56
+ if (url.href === window.location.href) {
57
+ return;
58
+ }
59
+ const previous = getCurrentOverlayEntry();
60
+ write("pushState", url, {
61
+ param,
62
+ id,
63
+ stack: [...previous?.stack ?? [], `${param}:${id}`]
64
+ });
65
+ }
66
+ function closeOverlay(param, id, options = {}) {
67
+ const url = new URL(window.location.href);
68
+ if (!url.searchParams.has(param)) {
69
+ return;
70
+ }
71
+ const entry = getCurrentOverlayEntry();
72
+ const stack = entry?.stack ?? [];
73
+ const index = id ? stack.lastIndexOf(`${param}:${id}`) : stack.reduce(
74
+ (found, key, index2) => key.startsWith(`${param}:`) ? index2 : found,
75
+ -1
76
+ );
77
+ if (index >= 0) {
78
+ window.history.go(-(stack.length - index));
79
+ return;
80
+ }
81
+ applyQuery(url, options.fallback ?? {});
82
+ if (!options.fallback || !(param in options.fallback)) {
83
+ url.searchParams.delete(param);
84
+ }
85
+ for (const omitted of options.omitParams ?? []) {
86
+ url.searchParams.delete(omitted);
87
+ }
88
+ write(
89
+ "replaceState",
90
+ url,
91
+ entry && url.searchParams.get(entry.param) === entry.id ? entry : null
92
+ );
93
+ }
94
+
95
+ export { LOCATION_EVENT, closeOverlay, locationSnapshot, openOverlay, subscribeLocation };
96
+ //# sourceMappingURL=chunk-BY2WQGLO.js.map
97
+ //# sourceMappingURL=chunk-BY2WQGLO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/overlay/history.ts"],"names":["index"],"mappings":"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","file":"chunk-BY2WQGLO.js","sourcesContent":["export type OverlayEntry = { param: string; id: string; stack: string[] };\nexport type OverlayQuery = Record<string, string | null | undefined>;\nexport type CloseOptions = {\n fallback?: OverlayQuery | undefined;\n omitParams?: string[] | undefined;\n};\nexport const LOCATION_EVENT = \"zappie:location\";\nexport function getCurrentOverlayEntry(): OverlayEntry | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n const entry = window.history.state?.__zappieOverlay;\n if (\n !entry ||\n typeof entry.param !== \"string\" ||\n typeof entry.id !== \"string\"\n ) {\n return null;\n }\n return {\n param: entry.param,\n id: entry.id,\n stack: Array.isArray(entry.stack)\n ? entry.stack.filter((key: unknown) => typeof key === \"string\")\n : [],\n };\n}\nexport function subscribeLocation(listener: () => void) {\n window.addEventListener(\"popstate\", listener);\n window.addEventListener(LOCATION_EVENT, listener);\n return () => {\n window.removeEventListener(\"popstate\", listener);\n window.removeEventListener(LOCATION_EVENT, listener);\n };\n}\nexport function locationSnapshot() {\n return window.location.search;\n}\nfunction applyQuery(url: URL, query: OverlayQuery) {\n for (const [key, value] of Object.entries(query)) {\n if (value == null) {\n url.searchParams.delete(key);\n } else {\n url.searchParams.set(key, value);\n }\n }\n}\nfunction write(\n type: \"pushState\" | \"replaceState\",\n url: URL,\n overlay: OverlayEntry | null,\n) {\n const state = { ...window.history.state };\n delete state.__zappieOverlay;\n if (overlay) {\n state.__zappieOverlay = overlay;\n }\n state.__zappieBase ??= window.location.pathname;\n if (url.pathname !== window.location.pathname) {\n delete state.__NA;\n delete state.__PRIVATE_NEXTJS_INTERNALS_TREE;\n }\n // Bypass Next's wrapper: shallow overlay writes must not remount the page.\n const prototype = Object.getPrototypeOf(window.history) as History;\n prototype[type].call(window.history, state, \"\", url.href);\n window.dispatchEvent(new Event(LOCATION_EVENT));\n}\nexport function openOverlay(\n param: string,\n id: string,\n query: OverlayQuery = {},\n) {\n const url = new URL(window.location.href);\n applyQuery(url, query);\n url.searchParams.set(param, id);\n if (url.href === window.location.href) {\n return;\n }\n const previous = getCurrentOverlayEntry();\n write(\"pushState\", url, {\n param,\n id,\n stack: [...(previous?.stack ?? []), `${param}:${id}`],\n });\n}\nexport function closeOverlay(\n param: string,\n id?: string,\n options: CloseOptions = {},\n) {\n const url = new URL(window.location.href);\n if (!url.searchParams.has(param)) {\n return;\n }\n const entry = getCurrentOverlayEntry();\n const stack = entry?.stack ?? [];\n const index = id\n ? stack.lastIndexOf(`${param}:${id}`)\n : stack.reduce(\n (found, key, index) => (key.startsWith(`${param}:`) ? index : found),\n -1,\n );\n if (index >= 0) {\n window.history.go(-(stack.length - index));\n return;\n }\n applyQuery(url, options.fallback ?? {});\n if (!options.fallback || !(param in options.fallback)) {\n url.searchParams.delete(param);\n }\n for (const omitted of options.omitParams ?? []) {\n url.searchParams.delete(omitted);\n }\n write(\n \"replaceState\",\n url,\n entry && url.searchParams.get(entry.param) === entry.id ? entry : null,\n );\n}\n"]}
@@ -0,0 +1,81 @@
1
+ import { Children, isValidElement, cloneElement, createElement } from 'react';
2
+
3
+ // src/internal/slot.tsx
4
+ function composeRefs(...refs) {
5
+ let cleanups = [];
6
+ return (value) => {
7
+ for (const cleanup of cleanups) {
8
+ cleanup();
9
+ }
10
+ cleanups = [];
11
+ if (value === null) {
12
+ return;
13
+ }
14
+ for (const ref of refs) {
15
+ if (typeof ref === "function") {
16
+ const cleanup = ref(value);
17
+ cleanups.push(
18
+ typeof cleanup === "function" ? cleanup : () => ref(null)
19
+ );
20
+ } else if (ref) {
21
+ ref.current = value;
22
+ cleanups.push(() => {
23
+ ref.current = null;
24
+ });
25
+ }
26
+ }
27
+ };
28
+ }
29
+ function mergeProps(base, consumer) {
30
+ const result = { ...base, ...consumer };
31
+ if (typeof base.className === "string" && typeof consumer.className === "string") {
32
+ result.className = `${base.className} ${consumer.className}`;
33
+ }
34
+ if (base.style && consumer.style && typeof base.style === "object" && typeof consumer.style === "object") {
35
+ result.style = { ...base.style, ...consumer.style };
36
+ }
37
+ for (const key of Object.keys(base)) {
38
+ if (/^on[A-Z]/.test(key) && typeof base[key] === "function" && typeof consumer[key] === "function") {
39
+ result[key] = (event) => {
40
+ consumer[key](event);
41
+ if (!event.defaultPrevented) {
42
+ base[key](event);
43
+ }
44
+ };
45
+ }
46
+ }
47
+ return result;
48
+ }
49
+ function part(tag, props, state, defaults = {}, ref) {
50
+ const { asChild, children, ...dom } = props;
51
+ const content = typeof children === "function" ? children(state) : children;
52
+ const merged = mergeProps(defaults, dom);
53
+ if (asChild || tag === "input" && typeof children === "function") {
54
+ const child = Children.only(content);
55
+ if (!isValidElement(child)) {
56
+ throw new Error("asChild requires one React element");
57
+ }
58
+ const element = child;
59
+ const descriptor = Object.getOwnPropertyDescriptor(element, "ref");
60
+ const childRef = element.props.ref ?? (descriptor && "value" in descriptor ? descriptor.value : void 0);
61
+ return cloneElement(element, {
62
+ ...mergeProps(merged, element.props),
63
+ ref: composeRefs(ref, childRef)
64
+ });
65
+ }
66
+ return createElement(tag, { ...merged, ref }, content);
67
+ }
68
+ function partId(props) {
69
+ if (props.id) {
70
+ return props.id;
71
+ }
72
+ if (props.asChild && isValidElement(props.children)) {
73
+ const id = props.children.props.id;
74
+ return typeof id === "string" ? id : void 0;
75
+ }
76
+ return void 0;
77
+ }
78
+
79
+ export { composeRefs, part, partId };
80
+ //# sourceMappingURL=chunk-D3J7S33L.js.map
81
+ //# sourceMappingURL=chunk-D3J7S33L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/slot.tsx"],"names":[],"mappings":"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","file":"chunk-D3J7S33L.js","sourcesContent":["import {\n Children,\n cloneElement,\n createElement,\n isValidElement,\n type AllHTMLAttributes,\n type ElementType,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\n/**\n * HTML attributes shared by foundation parts, with optional render-function children.\n * Set asChild to merge the part props and ref into a single child element.\n */\nexport type PartProps<S = Record<string, never>> = Omit<\n AllHTMLAttributes<HTMLElement>,\n \"children\" | \"defaultValue\" | \"value\"\n> & {\n asChild?: boolean;\n children?: ReactNode | ((state: S) => ReactNode);\n};\nexport function composeRefs<T>(...refs: (Ref<T> | undefined)[]): Ref<T> {\n let cleanups: (() => void)[] = [];\n return (value) => {\n for (const cleanup of cleanups) {\n cleanup();\n }\n cleanups = [];\n if (value === null) {\n return;\n }\n for (const ref of refs) {\n if (typeof ref === \"function\") {\n const cleanup = ref(value);\n cleanups.push(\n typeof cleanup === \"function\" ? cleanup : () => ref(null),\n );\n } else if (ref) {\n ref.current = value;\n cleanups.push(() => {\n ref.current = null;\n });\n }\n }\n };\n}\n/** Consumer handlers run first and may cancel the primitive's action. */\nexport function mergeProps(\n base: Record<string, unknown>,\n consumer: Record<string, unknown>,\n) {\n const result = { ...base, ...consumer };\n if (\n typeof base.className === \"string\" &&\n typeof consumer.className === \"string\"\n ) {\n result.className = `${base.className} ${consumer.className}`;\n }\n if (\n base.style &&\n consumer.style &&\n typeof base.style === \"object\" &&\n typeof consumer.style === \"object\"\n ) {\n result.style = { ...base.style, ...consumer.style };\n }\n for (const key of Object.keys(base)) {\n if (\n /^on[A-Z]/.test(key) &&\n typeof base[key] === \"function\" &&\n typeof consumer[key] === \"function\"\n ) {\n result[key] = (event: { defaultPrevented?: boolean }) => {\n (consumer[key] as (event: unknown) => void)(event);\n if (!event.defaultPrevented) {\n (base[key] as (event: unknown) => void)(event);\n }\n };\n }\n }\n return result;\n}\nexport function part<S>(\n tag: ElementType,\n props: PartProps<S>,\n state: S,\n defaults: Record<string, unknown> = {},\n ref?: Ref<HTMLElement>,\n) {\n const { asChild, children, ...dom } = props;\n const content = typeof children === \"function\" ? children(state) : children;\n const merged = mergeProps(defaults, dom);\n if (asChild || (tag === \"input\" && typeof children === \"function\")) {\n const child = Children.only(content);\n if (!isValidElement(child)) {\n throw new Error(\"asChild requires one React element\");\n }\n const element = child as ReactElement<Record<string, unknown>>;\n // React 18 stores ref on the element; React 19 stores it in props.\n const descriptor = Object.getOwnPropertyDescriptor(element, \"ref\");\n const childRef =\n element.props.ref ??\n (descriptor && \"value\" in descriptor ? descriptor.value : undefined);\n return cloneElement(element, {\n ...mergeProps(merged, element.props),\n ref: composeRefs(ref, childRef as Ref<HTMLElement>),\n });\n }\n return createElement(tag, { ...merged, ref }, content);\n}\n/** A part's caller-supplied id, whether passed as a prop or set on its `asChild` element. */\nexport function partId(props: {\n id?: string | undefined;\n asChild?: boolean | undefined;\n children?: unknown;\n}): string | undefined {\n if (props.id) {\n return props.id;\n }\n if (props.asChild && isValidElement(props.children)) {\n const id = (props.children.props as { id?: unknown }).id;\n return typeof id === \"string\" ? id : undefined;\n }\n return undefined;\n}\n"]}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * A parser-neutral rich-text node containing its type, optional tag name, text and children.
3
+ */
4
+ type ParsedRichTextNode = {
5
+ type: string;
6
+ name?: string;
7
+ data?: string;
8
+ children?: ParsedRichTextNode[];
9
+ };
10
+ /**
11
+ * A parser adapter that converts HTML into the node tree consumed by the rich-text sanitizer.
12
+ */
13
+ type ParseRichText = (html: string) => ParsedRichTextNode[];
14
+ /**
15
+ * Create a sanitizer using your HTML parser adapter.
16
+ * Keeps supported formatting tags without attributes, escapes text and removes unsafe element content.
17
+ *
18
+ * @param parseRichText - A parser that returns the shared rich-text node format.
19
+ * @returns A sanitizer that accepts HTML and returns sanitized HTML, or an empty string for empty input.
20
+ */
21
+ declare const createSanitizeRichText: (parseRichText: ParseRichText) => (html?: string | null) => string;
22
+
23
+ export { type ParsedRichTextNode as P, type ParseRichText as a, createSanitizeRichText as c };
@@ -0,0 +1,60 @@
1
+ import * as react from 'react';
2
+ import { AllHTMLAttributes, ReactNode, Ref } from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { Dialog } from '@base-ui/react/dialog';
5
+
6
+ /**
7
+ * HTML attributes shared by foundation parts, with optional render-function children.
8
+ * Set asChild to merge the part props and ref into a single child element.
9
+ */
10
+ type PartProps<S = Record<string, never>> = Omit<AllHTMLAttributes<HTMLElement>, "children" | "defaultValue" | "value"> & {
11
+ asChild?: boolean;
12
+ children?: ReactNode | ((state: S) => ReactNode);
13
+ };
14
+
15
+ type Presentation = "dialog" | "drawer" | "sheet";
16
+ type SwipeDirection = "up" | "down" | "left" | "right";
17
+ type SurfaceProps = {
18
+ open: boolean;
19
+ presentation: Presentation;
20
+ swipeDirection: SwipeDirection;
21
+ /** Ids the trigger points at; caller-supplied ids win. */
22
+ contentId: string;
23
+ titleId?: string | undefined;
24
+ trigger: {
25
+ current: HTMLElement | null;
26
+ };
27
+ onOpen: () => void;
28
+ onClose: () => void;
29
+ onEscape?: ((event: KeyboardEvent) => void) | undefined;
30
+ onInteractOutside?: ((event: Event) => void) | undefined;
31
+ forceMount?: true | undefined;
32
+ container?: HTMLElement | null | undefined;
33
+ state: unknown;
34
+ contentProps: PartProps<never>;
35
+ contentRef: Ref<HTMLElement>;
36
+ };
37
+ type Parts = {
38
+ Title: typeof Dialog.Title;
39
+ Close: typeof Dialog.Close;
40
+ };
41
+ declare function useEngineParts(): Parts;
42
+ declare function Surface(props: SurfaceProps & {
43
+ children?: ReactNode;
44
+ }): react_jsx_runtime.JSX.Element;
45
+ declare const EngineTitle: react.ForwardRefExoticComponent<Omit<react.AllHTMLAttributes<HTMLElement>, "children" | "defaultValue" | "value"> & {
46
+ asChild?: boolean;
47
+ children?: ReactNode | ((state: unknown) => ReactNode);
48
+ } & {
49
+ id?: string | undefined;
50
+ state: unknown;
51
+ } & react.RefAttributes<HTMLElement>>;
52
+ declare const EngineClose: react.ForwardRefExoticComponent<Omit<react.AllHTMLAttributes<HTMLElement>, "children" | "defaultValue" | "value"> & {
53
+ asChild?: boolean;
54
+ children?: ReactNode | ((state: unknown) => ReactNode);
55
+ } & {
56
+ id?: string | undefined;
57
+ state: unknown;
58
+ } & react.RefAttributes<HTMLElement>>;
59
+
60
+ export { EngineClose as E, type PartProps as P, type SwipeDirection as S, type Presentation as a, EngineTitle as b, Surface as c, type SurfaceProps as d, useEngineParts as u };
@@ -0,0 +1,8 @@
1
+ type OverlayQuery = Record<string, string | null | undefined>;
2
+ type CloseOptions = {
3
+ fallback?: OverlayQuery | undefined;
4
+ omitParams?: string[] | undefined;
5
+ };
6
+ declare const LOCATION_EVENT = "zappie:location";
7
+
8
+ export { type CloseOptions as C, LOCATION_EVENT as L, type OverlayQuery as O };