@howells/stacksheet 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel Howells
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.
@@ -0,0 +1,3 @@
1
+ import type { ResolvedConfig, SheetStackConfig } from "./types.js";
2
+ export declare function resolveConfig(config?: SheetStackConfig): ResolvedConfig;
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAEd,gBAAgB,EAGjB,MAAM,YAAY,CAAC;AAyBpB,wBAAgB,aAAa,CAAC,MAAM,GAAE,gBAAqB,GAAG,cAAc,CAmB3E"}
package/dist/config.js ADDED
@@ -0,0 +1,37 @@
1
+ // ── Defaults ────────────────────────────────────
2
+ const DEFAULT_STACKING = {
3
+ scaleStep: 0.04,
4
+ offsetStep: 24,
5
+ opacityStep: 0.15,
6
+ radius: 12,
7
+ renderThreshold: 5,
8
+ };
9
+ const DEFAULT_SPRING = {
10
+ damping: 30,
11
+ stiffness: 170,
12
+ mass: 0.8,
13
+ };
14
+ const DEFAULT_SIDE = {
15
+ desktop: "right",
16
+ mobile: "bottom",
17
+ };
18
+ // ── Resolver ────────────────────────────────────
19
+ export function resolveConfig(config = {}) {
20
+ const side = typeof config.side === "string"
21
+ ? { desktop: config.side, mobile: config.side }
22
+ : { ...DEFAULT_SIDE, ...config.side };
23
+ return {
24
+ maxDepth: config.maxDepth ?? Infinity,
25
+ closeOnEscape: config.closeOnEscape ?? true,
26
+ closeOnBackdrop: config.closeOnBackdrop ?? true,
27
+ lockScroll: config.lockScroll ?? true,
28
+ width: config.width ?? 420,
29
+ maxWidth: config.maxWidth ?? "90vw",
30
+ breakpoint: config.breakpoint ?? 768,
31
+ side,
32
+ stacking: { ...DEFAULT_STACKING, ...config.stacking },
33
+ spring: { ...DEFAULT_SPRING, ...config.spring },
34
+ zIndex: config.zIndex ?? 100,
35
+ };
36
+ }
37
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,mDAAmD;AAEnD,MAAM,gBAAgB,GAAmB;IACvC,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE,EAAE;IACV,eAAe,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,cAAc,GAAiB;IACnC,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,GAAG;IACd,IAAI,EAAE,GAAG;CACV,CAAC;AAEF,MAAM,YAAY,GAAmB;IACnC,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,QAAQ;CACjB,CAAC;AAEF,mDAAmD;AAEnD,MAAM,UAAU,aAAa,CAAC,SAA2B,EAAE;IACzD,MAAM,IAAI,GACR,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ;QAC7B,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;QAC/C,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAE1C,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,QAAQ;QACrC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;QAC3C,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI;QAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI;QACrC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,GAAG;QAC1B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM;QACnC,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG;QACpC,IAAI;QACJ,QAAQ,EAAE,EAAE,GAAG,gBAAgB,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE;QACrD,MAAM,EAAE,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE;QAC/C,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,GAAG;KAC7B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { SheetStackConfig, SheetStackInstance } from "./types.js";
2
+ /**
3
+ * Create an isolated sheet stack instance with typed store, hooks, and provider.
4
+ *
5
+ * ```ts
6
+ * const { SheetProvider, useSheet, useSheetState } = createSheetStack<{
7
+ * "bucket-create": { onCreated?: (b: Bucket) => void };
8
+ * "bucket-edit": { bucket: Bucket };
9
+ * }>();
10
+ * ```
11
+ */
12
+ export declare function createSheetStack<TMap extends Record<string, unknown>>(config?: SheetStackConfig): SheetStackInstance<TMap>;
13
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAKV,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAKpB;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnE,MAAM,CAAC,EAAE,gBAAgB,GACxB,kBAAkB,CAAC,IAAI,CAAC,CAiE1B"}
package/dist/create.js ADDED
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo } from "react";
3
+ import { useStore } from "zustand";
4
+ import { resolveConfig } from "./config.js";
5
+ import { SheetRenderer } from "./renderer.js";
6
+ import { createSheetStore } from "./store.js";
7
+ /**
8
+ * Create an isolated sheet stack instance with typed store, hooks, and provider.
9
+ *
10
+ * ```ts
11
+ * const { SheetProvider, useSheet, useSheetState } = createSheetStack<{
12
+ * "bucket-create": { onCreated?: (b: Bucket) => void };
13
+ * "bucket-edit": { bucket: Bucket };
14
+ * }>();
15
+ * ```
16
+ */
17
+ export function createSheetStack(config) {
18
+ const resolved = resolveConfig(config);
19
+ const store = createSheetStore(resolved);
20
+ // Context for the store — allows multiple instances
21
+ const StoreContext = createContext(null);
22
+ function useStoreContext() {
23
+ const ctx = useContext(StoreContext);
24
+ if (!ctx) {
25
+ throw new Error("useSheet/useSheetState must be used within <SheetProvider>");
26
+ }
27
+ return ctx;
28
+ }
29
+ // ── Provider ────────────────────────────────
30
+ function SheetProvider({ content, children, }) {
31
+ const value = useMemo(() => ({ store, config: resolved }), []);
32
+ return (_jsxs(StoreContext.Provider, { value: value, children: [children, _jsx(SheetRenderer, { config: resolved, content: content, store: store })] }));
33
+ }
34
+ // ── Hooks ───────────────────────────────────
35
+ function useSheet() {
36
+ const { store: s } = useStoreContext();
37
+ return useStore(s, (state) => ({
38
+ open: state.open,
39
+ push: state.push,
40
+ replace: state.replace,
41
+ navigate: state.navigate,
42
+ pop: state.pop,
43
+ close: state.close,
44
+ }));
45
+ }
46
+ function useSheetState() {
47
+ const { store: s } = useStoreContext();
48
+ return useStore(s, (state) => ({
49
+ stack: state.stack,
50
+ isOpen: state.isOpen,
51
+ }));
52
+ }
53
+ return { SheetProvider, useSheet, useSheetState, store };
54
+ }
55
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAa9C;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAyB;IAEzB,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,gBAAgB,CAAO,QAAQ,CAAC,CAAC;IAE/C,oDAAoD;IACpD,MAAM,YAAY,GAAG,aAAa,CAGxB,IAAI,CAAC,CAAC;IAEhB,SAAS,eAAe;QACtB,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,+CAA+C;IAE/C,SAAS,aAAa,CAAC,EACrB,OAAO,EACP,QAAQ,GAIT;QACC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,OAAO,CACL,MAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,aAChC,QAAQ,EACT,KAAC,aAAa,IACZ,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,GACZ,IACoB,CACzB,CAAC;IACJ,CAAC;IAED,+CAA+C;IAE/C,SAAS,QAAQ;QACf,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,eAAe,EAAE,CAAC;QACvC,OAAO,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,SAAS,aAAa;QACpB,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,eAAe,EAAE,CAAC;QACvC,OAAO,QAAQ,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { createSheetStack } from "./create.js";
2
+ export { resolveConfig } from "./config.js";
3
+ export { getStackTransform, getSlideFrom, getPanelStyles } from "./stacking.js";
4
+ export { useIsMobile, useResolvedSide } from "./media.js";
5
+ export type { SheetItem, Side, ResponsiveSide, SideConfig, StackingConfig, SpringConfig, SheetStackConfig, ResolvedConfig, SheetContentComponent, ContentMap, SheetSnapshot, SheetActions, SheetStackInstance, } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE1D,YAAY,EAEV,SAAS,EACT,IAAI,EACJ,cAAc,EACd,UAAU,EAEV,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EAEd,qBAAqB,EACrB,UAAU,EAEV,aAAa,EACb,YAAY,EAEZ,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { createSheetStack } from "./create.js";
2
+ export { resolveConfig } from "./config.js";
3
+ export { getStackTransform, getSlideFrom, getPanelStyles } from "./stacking.js";
4
+ export { useIsMobile, useResolvedSide } from "./media.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ResolvedConfig, Side } from "./types.js";
2
+ /**
3
+ * Returns true when viewport width is at or below the breakpoint.
4
+ * SSR-safe: defaults to false (desktop).
5
+ */
6
+ export declare function useIsMobile(breakpoint: number): boolean;
7
+ /** Resolve the current side from config + viewport. */
8
+ export declare function useResolvedSide(config: ResolvedConfig): Side;
9
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAavD;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAG5D"}
package/dist/media.js ADDED
@@ -0,0 +1,22 @@
1
+ import { useEffect, useState } from "react";
2
+ /**
3
+ * Returns true when viewport width is at or below the breakpoint.
4
+ * SSR-safe: defaults to false (desktop).
5
+ */
6
+ export function useIsMobile(breakpoint) {
7
+ const [isMobile, setIsMobile] = useState(false);
8
+ useEffect(() => {
9
+ const mql = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
10
+ setIsMobile(mql.matches);
11
+ const handler = (e) => setIsMobile(e.matches);
12
+ mql.addEventListener("change", handler);
13
+ return () => mql.removeEventListener("change", handler);
14
+ }, [breakpoint]);
15
+ return isMobile;
16
+ }
17
+ /** Resolve the current side from config + viewport. */
18
+ export function useResolvedSide(config) {
19
+ const isMobile = useIsMobile(config.breakpoint);
20
+ return isMobile ? config.side.mobile : config.side.desktop;
21
+ }
22
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG5C;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,eAAe,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC;QAClE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEzB,MAAM,OAAO,GAAG,CAAC,CAAsB,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACnE,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACxC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { StoreApi } from "zustand";
2
+ import type { ContentMap, ResolvedConfig, SheetActions, SheetSnapshot } from "./types.js";
3
+ interface SheetRendererProps<TMap extends Record<string, unknown>> {
4
+ store: StoreApi<SheetSnapshot<TMap> & SheetActions<TMap>>;
5
+ config: ResolvedConfig;
6
+ content: ContentMap<TMap>;
7
+ }
8
+ export declare function SheetRenderer<TMap extends Record<string, unknown>>({ store, config, content, }: SheetRendererProps<TMap>): import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AASxC,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,YAAY,EAEZ,aAAa,EAEd,MAAM,YAAY,CAAC;AA4DpB,UAAU,kBAAkB,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/D,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAClE,KAAK,EACL,MAAM,EACN,OAAO,GACR,EAAE,kBAAkB,CAAC,IAAI,CAAC,2CAmM1B"}
@@ -0,0 +1,169 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { AnimatePresence, m } from "motion/react";
3
+ import { useEffect, useRef, useState, } from "react";
4
+ import { useStore } from "zustand";
5
+ import { useResolvedSide } from "./media.js";
6
+ import { getSlideFrom, getSlideTarget, getStackTransform, getPanelStyles, } from "./stacking.js";
7
+ // ── Icons (inline SVG — no external dependency) ─
8
+ function ArrowLeftIcon() {
9
+ return (_jsx("svg", { "aria-hidden": "true", fill: "none", height: 16, stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, viewBox: "0 0 24 24", width: 16, children: _jsx("path", { d: "M19 12H5M12 19l-7-7 7-7" }) }));
10
+ }
11
+ function XIcon() {
12
+ return (_jsx("svg", { "aria-hidden": "true", fill: "none", height: 16, stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, viewBox: "0 0 24 24", width: 16, children: _jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }));
13
+ }
14
+ // ── Header button ───────────────────────────────
15
+ const BUTTON_STYLE = {
16
+ display: "inline-flex",
17
+ alignItems: "center",
18
+ justifyContent: "center",
19
+ width: 32,
20
+ height: 32,
21
+ borderRadius: "50%",
22
+ border: "none",
23
+ background: "transparent",
24
+ cursor: "pointer",
25
+ color: "inherit",
26
+ opacity: 0.5,
27
+ transition: "opacity 150ms",
28
+ padding: 0,
29
+ };
30
+ export function SheetRenderer({ store, config, content, }) {
31
+ const isOpen = useStore(store, (s) => s.isOpen);
32
+ const stack = useStore(store, (s) => s.stack);
33
+ const close = useStore(store, (s) => s.close);
34
+ const pop = useStore(store, (s) => s.pop);
35
+ const side = useResolvedSide(config);
36
+ // Display stack — keep items during exit animation
37
+ const [displayStack, setDisplayStack] = useState([]);
38
+ const clearTimerRef = useRef(null);
39
+ useEffect(() => {
40
+ if (stack.length > 0) {
41
+ if (clearTimerRef.current) {
42
+ clearTimeout(clearTimerRef.current);
43
+ clearTimerRef.current = null;
44
+ }
45
+ setDisplayStack(stack);
46
+ }
47
+ else {
48
+ // Delay clearing so exit animations complete
49
+ clearTimerRef.current = setTimeout(() => {
50
+ setDisplayStack([]);
51
+ }, 500);
52
+ }
53
+ return () => {
54
+ if (clearTimerRef.current) {
55
+ clearTimeout(clearTimerRef.current);
56
+ }
57
+ };
58
+ }, [stack]);
59
+ // Scroll lock
60
+ useEffect(() => {
61
+ if (!isOpen || !config.lockScroll)
62
+ return;
63
+ const prev = document.body.style.overflow;
64
+ document.body.style.overflow = "hidden";
65
+ return () => {
66
+ document.body.style.overflow = prev;
67
+ };
68
+ }, [isOpen, config.lockScroll]);
69
+ // Escape key
70
+ useEffect(() => {
71
+ if (!isOpen || !config.closeOnEscape)
72
+ return;
73
+ function handleKeyDown(e) {
74
+ if (e.key === "Escape") {
75
+ e.preventDefault();
76
+ if (stack.length > 1) {
77
+ pop();
78
+ }
79
+ else {
80
+ close();
81
+ }
82
+ }
83
+ }
84
+ document.addEventListener("keydown", handleKeyDown);
85
+ return () => document.removeEventListener("keydown", handleKeyDown);
86
+ }, [isOpen, config.closeOnEscape, stack.length, pop, close]);
87
+ const slideFrom = getSlideFrom(side);
88
+ const slideTarget = getSlideTarget();
89
+ const spring = {
90
+ type: "spring",
91
+ damping: config.spring.damping,
92
+ stiffness: config.spring.stiffness,
93
+ mass: config.spring.mass,
94
+ };
95
+ return (_jsx(AnimatePresence, { children: isOpen && (_jsxs(_Fragment, { children: [_jsx(m.div, { animate: { opacity: 1 }, exit: { opacity: 0 }, initial: { opacity: 0 }, onClick: config.closeOnBackdrop ? close : undefined, style: {
96
+ position: "fixed",
97
+ inset: 0,
98
+ zIndex: config.zIndex,
99
+ background: "rgba(0, 0, 0, 0.2)",
100
+ cursor: config.closeOnBackdrop ? "pointer" : undefined,
101
+ }, transition: { duration: 0.2 } }, "stacksheet-backdrop"), displayStack.map((item, index) => {
102
+ const depth = displayStack.length - 1 - index;
103
+ const isTop = depth === 0;
104
+ const isNested = displayStack.length > 1;
105
+ const transform = getStackTransform(depth, config.stacking);
106
+ const panelStyles = getPanelStyles(side, config, depth, index);
107
+ const shouldRender = depth < config.stacking.renderThreshold;
108
+ // Compute stacking offset for animate
109
+ const stackOffset = getStackingOffset(side, transform.offset);
110
+ const Content = content[item.type];
111
+ return (_jsxs(m.div, { animate: {
112
+ ...slideTarget,
113
+ ...stackOffset,
114
+ scale: transform.scale,
115
+ opacity: transform.opacity,
116
+ borderRadius: transform.borderRadius,
117
+ }, "aria-modal": isTop ? "true" : undefined, exit: {
118
+ ...slideFrom,
119
+ opacity: 0.6,
120
+ }, initial: {
121
+ ...slideFrom,
122
+ opacity: 0.8,
123
+ }, role: isTop ? "dialog" : undefined, style: {
124
+ ...panelStyles,
125
+ boxShadow: isTop
126
+ ? getShadow(side, false)
127
+ : getShadow(side, true),
128
+ pointerEvents: isTop ? "auto" : "none",
129
+ }, transition: spring, children: [isTop && (_jsxs("div", { style: {
130
+ display: "flex",
131
+ alignItems: "center",
132
+ height: 48,
133
+ flexShrink: 0,
134
+ padding: "0 12px",
135
+ borderBottom: "1px solid transparent",
136
+ }, children: [isNested && (_jsx("button", { "aria-label": "Back", onClick: pop, style: BUTTON_STYLE, type: "button", children: _jsx(ArrowLeftIcon, {}) })), _jsx("div", { style: { flex: 1 } }), _jsx("button", { "aria-label": "Close", onClick: close, style: BUTTON_STYLE, type: "button", children: _jsx(XIcon, {}) })] })), shouldRender && Content && (_jsx("div", { style: {
137
+ flex: 1,
138
+ minHeight: 0,
139
+ overflowY: "auto",
140
+ overscrollBehavior: "contain",
141
+ }, children: _jsx(Content, { data: item.data, onClose: close }) }))] }, item.id));
142
+ })] })) }));
143
+ }
144
+ // ── Helpers ─────────────────────────────────────
145
+ function getStackingOffset(side, offset) {
146
+ if (offset === 0)
147
+ return {};
148
+ switch (side) {
149
+ case "right":
150
+ return { x: -offset };
151
+ case "left":
152
+ return { x: offset };
153
+ case "bottom":
154
+ return { y: -offset };
155
+ }
156
+ }
157
+ function getShadow(side, isNested) {
158
+ if (side === "bottom") {
159
+ return isNested
160
+ ? "0 -2px 16px rgba(0,0,0,0.06)"
161
+ : "0 -8px 32px rgba(0,0,0,0.15)";
162
+ }
163
+ // Left/right
164
+ const dir = side === "right" ? -1 : 1;
165
+ return isNested
166
+ ? `${dir * 2}px 0 16px rgba(0,0,0,0.06)`
167
+ : `${dir * 8}px 0 32px rgba(0,0,0,0.15)`;
168
+ }
169
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { CSSProperties } from "react";
2
+ import type { ResolvedConfig, Side, StackingConfig } from "./types.js";
3
+ export interface StackTransform {
4
+ scale: number;
5
+ offset: number;
6
+ opacity: number;
7
+ borderRadius: number;
8
+ }
9
+ /**
10
+ * Compute visual transforms for a panel at a given depth.
11
+ * depth=0 is the top (foreground) panel.
12
+ */
13
+ export declare function getStackTransform(depth: number, stacking: StackingConfig): StackTransform;
14
+ export interface SlideValues {
15
+ x?: string | number;
16
+ y?: string | number;
17
+ }
18
+ /** Motion initial/exit values for sliding from the given side. */
19
+ export declare function getSlideFrom(side: Side): SlideValues;
20
+ /** Motion animate target — the resting position. */
21
+ export declare function getSlideTarget(): SlideValues;
22
+ /**
23
+ * Fixed-position styles for a panel, accounting for side, width, and depth.
24
+ */
25
+ export declare function getPanelStyles(side: Side, config: ResolvedConfig, depth: number, index: number): CSSProperties;
26
+ //# sourceMappingURL=stacking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stacking.d.ts","sourceRoot":"","sources":["../src/stacking.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIvE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACvB,cAAc,CAUhB;AAID,MAAM,WAAW,WAAW;IAC1B,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CASpD;AAED,oDAAoD;AACpD,wBAAgB,cAAc,IAAI,WAAW,CAE5C;AAID;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,aAAa,CAoCf"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Compute visual transforms for a panel at a given depth.
3
+ * depth=0 is the top (foreground) panel.
4
+ */
5
+ export function getStackTransform(depth, stacking) {
6
+ if (depth <= 0) {
7
+ return { scale: 1, offset: 0, opacity: 1, borderRadius: 0 };
8
+ }
9
+ return {
10
+ scale: Math.max(0.5, 1 - depth * stacking.scaleStep),
11
+ offset: depth * stacking.offsetStep,
12
+ opacity: Math.max(0, 1 - depth * stacking.opacityStep),
13
+ borderRadius: stacking.radius,
14
+ };
15
+ }
16
+ /** Motion initial/exit values for sliding from the given side. */
17
+ export function getSlideFrom(side) {
18
+ switch (side) {
19
+ case "right":
20
+ return { x: "100%" };
21
+ case "left":
22
+ return { x: "-100%" };
23
+ case "bottom":
24
+ return { y: "100%" };
25
+ }
26
+ }
27
+ /** Motion animate target — the resting position. */
28
+ export function getSlideTarget() {
29
+ return { x: 0, y: 0 };
30
+ }
31
+ // ── Panel positioning ───────────────────────────
32
+ /**
33
+ * Fixed-position styles for a panel, accounting for side, width, and depth.
34
+ */
35
+ export function getPanelStyles(side, config, depth, index) {
36
+ const { width, maxWidth, zIndex } = config;
37
+ const base = {
38
+ position: "fixed",
39
+ zIndex: zIndex + 10 + index,
40
+ display: "flex",
41
+ flexDirection: "column",
42
+ overflow: "hidden",
43
+ willChange: "transform",
44
+ transformOrigin: side === "bottom" ? "center bottom" : `${side} center`,
45
+ };
46
+ if (side === "bottom") {
47
+ return {
48
+ ...base,
49
+ left: 0,
50
+ right: 0,
51
+ bottom: 0,
52
+ maxHeight: "85vh",
53
+ borderTopLeftRadius: depth > 0 ? config.stacking.radius : 16,
54
+ borderTopRightRadius: depth > 0 ? config.stacking.radius : 16,
55
+ };
56
+ }
57
+ // Left or right side panel
58
+ const sideStyles = side === "right"
59
+ ? { top: 0, right: 0, bottom: 0 }
60
+ : { top: 0, left: 0, bottom: 0 };
61
+ return {
62
+ ...base,
63
+ ...sideStyles,
64
+ width,
65
+ maxWidth,
66
+ };
67
+ }
68
+ //# sourceMappingURL=stacking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stacking.js","sourceRoot":"","sources":["../src/stacking.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,QAAwB;IAExB,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAC9D,CAAC;IACD,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC;QACpD,MAAM,EAAE,KAAK,GAAG,QAAQ,CAAC,UAAU;QACnC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC;QACtD,YAAY,EAAE,QAAQ,CAAC,MAAM;KAC9B,CAAC;AACJ,CAAC;AASD,kEAAkE;AAClE,MAAM,UAAU,YAAY,CAAC,IAAU;IACrC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,KAAK,QAAQ;YACX,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,cAAc;IAC5B,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACxB,CAAC;AAED,mDAAmD;AAEnD;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAU,EACV,MAAsB,EACtB,KAAa,EACb,KAAa;IAEb,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC3C,MAAM,IAAI,GAAkB;QAC1B,QAAQ,EAAE,OAAO;QACjB,MAAM,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK;QAC3B,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,QAAQ,EAAE,QAAQ;QAClB,UAAU,EAAE,WAAW;QACvB,eAAe,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,SAAS;KACxE,CAAC;IAEF,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO;YACL,GAAG,IAAI;YACP,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;YACT,SAAS,EAAE,MAAM;YACjB,mBAAmB,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YAC5D,oBAAoB,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;SAC9D,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,MAAM,UAAU,GACd,IAAI,KAAK,OAAO;QACd,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;QACjC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAErC,OAAO;QACL,GAAG,IAAI;QACP,GAAG,UAAU;QACb,KAAK;QACL,QAAQ;KACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type StoreApi } from "zustand";
2
+ import type { ResolvedConfig, SheetActions, SheetSnapshot } from "./types.js";
3
+ type StoreState<TMap extends Record<string, unknown>> = SheetSnapshot<TMap> & SheetActions<TMap>;
4
+ /**
5
+ * Create an isolated Zustand store for a sheet stack instance.
6
+ */
7
+ export declare function createSheetStore<TMap extends Record<string, unknown>>(config: ResolvedConfig): StoreApi<StoreState<TMap>>;
8
+ export {};
9
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EAEZ,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,KAAK,UAAU,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,GACzE,YAAY,CAAC,IAAI,CAAC,CAAC;AAErB;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnE,MAAM,EAAE,cAAc,GACrB,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAgF5B"}
package/dist/store.js ADDED
@@ -0,0 +1,73 @@
1
+ import { createStore } from "zustand";
2
+ /**
3
+ * Create an isolated Zustand store for a sheet stack instance.
4
+ */
5
+ export function createSheetStore(config) {
6
+ return createStore()((set, get) => ({
7
+ stack: [],
8
+ isOpen: false,
9
+ open(type, id, data) {
10
+ set({
11
+ stack: [{ id, type, data }],
12
+ isOpen: true,
13
+ });
14
+ },
15
+ push(type, id, data) {
16
+ set((state) => {
17
+ const item = { id, type, data };
18
+ if (Number.isFinite(config.maxDepth) &&
19
+ state.stack.length >= config.maxDepth) {
20
+ // Replace top at max depth
21
+ return {
22
+ stack: [...state.stack.slice(0, -1), item],
23
+ isOpen: true,
24
+ };
25
+ }
26
+ return {
27
+ stack: [...state.stack, item],
28
+ isOpen: true,
29
+ };
30
+ });
31
+ },
32
+ replace(type, id, data) {
33
+ set((state) => {
34
+ const item = { id, type, data };
35
+ if (state.stack.length === 0) {
36
+ return { stack: [item], isOpen: true };
37
+ }
38
+ return {
39
+ stack: [...state.stack.slice(0, -1), item],
40
+ isOpen: true,
41
+ };
42
+ });
43
+ },
44
+ navigate(type, id, data) {
45
+ const { stack } = get();
46
+ const top = stack.at(-1);
47
+ // Empty → open
48
+ if (stack.length === 0) {
49
+ get().open(type, id, data);
50
+ return;
51
+ }
52
+ // Same type on top → replace
53
+ if (top?.type === type) {
54
+ get().replace(type, id, data);
55
+ return;
56
+ }
57
+ // Different type → push
58
+ get().push(type, id, data);
59
+ },
60
+ pop() {
61
+ set((state) => {
62
+ if (state.stack.length <= 1) {
63
+ return { stack: [], isOpen: false };
64
+ }
65
+ return { stack: state.stack.slice(0, -1), isOpen: true };
66
+ });
67
+ },
68
+ close() {
69
+ set({ stack: [], isOpen: false });
70
+ },
71
+ }));
72
+ }
73
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import type { ComponentType } from "react";
2
+ export interface SheetItem<TType extends string = string> {
3
+ id: string;
4
+ type: TType;
5
+ data: Record<string, unknown>;
6
+ }
7
+ export type Side = "left" | "right" | "bottom";
8
+ export interface ResponsiveSide {
9
+ desktop: Side;
10
+ mobile: Side;
11
+ }
12
+ export type SideConfig = Side | ResponsiveSide;
13
+ export interface StackingConfig {
14
+ /** Scale reduction per depth level (default: 0.04) */
15
+ scaleStep: number;
16
+ /** Horizontal/vertical offset per depth level in px (default: 24) */
17
+ offsetStep: number;
18
+ /** Opacity reduction per depth level (default: 0.15) */
19
+ opacityStep: number;
20
+ /** Border radius applied to stacked panels in px (default: 12) */
21
+ radius: number;
22
+ /** Max depth before content stops rendering (default: 5) */
23
+ renderThreshold: number;
24
+ }
25
+ export interface SpringConfig {
26
+ /** Damping — higher = less oscillation (default: 30) */
27
+ damping: number;
28
+ /** Stiffness — higher = snappier (default: 170) */
29
+ stiffness: number;
30
+ /** Mass — higher = more momentum (default: 0.8) */
31
+ mass: number;
32
+ }
33
+ export interface SheetStackConfig {
34
+ /** Maximum stack depth. Default: Infinity (unlimited) */
35
+ maxDepth?: number;
36
+ /** Close on ESC key. Default: true */
37
+ closeOnEscape?: boolean;
38
+ /** Close on backdrop click. Default: true */
39
+ closeOnBackdrop?: boolean;
40
+ /** Lock body scroll when open. Default: true */
41
+ lockScroll?: boolean;
42
+ /** Panel width in px. Default: 420 */
43
+ width?: number;
44
+ /** Maximum panel width as CSS value. Default: "90vw" */
45
+ maxWidth?: string;
46
+ /** Mobile breakpoint in px. Default: 768 */
47
+ breakpoint?: number;
48
+ /** Sheet slide-from side. Default: { desktop: "right", mobile: "bottom" } */
49
+ side?: SideConfig;
50
+ /** Stacking visual parameters */
51
+ stacking?: Partial<StackingConfig>;
52
+ /** Spring animation parameters */
53
+ spring?: Partial<SpringConfig>;
54
+ /** Base z-index. Default: 100 */
55
+ zIndex?: number;
56
+ }
57
+ /** Fully resolved config — all fields required */
58
+ export interface ResolvedConfig {
59
+ maxDepth: number;
60
+ closeOnEscape: boolean;
61
+ closeOnBackdrop: boolean;
62
+ lockScroll: boolean;
63
+ width: number;
64
+ maxWidth: string;
65
+ breakpoint: number;
66
+ side: ResponsiveSide;
67
+ stacking: StackingConfig;
68
+ spring: SpringConfig;
69
+ zIndex: number;
70
+ }
71
+ /** Component rendered inside a sheet panel */
72
+ export type SheetContentComponent<TData = unknown> = ComponentType<{
73
+ data: TData;
74
+ onClose: () => void;
75
+ }>;
76
+ /** Map of sheet type → content component */
77
+ export type ContentMap<TMap extends Record<string, unknown>> = {
78
+ [K in keyof TMap]: SheetContentComponent<TMap[K]>;
79
+ };
80
+ export interface SheetSnapshot<TMap extends Record<string, unknown>> {
81
+ stack: SheetItem<Extract<keyof TMap, string>>[];
82
+ isOpen: boolean;
83
+ }
84
+ export interface SheetActions<TMap extends Record<string, unknown>> {
85
+ /** Replace stack with a single item */
86
+ open<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void;
87
+ /** Push onto stack (replaces top at maxDepth) */
88
+ push<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void;
89
+ /** Swap the top item */
90
+ replace<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void;
91
+ /** Smart: empty→open, same type on top→replace, different→push */
92
+ navigate<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void;
93
+ /** Pop top item; close if last */
94
+ pop(): void;
95
+ /** Clear entire stack */
96
+ close(): void;
97
+ }
98
+ export interface SheetStackInstance<TMap extends Record<string, unknown>> {
99
+ /** Provider component — wrap your app, pass content map */
100
+ SheetProvider: ComponentType<{
101
+ content: ContentMap<TMap>;
102
+ children: React.ReactNode;
103
+ }>;
104
+ /** Hook returning sheet actions */
105
+ useSheet: () => SheetActions<TMap>;
106
+ /** Hook returning sheet state (stack, isOpen) */
107
+ useSheetState: () => SheetSnapshot<TMap>;
108
+ /** Raw Zustand store for advanced use */
109
+ store: import("zustand").StoreApi<SheetSnapshot<TMap> & SheetActions<TMap>>;
110
+ }
111
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAI3C,MAAM,WAAW,SAAS,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAID,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,IAAI,CAAC;CACd;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,cAAc,CAAC;AAI/C,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;CACd;AAID,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gDAAgD;IAChD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC,kCAAkC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kDAAkD;AAClD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,8CAA8C;AAC9C,MAAM,MAAM,qBAAqB,CAAC,KAAK,GAAG,OAAO,IAAI,aAAa,CAAC;IACjE,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC,CAAC;AAEH,4CAA4C;AAC5C,MAAM,MAAM,UAAU,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KAC5D,CAAC,IAAI,MAAM,IAAI,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CAClD,CAAC;AAIF,MAAM,WAAW,aAAa,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IAChD,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAY,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChE,uCAAuC;IACvC,IAAI,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,EACxC,IAAI,EAAE,CAAC,EACP,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GACZ,IAAI,CAAC;IACR,iDAAiD;IACjD,IAAI,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,EACxC,IAAI,EAAE,CAAC,EACP,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GACZ,IAAI,CAAC;IACR,wBAAwB;IACxB,OAAO,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,EAC3C,IAAI,EAAE,CAAC,EACP,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GACZ,IAAI,CAAC;IACR,kEAAkE;IAClE,QAAQ,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,EAC5C,IAAI,EAAE,CAAC,EACP,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GACZ,IAAI,CAAC;IACR,kCAAkC;IAClC,GAAG,IAAI,IAAI,CAAC;IACZ,yBAAyB;IACzB,KAAK,IAAI,IAAI,CAAC;CACf;AAID,MAAM,WAAW,kBAAkB,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACtE,2DAA2D;IAC3D,aAAa,EAAE,aAAa,CAAC;QAC3B,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;KAC3B,CAAC,CAAC;IACH,mCAAmC;IACnC,QAAQ,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACnC,iDAAiD;IACjD,aAAa,EAAE,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IACzC,yCAAyC;IACzC,KAAK,EAAE,OAAO,SAAS,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;CAC7E"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@howells/stacksheet",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "Typed, animated sheet stack system. Zustand store + Motion animations with Apple-style depth stacking.",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "license": "MIT",
9
+ "author": "Daniel Howells",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+ssh://git@github.com/howells/stacksheet.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/howells/stacksheet/issues"
16
+ },
17
+ "homepage": "https://github.com/howells/stacksheet#readme",
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ }
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "engines": {
31
+ "node": ">=20"
32
+ },
33
+ "keywords": [
34
+ "sheet",
35
+ "drawer",
36
+ "modal",
37
+ "stack",
38
+ "zustand",
39
+ "motion",
40
+ "react",
41
+ "animation"
42
+ ],
43
+ "dependencies": {
44
+ "zustand": "^5.0.0",
45
+ "motion": "^12.0.0"
46
+ },
47
+ "peerDependencies": {
48
+ "react": "^18.0.0 || ^19.0.0",
49
+ "react-dom": "^18.0.0 || ^19.0.0"
50
+ },
51
+ "devDependencies": {
52
+ "@types/react": "^19.0.0",
53
+ "@types/react-dom": "^19.0.0",
54
+ "typescript": "^5.7.0"
55
+ },
56
+ "scripts": {
57
+ "build": "tsc -p tsconfig.json",
58
+ "dev": "tsc -p tsconfig.json -w",
59
+ "typecheck": "tsc -p tsconfig.json --noEmit"
60
+ }
61
+ }