@patternmode/stacksheet 1.3.3
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 +21 -0
- package/README.md +191 -0
- package/dist/Drag/DragConstants.d.ts +9 -0
- package/dist/Drag/DragConstants.d.ts.map +1 -0
- package/dist/Drag/DragGeometry.d.ts +34 -0
- package/dist/Drag/DragGeometry.d.ts.map +1 -0
- package/dist/Drag/DragTypes.d.ts +34 -0
- package/dist/Drag/DragTypes.d.ts.map +1 -0
- package/dist/Drag/index.d.ts +3 -0
- package/dist/Drag/index.d.ts.map +1 -0
- package/dist/Drag/useDrag.d.ts +20 -0
- package/dist/Drag/useDrag.d.ts.map +1 -0
- package/dist/SheetPanel/DefaultHeader.d.ts +5 -0
- package/dist/SheetPanel/DefaultHeader.d.ts.map +1 -0
- package/dist/SheetPanel/SheetPanel.d.ts +3 -0
- package/dist/SheetPanel/SheetPanel.d.ts.map +1 -0
- package/dist/SheetPanel/SheetPanelContent.d.ts +13 -0
- package/dist/SheetPanel/SheetPanelContent.d.ts.map +1 -0
- package/dist/SheetPanel/SheetPanelFocus.d.ts +8 -0
- package/dist/SheetPanel/SheetPanelFocus.d.ts.map +1 -0
- package/dist/SheetPanel/SheetPanelHandles.d.ts +10 -0
- package/dist/SheetPanel/SheetPanelHandles.d.ts.map +1 -0
- package/dist/SheetPanel/SheetPanelTypes.d.ts +31 -0
- package/dist/SheetPanel/SheetPanelTypes.d.ts.map +1 -0
- package/dist/SheetPanel/index.d.ts +3 -0
- package/dist/SheetPanel/index.d.ts.map +1 -0
- package/dist/SheetParts/SheetBack.d.ts +3 -0
- package/dist/SheetParts/SheetBack.d.ts.map +1 -0
- package/dist/SheetParts/SheetBody.d.ts +3 -0
- package/dist/SheetParts/SheetBody.d.ts.map +1 -0
- package/dist/SheetParts/SheetClose.d.ts +3 -0
- package/dist/SheetParts/SheetClose.d.ts.map +1 -0
- package/dist/SheetParts/SheetDescription.d.ts +3 -0
- package/dist/SheetParts/SheetDescription.d.ts.map +1 -0
- package/dist/SheetParts/SheetFooter.d.ts +3 -0
- package/dist/SheetParts/SheetFooter.d.ts.map +1 -0
- package/dist/SheetParts/SheetHandle.d.ts +3 -0
- package/dist/SheetParts/SheetHandle.d.ts.map +1 -0
- package/dist/SheetParts/SheetHeader.d.ts +3 -0
- package/dist/SheetParts/SheetHeader.d.ts.map +1 -0
- package/dist/SheetParts/SheetPartTypes.d.ts +22 -0
- package/dist/SheetParts/SheetPartTypes.d.ts.map +1 -0
- package/dist/SheetParts/SheetParts.d.ts +28 -0
- package/dist/SheetParts/SheetParts.d.ts.map +1 -0
- package/dist/SheetParts/SheetTitle.d.ts +3 -0
- package/dist/SheetParts/SheetTitle.d.ts.map +1 -0
- package/dist/SheetParts/index.d.ts +11 -0
- package/dist/SheetParts/index.d.ts.map +1 -0
- package/dist/Store/StoreArgs.d.ts +15 -0
- package/dist/Store/StoreArgs.d.ts.map +1 -0
- package/dist/Store/StoreTypes.d.ts +21 -0
- package/dist/Store/StoreTypes.d.ts.map +1 -0
- package/dist/Store/createSheetStore.d.ts +15 -0
- package/dist/Store/createSheetStore.d.ts.map +1 -0
- package/dist/Store/index.d.ts +3 -0
- package/dist/Store/index.d.ts.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/create.d.ts +33 -0
- package/dist/create.d.ts.map +1 -0
- package/dist/icons.d.ts +4 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +1732 -0
- package/dist/index.mjs.map +1 -0
- package/dist/media.d.ts +9 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/panel-context.d.ts +26 -0
- package/dist/panel-context.d.ts.map +1 -0
- package/dist/parts.d.ts +11 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/renderer-effects.d.ts +6 -0
- package/dist/renderer-effects.d.ts.map +1 -0
- package/dist/renderer-helpers.d.ts +53 -0
- package/dist/renderer-helpers.d.ts.map +1 -0
- package/dist/renderer.d.ts +29 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/sheet-panel.d.ts +3 -0
- package/dist/sheet-panel.d.ts.map +1 -0
- package/dist/snap-points.d.ts +22 -0
- package/dist/snap-points.d.ts.map +1 -0
- package/dist/springs.d.ts +26 -0
- package/dist/springs.d.ts.map +1 -0
- package/dist/stacking.d.ts +38 -0
- package/dist/stacking.d.ts.map +1 -0
- package/dist/store.d.ts +3 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/types.d.ts +232 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/use-drag.d.ts +3 -0
- package/dist/use-drag.d.ts.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["m","m","m","ScrollAreaRoot","ScrollAreaViewport","ScrollAreaScrollbar","ScrollAreaThumb"],"sources":["../src/springs.ts","../src/config.ts","../src/media.ts","../src/renderer-effects.ts","../src/snap-points.ts","../src/renderer-helpers.ts","../src/Drag/DragConstants.ts","../src/Drag/DragGeometry.ts","../src/Drag/useDrag.ts","../src/panel-context.tsx","../src/stacking.ts","../src/icons.tsx","../src/SheetPanel/DefaultHeader.tsx","../src/SheetPanel/SheetPanelContent.tsx","../src/SheetPanel/SheetPanelFocus.tsx","../src/SheetPanel/SheetPanelHandles.tsx","../src/SheetPanel/SheetPanel.tsx","../src/renderer.tsx","../src/Store/StoreArgs.ts","../src/Store/createSheetStore.ts","../src/create.tsx","../src/SheetParts/SheetBack.tsx","../src/SheetParts/SheetBody.tsx","../src/SheetParts/SheetClose.tsx","../src/SheetParts/SheetDescription.tsx","../src/SheetParts/SheetFooter.tsx","../src/SheetParts/SheetHandle.tsx","../src/SheetParts/SheetHeader.tsx","../src/SheetParts/SheetTitle.tsx","../src/SheetParts/SheetParts.ts"],"sourcesContent":["import type { SpringConfig } from \"./types\";\n\n/**\n * Spring presets inspired by iOS animation feel.\n *\n * - `subtle` — Barely noticeable bounce, professional.\n * - `snappy` — Quick, responsive for interactions.\n * - `stiff` — Very quick, controlled. Panels, drawers. **(default)**\n */\nexport const springs = {\n\tsubtle: { stiffness: 300, damping: 30, mass: 1 },\n\tsnappy: { stiffness: 400, damping: 28, mass: 0.8 },\n\tstiff: { stiffness: 400, damping: 40, mass: 1 },\n} as const satisfies Record<string, SpringConfig>;\n\nexport type SpringPreset = keyof typeof springs;\n","import type { SpringPreset } from \"./springs\";\nimport { springs } from \"./springs\";\nimport type {\n\tResolvedConfig,\n\tResponsiveSide,\n\tSideConfig,\n\tSpringConfig,\n\tStackingConfig,\n\tStacksheetConfig,\n} from \"./types\";\n\n// ── Defaults ────────────────────────────────────\n\nconst DEFAULT_STACKING: StackingConfig = {\n\tscaleStep: 0.04,\n\toffsetStep: 16,\n\topacityStep: 0,\n\tradius: 12,\n\trenderThreshold: 3,\n};\n\nconst DEFAULT_SIDE: ResponsiveSide = {\n\tdesktop: \"right\",\n\tmobile: \"bottom\",\n};\n\n// ── Helpers ─────────────────────────────────────\n\n/** Normalize a string side to a responsive object, merging with defaults. */\nfunction resolveSide(side: SideConfig | undefined): ResponsiveSide {\n\tif (typeof side === \"string\") {\n\t\treturn { desktop: side, mobile: side };\n\t}\n\treturn { ...DEFAULT_SIDE, ...side };\n}\n\n/** Resolve a preset name to a SpringConfig, or merge partial config with defaults. */\nfunction resolveSpring(\n\tspring: SpringPreset | Partial<SpringConfig> | undefined,\n): SpringConfig {\n\tif (typeof spring === \"string\") {\n\t\treturn springs[spring];\n\t}\n\treturn { ...springs.stiff, ...spring };\n}\n\n// ── Resolver ────────────────────────────────────\n\n/** Merge user-provided config with defaults. Resolves union types (side, spring) to concrete values. */\nexport function resolveConfig(config: StacksheetConfig = {}): ResolvedConfig {\n\treturn {\n\t\tmaxDepth: config.maxDepth ?? Number.POSITIVE_INFINITY,\n\t\tcloseOnEscape: config.closeOnEscape ?? true,\n\t\tcloseOnBackdrop: config.closeOnBackdrop ?? true,\n\t\tshowOverlay: config.showOverlay ?? true,\n\t\tlockScroll: config.lockScroll ?? true,\n\t\twidth: config.width ?? 420,\n\t\tmaxWidth: config.maxWidth ?? \"90vw\",\n\t\tbreakpoint: config.breakpoint ?? 768,\n\t\tside: resolveSide(config.side),\n\t\tstacking: { ...DEFAULT_STACKING, ...config.stacking },\n\t\tspring: resolveSpring(config.spring),\n\t\tzIndex: config.zIndex ?? 100,\n\t\tariaLabel: config.ariaLabel ?? \"Sheet dialog\",\n\t\tonOpenComplete: config.onOpenComplete,\n\t\tonCloseComplete: config.onCloseComplete,\n\t\tsnapPoints: config.snapPoints ?? [],\n\t\tsnapPointIndex: config.snapPointIndex,\n\t\tonSnapPointChange: config.onSnapPointChange,\n\t\tsnapToSequentialPoints: config.snapToSequentialPoints ?? false,\n\t\tdrag: config.drag ?? true,\n\t\tcloseThreshold: config.closeThreshold ?? 0.25,\n\t\tvelocityThreshold: config.velocityThreshold ?? 0.5,\n\t\tdismissible: config.dismissible ?? true,\n\t\tmodal: config.modal ?? true,\n\t\tshouldScaleBackground: config.shouldScaleBackground ?? false,\n\t\tscaleBackgroundAmount: config.scaleBackgroundAmount ?? 0.97,\n\t};\n}\n","import { useEffect, useState } from \"react\";\nimport type { ResolvedConfig, Side } from \"./types\";\n\n/**\n * Returns true when viewport width is at or below the breakpoint.\n * SSR-safe: defaults to false (desktop).\n */\nexport function useIsMobile(breakpoint: number): boolean {\n\tconst [isMobile, setIsMobile] = useState(false);\n\n\tuseEffect(() => {\n\t\tconst mql = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n\t\tsetIsMobile(mql.matches);\n\n\t\tconst handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n\t\tmql.addEventListener(\"change\", handler);\n\t\treturn () => mql.removeEventListener(\"change\", handler);\n\t}, [breakpoint]);\n\n\treturn isMobile;\n}\n\n/** Resolve the current side from config + viewport. */\nexport function useResolvedSide(config: ResolvedConfig): Side {\n\tconst isMobile = useIsMobile(config.breakpoint);\n\treturn isMobile ? config.side.mobile : config.side.desktop;\n}\n","import { type RefObject, useCallback, useEffect, useState } from \"react\";\nimport type { ResolvedConfig } from \"./types\";\n\nexport function usePanelHeight(\n\tpanelRef: RefObject<HTMLDivElement | null>,\n\thasSnapPoints: boolean,\n): number {\n\tconst [height, setHeight] = useState(0);\n\n\tuseEffect(() => {\n\t\tconst el = panelRef.current;\n\t\tif (!(el && hasSnapPoints)) {\n\t\t\treturn;\n\t\t}\n\t\tsetHeight(el.offsetHeight);\n\t\tconst observer = new ResizeObserver(([entry]) => {\n\t\t\tif (entry) {\n\t\t\t\tsetHeight(entry.contentRect.height);\n\t\t\t}\n\t\t});\n\t\tobserver.observe(el);\n\t\treturn () => observer.disconnect();\n\t}, [panelRef, hasSnapPoints]);\n\n\treturn height;\n}\n\nexport function useViewportHeight(active: boolean): number {\n\tconst getHeight = useCallback(\n\t\t() =>\n\t\t\ttypeof window === \"undefined\"\n\t\t\t\t? 0\n\t\t\t\t: (window.visualViewport?.height ?? window.innerHeight),\n\t\t[],\n\t);\n\tconst [height, setHeight] = useState(() => getHeight());\n\n\tuseEffect(() => {\n\t\tif (!active || typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst update = () => setHeight(getHeight());\n\t\tupdate();\n\n\t\twindow.addEventListener(\"resize\", update);\n\t\twindow.visualViewport?.addEventListener(\"resize\", update);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"resize\", update);\n\t\t\twindow.visualViewport?.removeEventListener(\"resize\", update);\n\t\t};\n\t}, [active, getHeight]);\n\n\treturn height;\n}\n\nexport function useBodyScale(\n\tconfig: ResolvedConfig,\n\tisOpen: boolean,\n\tprefersReducedMotion: boolean,\n) {\n\tuseEffect(() => {\n\t\tif (!config.shouldScaleBackground || prefersReducedMotion) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst wrapper = document.querySelector(\"[data-stacksheet-wrapper]\");\n\t\tif (!(wrapper && wrapper instanceof HTMLElement)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (isOpen) {\n\t\t\tconst scale = config.scaleBackgroundAmount;\n\t\t\twrapper.style.transition =\n\t\t\t\t\"transform 500ms cubic-bezier(0.32, 0.72, 0, 1), border-radius 500ms cubic-bezier(0.32, 0.72, 0, 1)\";\n\t\t\twrapper.style.transform = `scale(${scale})`;\n\t\t\twrapper.style.borderRadius = \"8px\";\n\t\t\twrapper.style.overflow = \"hidden\";\n\t\t\twrapper.style.transformOrigin = \"center top\";\n\t\t\treturn;\n\t\t}\n\n\t\twrapper.style.transform = \"\";\n\t\twrapper.style.borderRadius = \"\";\n\t\tconst handleEnd = () => {\n\t\t\twrapper.style.transition = \"\";\n\t\t\twrapper.style.overflow = \"\";\n\t\t\twrapper.style.transformOrigin = \"\";\n\t\t};\n\t\twrapper.addEventListener(\"transitionend\", handleEnd, { once: true });\n\t\treturn () => wrapper.removeEventListener(\"transitionend\", handleEnd);\n\t}, [\n\t\tisOpen,\n\t\tconfig.shouldScaleBackground,\n\t\tconfig.scaleBackgroundAmount,\n\t\tprefersReducedMotion,\n\t]);\n}\n","import type { SnapPoint } from \"./types\";\n\nconst SNAP_POINT_RE = /^(\\d+(?:\\.\\d+)?)(px|rem|em|vh|%)$/;\n\n/**\n * Resolve a snap point value to pixels given the viewport height.\n * - number 0-1: fraction of viewport (0.5 → 50% of vh)\n * - number > 1: pixel value (300 → 300px)\n * - string: parsed via regex for CSS unit support\n */\nfunction resolveSnapPointPx(point: SnapPoint, viewportHeight: number): number {\n\tif (typeof point === \"number\") {\n\t\treturn point <= 1 ? point * viewportHeight : point;\n\t}\n\n\tif (typeof point === \"string\") {\n\t\tconst match = point.match(SNAP_POINT_RE);\n\t\tif (!match?.[1]) {\n\t\t\treturn 0;\n\t\t}\n\t\tconst value = Number.parseFloat(match[1]);\n\t\tconst unit = match[2];\n\t\tswitch (unit) {\n\t\t\tcase \"px\":\n\t\t\t\treturn value;\n\t\t\tcase \"rem\":\n\t\t\tcase \"em\": {\n\t\t\t\tconst fontSize =\n\t\t\t\t\ttypeof document === \"undefined\"\n\t\t\t\t\t\t? 16\n\t\t\t\t\t\t: Number.parseFloat(\n\t\t\t\t\t\t\t\tgetComputedStyle(document.documentElement).fontSize,\n\t\t\t\t\t\t\t);\n\t\t\t\treturn value * fontSize;\n\t\t\t}\n\t\t\tcase \"vh\":\n\t\t\tcase \"%\":\n\t\t\t\treturn (value / 100) * viewportHeight;\n\t\t\tdefault:\n\t\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/**\n * Resolve all snap points to sorted pixel heights (ascending).\n * Returns an array of heights in px that the drawer should snap to.\n */\nexport function resolveSnapPoints(\n\tpoints: SnapPoint[],\n\tviewportHeight: number,\n): number[] {\n\tif (points.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst resolved = points\n\t\t.map((p) => resolveSnapPointPx(p, viewportHeight))\n\t\t.filter((px) => px > 0);\n\n\t// Sort ascending (smallest snap point first)\n\tresolved.sort((a, b) => a - b);\n\n\t// Deduplicate (1px tolerance)\n\tconst deduped: number[] = [];\n\tfor (const px of resolved) {\n\t\tconst last = deduped.at(-1);\n\t\tif (last === undefined || Math.abs(px - last) > 1) {\n\t\t\tdeduped.push(px);\n\t\t}\n\t}\n\n\treturn deduped;\n}\n\n/** Velocity threshold (px/ms) for skipping intermediate snap points */\nconst SNAP_VELOCITY_THRESHOLD = 0.4;\n\n/** Max velocity to consider for snap offset calculation */\nconst MAX_SNAP_VELOCITY = 2;\n\n/** Multiplier to convert velocity to pixel offset for snap target */\nconst SNAP_VELOCITY_MULTIPLIER = 150;\n\n/**\n * Given the current drag offset (from fully open), resolved snap heights,\n * the panel height, and release velocity, find the best snap point index.\n *\n * `dragOffset` is positive in the dismiss direction (downward for bottom sheets).\n * Snap heights are \"how tall the drawer should be\" (ascending order).\n *\n * Returns -1 if the gesture indicates full dismissal.\n */\nexport function findSnapTarget(\n\tdragOffset: number,\n\tpanelHeight: number,\n\tsnapHeights: number[],\n\tvelocity: number,\n\tcurrentIndex: number,\n\tsequential: boolean,\n): number {\n\tif (snapHeights.length === 0) {\n\t\treturn -1;\n\t}\n\n\t// Convert snap heights to offsets from fully open (panelHeight = 0 offset)\n\t// A smaller snap height = larger offset from top = more closed\n\tconst snapOffsets = snapHeights.map((h) => panelHeight - h);\n\n\t// Current position = dragOffset from fully open\n\tconst currentPos = dragOffset;\n\n\tif (sequential) {\n\t\t// Sequential mode: only snap to adjacent points\n\t\tconst direction = velocity > 0 ? 1 : -1; // positive = dismissing\n\t\tconst nextIndex = currentIndex - direction; // snap heights are ascending, so -1 = more closed\n\t\tif (nextIndex < 0) {\n\t\t\treturn -1; // dismiss\n\t\t}\n\t\tif (nextIndex >= snapHeights.length) {\n\t\t\treturn snapHeights.length - 1; // fully open\n\t\t}\n\t\treturn nextIndex;\n\t}\n\n\t// Velocity-based: project position forward based on velocity\n\tconst velocityOffset =\n\t\tMath.abs(velocity) >= SNAP_VELOCITY_THRESHOLD\n\t\t\t? Math.min(Math.max(velocity, -MAX_SNAP_VELOCITY), MAX_SNAP_VELOCITY) *\n\t\t\t\tSNAP_VELOCITY_MULTIPLIER\n\t\t\t: 0;\n\n\tconst projectedPos = currentPos + velocityOffset;\n\n\t// Find nearest snap offset to projected position\n\tconst first = snapOffsets[0] ?? 0;\n\tlet bestIndex = 0;\n\tlet bestDist = Math.abs(projectedPos - first);\n\n\tfor (let i = 1; i < snapOffsets.length; i++) {\n\t\tconst offset = snapOffsets[i] ?? 0;\n\t\tconst dist = Math.abs(projectedPos - offset);\n\t\tif (dist < bestDist) {\n\t\t\tbestDist = dist;\n\t\t\tbestIndex = i;\n\t\t}\n\t}\n\n\t// Check if dismissal is closer than (or equal to) any snap point.\n\t// Ties favor dismiss — the user dragged past the last snap point.\n\tconst dismissDist = Math.abs(projectedPos - panelHeight);\n\tif (dismissDist <= bestDist) {\n\t\treturn -1;\n\t}\n\n\treturn bestIndex;\n}\n\n/**\n * Get the Y offset for a snap point relative to fully open (0 offset).\n * Returns the number of pixels the drawer should be translated down from fully open.\n */\nexport function getSnapOffset(\n\tsnapIndex: number,\n\tsnapHeights: number[],\n\tpanelHeight: number,\n): number {\n\tif (snapIndex < 0 || snapIndex >= snapHeights.length) {\n\t\treturn 0;\n\t}\n\tconst targetHeight = snapHeights[snapIndex] ?? 0;\n\treturn panelHeight - targetHeight;\n}\n","import type { CSSProperties } from \"react\";\nimport { getSnapOffset } from \"./snap-points\";\nimport type { getStackTransform, SlideValues } from \"./stacking\";\nimport type { Side, StacksheetClassNames } from \"./types\";\n\nexport type ResolvedClassNames = Required<StacksheetClassNames>;\n\nconst EMPTY_CLASSNAMES: ResolvedClassNames = {\n\tbackdrop: \"\",\n\tpanel: \"\",\n\theader: \"\",\n};\n\nexport function resolveClassNames(\n\tcn?: StacksheetClassNames,\n): ResolvedClassNames {\n\tif (!cn) {\n\t\treturn EMPTY_CLASSNAMES;\n\t}\n\treturn {\n\t\tbackdrop: cn.backdrop ?? \"\",\n\t\tpanel: cn.panel ?? \"\",\n\t\theader: cn.header ?? \"\",\n\t};\n}\n\nexport function buildAriaProps(\n\tisTop: boolean,\n\tisModal: boolean,\n\tisComposable: boolean,\n\tariaLabel: string,\n\tpanelId: string,\n\thasDescription: boolean,\n): Record<string, string | undefined> {\n\tif (!isTop) {\n\t\treturn {};\n\t}\n\tconst props: Record<string, string | undefined> = { role: \"dialog\" };\n\tif (isModal) {\n\t\tprops[\"aria-modal\"] = \"true\";\n\t}\n\tif (isComposable) {\n\t\tprops[\"aria-labelledby\"] = `${panelId}-title`;\n\t\tif (hasDescription) {\n\t\t\tprops[\"aria-describedby\"] = `${panelId}-desc`;\n\t\t}\n\t} else {\n\t\tprops[\"aria-label\"] = ariaLabel;\n\t}\n\treturn props;\n}\n\nexport function getDragTransform(\n\tside: Side,\n\toffset: number,\n): { x?: number; y?: number } {\n\tif (offset === 0) {\n\t\treturn {};\n\t}\n\tswitch (side) {\n\t\tcase \"right\":\n\t\t\treturn { x: offset };\n\t\tcase \"left\":\n\t\t\treturn { x: -offset };\n\t\tcase \"bottom\":\n\t\t\treturn { y: offset };\n\t\tdefault:\n\t\t\treturn {};\n\t}\n}\n\nexport const VISUAL_TWEEN = {\n\ttype: \"tween\" as const,\n\tduration: 0.25,\n\tease: \"easeOut\" as const,\n};\n\nexport function buildPanelStyle(\n\tpanelStyles: CSSProperties,\n\tisTop: boolean,\n\thasPanelClass: boolean,\n\tisDragging: boolean,\n): CSSProperties {\n\treturn {\n\t\t...panelStyles,\n\t\tpointerEvents: isTop ? \"auto\" : \"none\",\n\t\t...(isTop ? {} : { contain: \"layout style paint\" }),\n\t\t...(isDragging ? { transition: \"none\" } : {}),\n\t\t...(hasPanelClass\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\tbackground: \"var(--background, #fff)\",\n\t\t\t\t\tborderColor: \"var(--border, transparent)\",\n\t\t\t\t}),\n\t};\n}\n\nexport function buildPanelTransition(\n\tisDragging: boolean,\n\tisTop: boolean,\n\tspring: Record<string, unknown>,\n\tstackSpring: Record<string, unknown>,\n) {\n\tif (isDragging) {\n\t\treturn { type: \"tween\" as const, duration: 0 };\n\t}\n\n\tconst base = isTop ? spring : stackSpring;\n\treturn { ...base, borderRadius: VISUAL_TWEEN, boxShadow: VISUAL_TWEEN };\n}\n\nexport function computeSnapYOffset(\n\tside: Side,\n\tsnapHeights: number[],\n\tactiveSnapIndex: number,\n\tmeasuredHeight: number,\n): number {\n\tif (side !== \"bottom\" || snapHeights.length === 0 || measuredHeight <= 0) {\n\t\treturn 0;\n\t}\n\treturn getSnapOffset(activeSnapIndex, snapHeights, measuredHeight);\n}\n\nexport function getBottomSlideDistance(measuredHeight: number): number {\n\tif (measuredHeight > 0) {\n\t\treturn measuredHeight;\n\t}\n\tif (typeof window !== \"undefined\") {\n\t\treturn window.innerHeight;\n\t}\n\treturn 1000;\n}\n\nexport function resolveSlideFrom(\n\tside: Side,\n\tslideFrom: SlideValues,\n\tmeasuredHeight: number,\n): SlideValues {\n\tif (side !== \"bottom\") {\n\t\treturn slideFrom;\n\t}\n\treturn { y: getBottomSlideDistance(measuredHeight) };\n}\n\nexport function buildAnimateTarget(\n\tslideTarget: SlideValues,\n\tstackOffset: { x?: number; y?: number },\n\tdragOffset: { x?: number; y?: number },\n\ttransform: ReturnType<typeof getStackTransform>,\n\tanimatedRadius: Record<string, number>,\n\ttransition: Record<string, unknown>,\n\tsnapYOffset: number,\n\tisTop: boolean,\n) {\n\tconst base = {\n\t\t...slideTarget,\n\t\t...stackOffset,\n\t\t...dragOffset,\n\t\tscale: transform.scale,\n\t\topacity: transform.opacity,\n\t\t...animatedRadius,\n\t\tboxShadow: getShadow(!isTop),\n\t\ttransition,\n\t};\n\n\tif (snapYOffset > 0) {\n\t\treturn { ...base, y: (dragOffset.y ?? 0) + snapYOffset };\n\t}\n\treturn base;\n}\n\nexport function getInitialRadius(side: Side): Record<string, number> {\n\tif (side === \"bottom\") {\n\t\treturn {\n\t\t\tborderTopLeftRadius: 0,\n\t\t\tborderTopRightRadius: 0,\n\t\t\tborderBottomLeftRadius: 0,\n\t\t\tborderBottomRightRadius: 0,\n\t\t};\n\t}\n\treturn { borderRadius: 0 };\n}\n\nconst SHADOW_SM =\n\t\"0px 1px 3px 0px rgba(0,0,0,0.06), 0px 6px 12px 0px rgba(0,0,0,0.06)\";\nconst SHADOW_LG =\n\t\"0px 8px 24px 0px rgba(0,0,0,0.06), 0px 24px 48px 0px rgba(0,0,0,0.04), 0px 48px 96px 0px rgba(0,0,0,0.03)\";\n\nexport function getShadow(isNested: boolean): string {\n\treturn isNested ? SHADOW_SM : SHADOW_LG;\n}\n","/** Elements that should never initiate a drag */\nexport const INTERACTIVE_TAGS = new Set([\n\t\"INPUT\",\n\t\"TEXTAREA\",\n\t\"SELECT\",\n\t\"BUTTON\",\n\t\"A\",\n]);\n\n/** Dead zone in px before committing to drag vs text selection */\nexport const DEAD_ZONE = 10;\n\n/** Max angle (degrees) from dismiss axis to qualify as drag intent */\nexport const MAX_ANGLE_DEG = 35;\n\n/** Rubber-band resistance factor for dragging past resting position */\nexport const RUBBER_BAND_FACTOR = 0.6;\n","import type { Side } from \"../types\";\nimport { INTERACTIVE_TAGS, MAX_ANGLE_DEG } from \"./DragConstants\";\nimport type { DragAxis, DragSign } from \"./DragTypes\";\n\nexport function isInteractiveElement(el: Element): boolean {\n\tif (INTERACTIVE_TAGS.has(el.tagName)) {\n\t\treturn true;\n\t}\n\tif ((el as HTMLElement).isContentEditable) {\n\t\treturn true;\n\t}\n\t// Children of interactive elements (e.g. SVG inside button, span inside link)\n\tif (el.closest(\"button, a, input, textarea, select, [contenteditable]\")) {\n\t\treturn true;\n\t}\n\tif (el.closest(\"[data-stacksheet-no-drag]\")) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Walk up from `el` to find the nearest scrollable ancestor.\n * Returns null if nothing is scrollable in the dismiss axis.\n */\nexport function findScrollableAncestor(\n\tel: Element,\n\taxis: DragAxis,\n): Element | null {\n\tlet current: Element | null = el;\n\twhile (current) {\n\t\tif (current instanceof HTMLElement) {\n\t\t\tconst style = getComputedStyle(current);\n\t\t\tconst overflow = axis === \"y\" ? style.overflowY : style.overflowX;\n\t\t\tif (overflow === \"auto\" || overflow === \"scroll\") {\n\t\t\t\tconst scrollable =\n\t\t\t\t\taxis === \"y\"\n\t\t\t\t\t\t? current.scrollHeight > current.clientHeight\n\t\t\t\t\t\t: current.scrollWidth > current.clientWidth;\n\t\t\t\tif (scrollable) {\n\t\t\t\t\treturn current;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcurrent = current.parentElement;\n\t}\n\treturn null;\n}\n\n/**\n * Check if a scrollable element is at its edge in the dismiss direction.\n * For bottom sheets (sign=1, axis=y), \"at edge\" means scrolled to top.\n * For left panels (sign=-1, axis=x), \"at edge\" means scrolled to right end.\n */\nexport function isAtScrollEdge(\n\tel: Element,\n\taxis: DragAxis,\n\tsign: DragSign,\n): boolean {\n\tif (axis === \"y\") {\n\t\t// Dismiss down (sign=1): at edge when scrollTop ≈ 0\n\t\t// Dismiss up (sign=-1): at edge when scrolled to bottom\n\t\treturn sign === 1\n\t\t\t? el.scrollTop <= 0\n\t\t\t: el.scrollTop + el.clientHeight >= el.scrollHeight - 1;\n\t}\n\treturn sign === 1\n\t\t? el.scrollLeft <= 0\n\t\t: el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;\n}\n\n/**\n * Get the dismiss direction axis and sign for a given side.\n * - right panel → dismiss by dragging right (+x)\n * - left panel → dismiss by dragging left (-x)\n * - bottom panel → dismiss by dragging down (+y)\n */\nexport function getDismissAxis(side: Side): {\n\taxis: DragAxis;\n\tsign: DragSign;\n} {\n\tswitch (side) {\n\t\tcase \"right\":\n\t\t\treturn { axis: \"x\", sign: 1 };\n\t\tcase \"left\":\n\t\t\treturn { axis: \"x\", sign: -1 };\n\t\tcase \"bottom\":\n\t\t\treturn { axis: \"y\", sign: 1 };\n\t\tdefault:\n\t\t\treturn { axis: \"x\", sign: 1 };\n\t}\n}\n\n/**\n * Decide whether a gesture past the dead zone qualifies as a dismiss drag.\n * Returns \"drag\" if it's a valid dismiss gesture, \"none\" if it's off-axis\n * or moving in the wrong direction.\n */\nexport function classifyGesture(\n\tdx: number,\n\tdy: number,\n\taxis: DragAxis,\n\tsign: DragSign,\n): \"drag\" | \"none\" {\n\tconst absDx = Math.abs(dx);\n\tconst absDy = Math.abs(dy);\n\n\t// Compute angle between movement vector and dismiss axis\n\tlet angleDeg: number;\n\tif (axis === \"y\") {\n\t\tangleDeg = absDy === 0 ? 90 : (Math.atan(absDx / absDy) * 180) / Math.PI;\n\t} else {\n\t\tangleDeg = absDx === 0 ? 90 : (Math.atan(absDy / absDx) * 180) / Math.PI;\n\t}\n\n\tif (angleDeg > MAX_ANGLE_DEG) {\n\t\treturn \"none\";\n\t}\n\n\t// Must be moving in the dismiss direction\n\tconst moveInAxis = axis === \"x\" ? dx : dy;\n\tif (moveInAxis * sign < 0) {\n\t\treturn \"none\";\n\t}\n\n\treturn \"drag\";\n}\n\n/** Decide whether a pointer gesture commits as a drag or should be ignored. */\nexport function commitGesture(\n\tdx: number,\n\tdy: number,\n\taxis: DragAxis,\n\tsign: DragSign,\n\tscrollEl: Element | null,\n): \"drag\" | \"none\" {\n\tconst gesture = classifyGesture(dx, dy, axis, sign);\n\tif (gesture === \"none\") {\n\t\treturn \"none\";\n\t}\n\tif (scrollEl && !isAtScrollEdge(scrollEl, axis, sign)) {\n\t\treturn \"none\";\n\t}\n\treturn \"drag\";\n}\n\nexport function getPanelDimension(\n\tpanel: HTMLDivElement | null,\n\taxis: DragAxis,\n): number {\n\tif (!panel) {\n\t\treturn 300;\n\t}\n\treturn axis === \"x\" ? panel.offsetWidth : panel.offsetHeight;\n}\n","import { type RefObject, useCallback, useEffect, useRef } from \"react\";\nimport { findSnapTarget } from \"../snap-points\";\nimport { DEAD_ZONE, RUBBER_BAND_FACTOR } from \"./DragConstants\";\nimport {\n\tcommitGesture,\n\tfindScrollableAncestor,\n\tgetDismissAxis,\n\tgetPanelDimension,\n\tisInteractiveElement,\n} from \"./DragGeometry\";\nimport type { DragConfig, DragState } from \"./DragTypes\";\n\n/**\n * Hook that manages drag gestures that can dismiss a sheet panel.\n *\n * Gesture pipeline:\n * 1. Dead zone (10px) — ignores micro-movements\n * 2. Angle check (35°) — must be roughly aligned with dismiss axis\n * 3. Scroll conflict — yields to scrollable containers not at edge\n * 4. Commit — drag is active, applies offset via `onDragUpdate`\n * 5. Release — velocity + threshold determine close/snap/bounce-back\n *\n * Opposite-direction drag uses √(offset) damping for elastic\n * rubber-band resistance (same physics as iOS over-scroll).\n *\n * When `snapHeights` is provided, release targeting uses\n * `findSnapTarget()` instead of the simple threshold check.\n */\nexport function useDrag(\n\tpanelRef: RefObject<HTMLDivElement | null>,\n\tconfig: DragConfig,\n\tonDragUpdate: (state: DragState) => void,\n) {\n\tconst startRef = useRef<{ x: number; y: number; time: number } | null>(null);\n\tconst committedRef = useRef<\"drag\" | \"none\" | null>(null);\n\tconst offsetRef = useRef(0);\n\tconst scrollTargetRef = useRef<Element | null>(null);\n\n\tconst { axis, sign } = getDismissAxis(config.side);\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\tif (!config.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Only primary button\n\t\t\tif (e.button !== 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Check target element\n\t\t\tconst target = e.target as Element;\n\t\t\tif (!target) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Allow drag from handle elements always\n\t\t\tconst isHandle = !!target.closest(\"[data-stacksheet-handle]\");\n\n\t\t\t// For non-handle areas, check if the target is interactive\n\t\t\tif (!isHandle && isInteractiveElement(target)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Track nearest scrollable ancestor — checked at commit time\n\t\t\tscrollTargetRef.current = isHandle\n\t\t\t\t? null\n\t\t\t\t: findScrollableAncestor(target, axis);\n\n\t\t\tstartRef.current = { x: e.clientX, y: e.clientY, time: Date.now() };\n\t\t\tcommittedRef.current = null;\n\t\t\toffsetRef.current = 0;\n\n\t\t\t// Capture pointer for reliable move/up outside the element\n\t\t\t(e.currentTarget as HTMLElement)?.setPointerCapture?.(e.pointerId);\n\t\t},\n\t\t[config.enabled, axis],\n\t);\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\tif (!startRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst dx = e.clientX - startRef.current.x;\n\t\t\tconst dy = e.clientY - startRef.current.y;\n\t\t\tconst dist = Math.sqrt(dx * dx + dy * dy);\n\n\t\t\t// Still in dead zone — don't commit yet\n\t\t\tif (committedRef.current === null && dist < DEAD_ZONE) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Commit decision: check direction + scroll state\n\t\t\tif (committedRef.current === null) {\n\t\t\t\tcommittedRef.current = commitGesture(\n\t\t\t\t\tdx,\n\t\t\t\t\tdy,\n\t\t\t\t\taxis,\n\t\t\t\t\tsign,\n\t\t\t\t\tscrollTargetRef.current,\n\t\t\t\t);\n\t\t\t\tif (committedRef.current !== \"drag\") {\n\t\t\t\t\tstartRef.current = null;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (committedRef.current !== \"drag\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Calculate offset in dismiss direction\n\t\t\tconst rawOffset = axis === \"x\" ? dx : dy;\n\t\t\tconst directional = rawOffset * sign;\n\n\t\t\t// Dismiss direction: linear movement. Opposite direction: √ damping\n\t\t\t// for elastic rubber-band resistance (same math as iOS over-scroll).\n\t\t\tconst clampedOffset =\n\t\t\t\tdirectional >= 0\n\t\t\t\t\t? directional\n\t\t\t\t\t: -Math.sqrt(Math.abs(directional)) * RUBBER_BAND_FACTOR;\n\n\t\t\toffsetRef.current = clampedOffset;\n\t\t\tonDragUpdate({ offset: clampedOffset, isDragging: true });\n\n\t\t\t// Prevent text selection during active drag\n\t\t\te.preventDefault();\n\t\t},\n\t\t[axis, sign, onDragUpdate],\n\t);\n\n\tconst dismiss = useCallback(() => {\n\t\tif (config.isNested) {\n\t\t\tconfig.onPop();\n\t\t} else {\n\t\t\tconfig.onClose();\n\t\t}\n\t}, [config]);\n\n\tconst handlePointerUp = useCallback(\n\t\t(_e: PointerEvent) => {\n\t\t\tif (!startRef.current || committedRef.current !== \"drag\") {\n\t\t\t\tstartRef.current = null;\n\t\t\t\tcommittedRef.current = null;\n\t\t\t\tscrollTargetRef.current = null;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst offset = Math.max(0, offsetRef.current);\n\t\t\tconst elapsed = Date.now() - startRef.current.time;\n\t\t\tconst velocity = elapsed > 0 ? offset / elapsed : 0;\n\n\t\t\tstartRef.current = null;\n\t\t\tcommittedRef.current = null;\n\t\t\toffsetRef.current = 0;\n\t\t\tscrollTargetRef.current = null;\n\n\t\t\tconst panelSize = getPanelDimension(panelRef.current, axis);\n\n\t\t\t// Snap points mode\n\t\t\tif (config.snapHeights.length > 0) {\n\t\t\t\tconst targetIndex = findSnapTarget(\n\t\t\t\t\toffset,\n\t\t\t\t\tpanelSize,\n\t\t\t\t\tconfig.snapHeights,\n\t\t\t\t\tvelocity,\n\t\t\t\t\tconfig.activeSnapIndex,\n\t\t\t\t\tconfig.sequential,\n\t\t\t\t);\n\t\t\t\tif (targetIndex === -1) {\n\t\t\t\t\tdismiss();\n\t\t\t\t} else {\n\t\t\t\t\tconfig.onSnap(targetIndex);\n\t\t\t\t\tonDragUpdate({ offset: 0, isDragging: false });\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Standard mode: threshold-based close\n\t\t\tconst pastThreshold = offset / panelSize > config.closeThreshold;\n\t\t\tconst fastEnough = velocity > config.velocityThreshold;\n\t\t\tif (pastThreshold || fastEnough) {\n\t\t\t\tdismiss();\n\t\t\t} else {\n\t\t\t\tonDragUpdate({ offset: 0, isDragging: false });\n\t\t\t}\n\t\t},\n\t\t[panelRef, axis, config, onDragUpdate, dismiss],\n\t);\n\n\tconst handlePointerCancel = useCallback(() => {\n\t\tstartRef.current = null;\n\t\tcommittedRef.current = null;\n\t\toffsetRef.current = 0;\n\t\tscrollTargetRef.current = null;\n\t\tonDragUpdate({ offset: 0, isDragging: false });\n\t}, [onDragUpdate]);\n\n\t// Attach pointer events to the panel element\n\tuseEffect(() => {\n\t\tconst el = panelRef.current;\n\t\tif (!(el && config.enabled)) {\n\t\t\treturn;\n\t\t}\n\n\t\tel.addEventListener(\"pointerdown\", handlePointerDown);\n\t\tel.addEventListener(\"pointermove\", handlePointerMove);\n\t\tel.addEventListener(\"pointerup\", handlePointerUp);\n\t\tel.addEventListener(\"pointercancel\", handlePointerCancel);\n\n\t\treturn () => {\n\t\t\tel.removeEventListener(\"pointerdown\", handlePointerDown);\n\t\t\tel.removeEventListener(\"pointermove\", handlePointerMove);\n\t\t\tel.removeEventListener(\"pointerup\", handlePointerUp);\n\t\t\tel.removeEventListener(\"pointercancel\", handlePointerCancel);\n\t\t};\n\t}, [\n\t\tpanelRef,\n\t\tconfig.enabled,\n\t\thandlePointerDown,\n\t\thandlePointerMove,\n\t\thandlePointerUp,\n\t\thandlePointerCancel,\n\t]);\n}\n","import { createContext, useContext } from \"react\";\nimport type { Side } from \"./types\";\n\nexport interface SheetPanelContextValue {\n\t/** Pop the top sheet (go back one level) */\n\tback: () => void;\n\t/** Close the entire sheet stack */\n\tclose: () => void;\n\t/** Whether a Sheet.Description is mounted inside this panel */\n\thasDescription: boolean;\n\t/** Whether the stack has more than one sheet */\n\tisNested: boolean;\n\t/** Whether this is the top (active) sheet */\n\tisTop: boolean;\n\t/** Unique ID prefix for this panel (for aria-labelledby linking) */\n\tpanelId: string;\n\t/** Called by Sheet.Description on mount to register its presence */\n\tregisterDescription: () => () => void;\n\t/** Current resolved side (left/right/bottom) */\n\tside: Side;\n}\n\nexport const SheetPanelContext = createContext<SheetPanelContextValue | null>(\n\tnull,\n);\n\n/**\n * Access the current sheet panel's context.\n * Must be called inside a component rendered by the sheet stack.\n */\nexport function useSheetPanel(): SheetPanelContextValue {\n\tconst ctx = useContext(SheetPanelContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t\"Sheet.* components must be used inside a sheet panel. \" +\n\t\t\t\t\"They should be rendered by a component opened via actions.open(), push(), etc.\",\n\t\t);\n\t}\n\treturn ctx;\n}\n","import type { CSSProperties } from \"react\";\nimport type { ResolvedConfig, Side, StackingConfig } from \"./types\";\n\n// ── Depth transforms ────────────────────────────\n\nexport interface StackTransform {\n\tborderRadius: number;\n\toffset: number;\n\topacity: number;\n\tscale: number;\n}\n\n/**\n * Compute visual transforms for a panel at a given depth.\n * depth=0 is the top (foreground) panel.\n * Panels beyond renderThreshold are clamped to the edge position and faded out.\n */\nexport function getStackTransform(\n\tdepth: number,\n\tstacking: StackingConfig,\n): StackTransform {\n\tif (depth <= 0) {\n\t\treturn { scale: 1, offset: 0, opacity: 1, borderRadius: 0 };\n\t}\n\n\tconst beyondThreshold = depth >= stacking.renderThreshold;\n\t// Clamp visual depth so panels beyond threshold stay at the edge position\n\tconst visualDepth = beyondThreshold ? stacking.renderThreshold - 1 : depth;\n\n\treturn {\n\t\tscale: Math.max(0.5, 1 - visualDepth * stacking.scaleStep),\n\t\toffset: visualDepth * stacking.offsetStep,\n\t\topacity: beyondThreshold\n\t\t\t? 0\n\t\t\t: Math.max(0, 1 - visualDepth * stacking.opacityStep),\n\t\tborderRadius: stacking.radius,\n\t};\n}\n\n/**\n * Border radius values for the animate target.\n * Must be animated (not static CSS) so Motion applies scale correction\n * when panels are scaled. See: https://motion.dev/docs/react-layout-animations#scale-correction\n */\nexport function getAnimatedBorderRadius(\n\tside: Side,\n\tdepth: number,\n\tstacking: StackingConfig,\n): Record<string, number> {\n\tif (side === \"bottom\") {\n\t\tconst radius = depth > 0 ? stacking.radius : 16;\n\t\treturn {\n\t\t\tborderTopLeftRadius: radius,\n\t\t\tborderTopRightRadius: radius,\n\t\t\tborderBottomLeftRadius: 0,\n\t\t\tborderBottomRightRadius: 0,\n\t\t};\n\t}\n\n\t// Left/right panels: stacked panels get uniform radius, top panel gets none\n\tif (depth > 0) {\n\t\treturn { borderRadius: stacking.radius };\n\t}\n\treturn { borderRadius: 0 };\n}\n\n// ── Slide directions ────────────────────────────\n\nexport interface SlideValues {\n\tx?: string | number;\n\ty?: string | number;\n}\n\n/** Motion initial/exit values for sliding from the given side. */\nexport function getSlideFrom(side: Side): SlideValues {\n\tswitch (side) {\n\t\tcase \"right\":\n\t\t\treturn { x: \"100%\" };\n\t\tcase \"left\":\n\t\t\treturn { x: \"-100%\" };\n\t\tcase \"bottom\":\n\t\t\treturn { y: \"100%\" };\n\t\tdefault:\n\t\t\treturn { x: \"100%\" };\n\t}\n}\n\n/** Motion animate target — the resting position. */\nexport function getSlideTarget(): SlideValues {\n\treturn { x: 0, y: 0 };\n}\n\n/** Translate offset that pushes stacked panels away from the stack edge. */\nexport function getStackOffset(\n\tside: Side,\n\toffset: number,\n): { x?: number; y?: number } {\n\tif (offset === 0) {\n\t\treturn {};\n\t}\n\tswitch (side) {\n\t\tcase \"right\":\n\t\t\treturn { x: -offset };\n\t\tcase \"left\":\n\t\t\treturn { x: offset };\n\t\tcase \"bottom\":\n\t\t\treturn { y: -offset };\n\t\tdefault:\n\t\t\treturn {};\n\t}\n}\n\n// ── Transform origin ────────────────────────────\n\n/** Opposite-side origin so stacked panels recede away from the stack edge. */\nfunction getTransformOrigin(side: Side): string {\n\tif (side === \"right\") {\n\t\treturn \"left center\";\n\t}\n\tif (side === \"left\") {\n\t\treturn \"right center\";\n\t}\n\treturn \"center top\";\n}\n\n// ── Panel positioning ───────────────────────────\n\n/**\n * Fixed-position styles for a panel, accounting for side, width, and depth.\n */\nexport function getPanelStyles(\n\tside: Side,\n\tconfig: ResolvedConfig,\n\tindex: number,\n): CSSProperties {\n\tconst { width, maxWidth, zIndex } = config;\n\tconst base: CSSProperties = {\n\t\tposition: \"fixed\",\n\t\tzIndex: zIndex + 10 + index,\n\t\tdisplay: \"flex\",\n\t\tflexDirection: \"column\",\n\t\twillChange: \"transform\",\n\t\ttransformOrigin: getTransformOrigin(side),\n\t};\n\n\tif (side === \"bottom\") {\n\t\treturn {\n\t\t\t...base,\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\tbottom: 0,\n\t\t\t// dvh tracks the dynamic viewport on iOS Safari (accounts for browser chrome).\n\t\t\theight: \"85dvh\",\n\t\t\tmaxHeight: \"85dvh\",\n\t\t\t// borderRadius is animated via Motion's animate prop for scale correction\n\t\t};\n\t}\n\n\t// Left or right side panel\n\tconst sideStyles: CSSProperties =\n\t\tside === \"right\"\n\t\t\t? { top: 0, right: 0, bottom: 0 }\n\t\t\t: { top: 0, left: 0, bottom: 0 };\n\n\treturn {\n\t\t...base,\n\t\t...sideStyles,\n\t\twidth,\n\t\tmaxWidth,\n\t};\n}\n","/** Inline SVG icons — no external dependency */\n\nexport function ArrowLeftIcon() {\n\treturn (\n\t\t<svg\n\t\t\taria-hidden=\"true\"\n\t\t\tfill=\"none\"\n\t\t\theight={16}\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tstrokeWidth={2}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\twidth={16}\n\t\t>\n\t\t\t<path d=\"M19 12H5M12 19l-7-7 7-7\" />\n\t\t</svg>\n\t);\n}\n\nexport function XIcon() {\n\treturn (\n\t\t<svg\n\t\t\taria-hidden=\"true\"\n\t\t\tfill=\"none\"\n\t\t\theight={16}\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tstrokeWidth={2}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\twidth={16}\n\t\t>\n\t\t\t<path d=\"M18 6L6 18M6 6l12 12\" />\n\t\t</svg>\n\t);\n}\n","import { ArrowLeftIcon, XIcon } from \"../icons\";\nimport type { HeaderRenderProps } from \"../types\";\n\nexport function DefaultHeader({\n\tisNested,\n\tonBack,\n\tonClose,\n\tclassName,\n}: HeaderRenderProps & { className?: string }) {\n\treturn (\n\t\t<div\n\t\t\tclassName={`flex shrink-0 items-center justify-between px-4 pt-4 pb-2 ${className ?? \"\"}`}\n\t\t>\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t{isNested && (\n\t\t\t\t\t<button\n\t\t\t\t\t\taria-label=\"Back\"\n\t\t\t\t\t\tclassName=\"flex min-h-11 min-w-11 shrink-0 cursor-pointer items-center justify-center rounded-full border-none bg-black/5 p-0 text-inherit opacity-70 transition-opacity duration-150 hover:opacity-100\"\n\t\t\t\t\t\tonClick={onBack}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<ArrowLeftIcon />\n\t\t\t\t\t</button>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<button\n\t\t\t\taria-label=\"Close\"\n\t\t\t\tclassName=\"flex min-h-11 min-w-11 shrink-0 cursor-pointer items-center justify-center rounded-full border-none bg-black/5 p-0 text-inherit opacity-70 transition-opacity duration-150 hover:opacity-100\"\n\t\t\t\tonClick={onClose}\n\t\t\t\ttype=\"button\"\n\t\t\t>\n\t\t\t\t<XIcon />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","import { type ComponentType, memo, type ReactNode } from \"react\";\n\nimport type { HeaderRenderProps, StacksheetLayout } from \"../types\";\nimport { DefaultHeader } from \"./DefaultHeader\";\n\nexport const PanelInnerContent = memo(function PanelInnerContent({\n\tisComposable,\n\tshouldRender,\n\tContent,\n\tdata,\n\trenderHeader,\n\theaderProps,\n\theaderClassName,\n}: {\n\tisComposable: boolean;\n\tshouldRender: boolean;\n\t// biome-ignore lint/suspicious/noExplicitAny: heterogeneous content component\n\tContent: ComponentType<any> | undefined;\n\tdata: Record<string, unknown>;\n\trenderHeader?: false | ((props: HeaderRenderProps) => ReactNode);\n\theaderProps: HeaderRenderProps;\n\theaderClassName: string | undefined;\n}) {\n\tif (isComposable) {\n\t\treturn shouldRender && Content ? <Content {...data} /> : null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{renderHeader ? (\n\t\t\t\trenderHeader(headerProps)\n\t\t\t) : (\n\t\t\t\t<DefaultHeader {...headerProps} className={headerClassName} />\n\t\t\t)}\n\t\t\t{shouldRender && Content && (\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\"\n\t\t\t\t\tdata-stacksheet-no-drag=\"\"\n\t\t\t\t>\n\t\t\t\t\t<Content {...data} />\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</>\n\t);\n});\n\nPanelInnerContent.displayName = \"PanelInnerContent\";\n\nexport function resolvePanelLayout(\n\tlayout: StacksheetLayout | undefined,\n\trenderHeader?: false | ((props: HeaderRenderProps) => ReactNode),\n): StacksheetLayout {\n\tif (layout) {\n\t\treturn layout;\n\t}\n\treturn renderHeader === false ? \"composable\" : \"classic\";\n}\n","import { FocusTrap } from \"focus-trap-react\";\nimport type { ReactNode, RefObject } from \"react\";\nimport { useEffect, useState } from \"react\";\n\nconst LAYERED_MODAL_SELECTORS = [\n\t'[role=\"dialog\"][data-state=\"open\"]',\n\t'[role=\"alertdialog\"][data-state=\"open\"]',\n\t\"[data-radix-popper-content-wrapper]\",\n\t\"[data-radix-focus-guard]\",\n].join(\", \");\n\nexport function ModalFocusTrap({\n\tenabled,\n\tactive,\n\tfallbackRef,\n\tchildren,\n}: {\n\tenabled: boolean;\n\tactive: boolean;\n\tfallbackRef: RefObject<HTMLElement | null>;\n\tchildren: ReactNode;\n}) {\n\tconst paused = useLayeredModalFocused(enabled && active);\n\n\tif (!enabled) {\n\t\treturn children;\n\t}\n\treturn (\n\t\t<FocusTrap\n\t\t\tactive={active}\n\t\t\tfocusTrapOptions={{\n\t\t\t\tinitialFocus: false,\n\t\t\t\treturnFocusOnDeactivate: true,\n\t\t\t\tescapeDeactivates: false,\n\t\t\t\tallowOutsideClick: true,\n\t\t\t\tcheckCanFocusTrap: () =>\n\t\t\t\t\tnew Promise<void>((resolve) =>\n\t\t\t\t\t\trequestAnimationFrame(() => resolve()),\n\t\t\t\t\t),\n\t\t\t\tfallbackFocus: () => {\n\t\t\t\t\tif (fallbackRef.current) {\n\t\t\t\t\t\treturn fallbackRef.current;\n\t\t\t\t\t}\n\t\t\t\t\treturn document.body;\n\t\t\t\t},\n\t\t\t}}\n\t\t\tpaused={paused}\n\t\t>\n\t\t\t{children}\n\t\t</FocusTrap>\n\t);\n}\n\nfunction useLayeredModalFocused(active: boolean): boolean {\n\tconst [layered, setLayered] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (!active) {\n\t\t\tsetLayered(false);\n\t\t\treturn;\n\t\t}\n\t\tconst evaluate = () => {\n\t\t\tconst target = document.activeElement;\n\t\t\tif (!target || target === document.body) {\n\t\t\t\tsetLayered(false);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst inLayer =\n\t\t\t\ttarget instanceof Element &&\n\t\t\t\ttarget.closest(LAYERED_MODAL_SELECTORS) !== null;\n\t\t\tsetLayered(inLayer);\n\t\t};\n\t\tevaluate();\n\t\tconst handler = () => evaluate();\n\t\tdocument.addEventListener(\"focusin\", handler, true);\n\t\treturn () => document.removeEventListener(\"focusin\", handler, true);\n\t}, [active]);\n\n\treturn layered;\n}\n","import { motion as m } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\n\nimport type { Side } from \"../types\";\n\nexport function BottomHandle({ onDismiss }: { onDismiss?: () => void }) {\n\treturn (\n\t\t<button\n\t\t\taria-label=\"Dismiss\"\n\t\t\tclassName=\"absolute inset-x-0 top-0 z-10 flex w-full cursor-grab touch-none items-center justify-center border-none bg-transparent pt-2.5 pb-2\"\n\t\t\tdata-stacksheet-handle=\"\"\n\t\t\tonClick={onDismiss}\n\t\t\ttype=\"button\"\n\t\t>\n\t\t\t<div\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tclassName=\"h-[5px] w-9 rounded-full bg-current/15\"\n\t\t\t/>\n\t\t</button>\n\t);\n}\n\nexport function SideHandle({\n\tside,\n\tisHovered,\n\tonDismiss,\n}: {\n\tside: Side;\n\tisHovered: boolean;\n\tonDismiss?: () => void;\n}) {\n\tconst position: CSSProperties =\n\t\tside === \"right\" ? { right: \"100%\" } : { left: \"100%\" };\n\n\treturn (\n\t\t<m.div\n\t\t\tanimate={{ opacity: isHovered ? 1 : 0 }}\n\t\t\taria-label=\"Dismiss\"\n\t\t\tclassName=\"absolute top-0 bottom-0 flex w-6 cursor-grab touch-none items-center justify-center\"\n\t\t\tdata-stacksheet-handle=\"\"\n\t\t\tonClick={onDismiss}\n\t\t\tonKeyDown={(e) => {\n\t\t\t\tif (e.key === \"Enter\" || e.key === \" \") {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tonDismiss?.();\n\t\t\t\t}\n\t\t\t}}\n\t\t\trole=\"button\"\n\t\t\tstyle={position}\n\t\t\ttabIndex={0}\n\t\t\ttransition={{ duration: isHovered ? 0.15 : 0.4, ease: \"easeOut\" }}\n\t\t>\n\t\t\t<div aria-hidden=\"true\" className=\"h-8 w-1 rounded-full bg-current/20\" />\n\t\t</m.div>\n\t);\n}\n","import { motion as m } from \"motion/react\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type { DragState } from \"../Drag/DragTypes\";\nimport { useDrag } from \"../Drag/useDrag\";\nimport { SheetPanelContext } from \"../panel-context\";\nimport { usePanelHeight } from \"../renderer-effects\";\nimport {\n\tbuildAnimateTarget,\n\tbuildAriaProps,\n\tbuildPanelStyle,\n\tbuildPanelTransition,\n\tcomputeSnapYOffset,\n\tgetDragTransform,\n\tgetInitialRadius,\n\tgetShadow,\n\tresolveSlideFrom,\n\tVISUAL_TWEEN,\n} from \"../renderer-helpers\";\nimport {\n\tgetAnimatedBorderRadius,\n\tgetPanelStyles,\n\tgetStackOffset,\n\tgetStackTransform,\n} from \"../stacking\";\nimport type { HeaderRenderProps } from \"../types\";\nimport { PanelInnerContent, resolvePanelLayout } from \"./SheetPanelContent\";\nimport { ModalFocusTrap } from \"./SheetPanelFocus\";\nimport { BottomHandle, SideHandle } from \"./SheetPanelHandles\";\nimport type { SheetPanelProps } from \"./SheetPanelTypes\";\n\nexport const SheetPanel = memo(function SheetPanel({\n\titem,\n\tindex,\n\tdepth,\n\tisTop,\n\tisNested,\n\tside,\n\tconfig,\n\tclassNames,\n\tContent,\n\tshouldRender,\n\tpop,\n\tclose,\n\tswipeClose,\n\tswipePop,\n\tsnapHeights,\n\tactiveSnapIndex,\n\tonSnap,\n\tlayout,\n\trenderHeader,\n\tslideFrom,\n\tslideTarget,\n\tspring,\n\tstackSpring,\n\tprefersReducedMotion,\n}: SheetPanelProps) {\n\tconst panelRef = useRef<HTMLDivElement>(null);\n\tconst hasEnteredRef = useRef(false);\n\tconst [dragState, setDragState] = useState<DragState>({\n\t\toffset: 0,\n\t\tisDragging: false,\n\t});\n\tconst [isHovered, setIsHovered] = useState(false);\n\n\tconst measuredHeight = usePanelHeight(panelRef, snapHeights.length > 0);\n\n\tconst transform = getStackTransform(depth, config.stacking);\n\tconst panelStyles = getPanelStyles(side, config, index);\n\n\tuseEffect(() => {\n\t\tif (!isTop) {\n\t\t\thasEnteredRef.current = false;\n\t\t}\n\t}, [isTop]);\n\n\tconst handleAnimationComplete = useCallback(() => {\n\t\tif (isTop && !hasEnteredRef.current) {\n\t\t\thasEnteredRef.current = true;\n\t\t\tconfig.onOpenComplete?.();\n\t\t}\n\t}, [isTop, config]);\n\n\tuseDrag(\n\t\tpanelRef,\n\t\t{\n\t\t\tenabled:\n\t\t\t\tisTop && config.drag && config.dismissible && !prefersReducedMotion,\n\t\t\tcloseThreshold: config.closeThreshold,\n\t\t\tvelocityThreshold: config.velocityThreshold,\n\t\t\tside,\n\t\t\tonClose: swipeClose,\n\t\t\tonPop: swipePop,\n\t\t\tisNested,\n\t\t\tsnapHeights,\n\t\t\tactiveSnapIndex,\n\t\t\tonSnap,\n\t\t\tsequential: config.snapToSequentialPoints,\n\t\t},\n\t\tsetDragState,\n\t);\n\n\tconst ariaLabel =\n\t\titem.ariaLabel ??\n\t\t(typeof item.data?.__ariaLabel === \"string\"\n\t\t\t? item.data.__ariaLabel\n\t\t\t: undefined) ??\n\t\tconfig.ariaLabel;\n\n\tconst panelId = `stacksheet-${item.id}`;\n\tconst [hasDescription, setHasDescription] = useState(false);\n\tconst registerDescription = useCallback(() => {\n\t\tsetHasDescription(true);\n\t\treturn () => setHasDescription(false);\n\t}, []);\n\tconst panelContext = useMemo(\n\t\t() => ({\n\t\t\tclose,\n\t\t\tback: pop,\n\t\t\tisNested,\n\t\t\tisTop,\n\t\t\tpanelId,\n\t\t\tside,\n\t\t\thasDescription,\n\t\t\tregisterDescription,\n\t\t}),\n\t\t[\n\t\t\tclose,\n\t\t\tpop,\n\t\t\tisNested,\n\t\t\tisTop,\n\t\t\tpanelId,\n\t\t\tside,\n\t\t\thasDescription,\n\t\t\tregisterDescription,\n\t\t],\n\t);\n\n\tconst panelLayout = resolvePanelLayout(layout, renderHeader);\n\tconst isComposable = panelLayout === \"composable\";\n\tconst hasPanelClass = classNames.panel !== \"\";\n\tconst dragOffset = getDragTransform(side, dragState.offset);\n\tconst panelStyle = buildPanelStyle(\n\t\tpanelStyles,\n\t\tisTop,\n\t\thasPanelClass,\n\t\tdragState.isDragging,\n\t);\n\n\tconst headerProps = useMemo<HeaderRenderProps>(\n\t\t() => ({\n\t\t\tisNested,\n\t\t\tonBack: pop,\n\t\t\tonClose: close,\n\t\t\tside,\n\t\t}),\n\t\t[close, isNested, pop, side],\n\t);\n\n\tconst ariaProps = buildAriaProps(\n\t\tisTop,\n\t\tconfig.modal,\n\t\tisComposable,\n\t\tariaLabel,\n\t\tpanelId,\n\t\thasDescription,\n\t);\n\n\tconst transition = buildPanelTransition(\n\t\tdragState.isDragging,\n\t\tisTop,\n\t\tspring,\n\t\tstackSpring,\n\t);\n\n\tconst animatedRadius = getAnimatedBorderRadius(side, depth, config.stacking);\n\tconst snapYOffset = computeSnapYOffset(\n\t\tside,\n\t\tsnapHeights,\n\t\tactiveSnapIndex,\n\t\tmeasuredHeight,\n\t);\n\tconst resolvedSlideFrom = resolveSlideFrom(side, slideFrom, measuredHeight);\n\n\tconst stackOffset = getStackOffset(side, transform.offset);\n\tconst animateTarget = buildAnimateTarget(\n\t\tslideTarget,\n\t\tstackOffset,\n\t\tdragOffset,\n\t\ttransform,\n\t\tanimatedRadius,\n\t\ttransition,\n\t\tsnapYOffset,\n\t\tisTop,\n\t);\n\n\tconst initialRadius = getInitialRadius(side);\n\tconst showSideHandle = isTop && side !== \"bottom\";\n\tconst showBottomHandle = isTop && side === \"bottom\";\n\n\tconst panelContent = (\n\t\t<m.div\n\t\t\tanimate={animateTarget}\n\t\t\tclassName={classNames.panel || undefined}\n\t\t\texit={{\n\t\t\t\t...resolvedSlideFrom,\n\t\t\t\topacity: 0.6,\n\t\t\t\tboxShadow: getShadow(false),\n\t\t\t\ttransition: {\n\t\t\t\t\ttype: \"tween\",\n\t\t\t\t\tduration: prefersReducedMotion ? 0 : 0.24,\n\t\t\t\t\tease: \"easeOut\",\n\t\t\t\t\tboxShadow: VISUAL_TWEEN,\n\t\t\t\t},\n\t\t\t}}\n\t\t\tinitial={{\n\t\t\t\t...resolvedSlideFrom,\n\t\t\t\topacity: 0.8,\n\t\t\t\t...initialRadius,\n\t\t\t\tboxShadow: getShadow(false),\n\t\t\t}}\n\t\t\tkey={item.id}\n\t\t\tonAnimationComplete={handleAnimationComplete}\n\t\t\tonBlur={showSideHandle ? () => setIsHovered(false) : undefined}\n\t\t\tonFocus={showSideHandle ? () => setIsHovered(true) : undefined}\n\t\t\tonMouseEnter={showSideHandle ? () => setIsHovered(true) : undefined}\n\t\t\tonMouseLeave={showSideHandle ? () => setIsHovered(false) : undefined}\n\t\t\tref={panelRef}\n\t\t\tstyle={panelStyle}\n\t\t\ttabIndex={isTop ? -1 : undefined}\n\t\t\t{...(isTop ? {} : { \"aria-hidden\": \"true\" as const, inert: true })}\n\t\t\t{...ariaProps}\n\t\t>\n\t\t\t{showSideHandle && (\n\t\t\t\t<SideHandle\n\t\t\t\t\tisHovered={isHovered}\n\t\t\t\t\tonDismiss={isNested ? pop : close}\n\t\t\t\t\tside={side}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<div className=\"relative flex min-h-0 flex-1 flex-col overflow-hidden rounded-[inherit]\">\n\t\t\t\t{showBottomHandle && (\n\t\t\t\t\t<BottomHandle onDismiss={isNested ? pop : close} />\n\t\t\t\t)}\n\t\t\t\t<PanelInnerContent\n\t\t\t\t\tContent={Content}\n\t\t\t\t\tdata={item.data as Record<string, unknown>}\n\t\t\t\t\theaderClassName={classNames.header || undefined}\n\t\t\t\t\theaderProps={headerProps}\n\t\t\t\t\tisComposable={isComposable}\n\t\t\t\t\trenderHeader={renderHeader}\n\t\t\t\t\tshouldRender={shouldRender}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</m.div>\n\t);\n\n\treturn (\n\t\t<SheetPanelContext.Provider value={panelContext}>\n\t\t\t<ModalFocusTrap\n\t\t\t\tactive={isTop}\n\t\t\t\tenabled={config.modal}\n\t\t\t\tfallbackRef={panelRef}\n\t\t\t>\n\t\t\t\t{panelContent}\n\t\t\t</ModalFocusTrap>\n\t\t</SheetPanelContext.Provider>\n\t);\n});\n","// CloseWatcher — ambient type for browsers that support it (Chromium 120+)\ndeclare global {\n\tvar CloseWatcher:\n\t\t| (new () => { onclose: (() => void) | null; destroy: () => void })\n\t\t| undefined;\n}\n\nimport { AnimatePresence, motion as m, useReducedMotion } from \"motion/react\";\nimport {\n\ttype ComponentType,\n\ttype CSSProperties,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport type { StoreApi } from \"zustand\";\nimport { useStore } from \"zustand\";\nimport { useResolvedSide } from \"./media\";\nimport { useBodyScale, useViewportHeight } from \"./renderer-effects\";\nimport { resolveClassNames } from \"./renderer-helpers\";\nimport { SheetPanel } from \"./sheet-panel\";\nimport { resolveSnapPoints } from \"./snap-points\";\nimport { getSlideFrom, getSlideTarget } from \"./stacking\";\nimport type {\n\tCloseReason,\n\tContentMap,\n\tHeaderRenderProps,\n\tResolvedConfig,\n\tSheetActions,\n\tStacksheetClassNames,\n\tStacksheetLayout,\n\tStacksheetSnapshot,\n} from \"./types\";\n\ninterface SheetRendererProps<TMap extends object> {\n\tclassNames?: StacksheetClassNames;\n\t/** Ad-hoc component map (type key → component) */\n\t// biome-ignore lint/suspicious/noExplicitAny: heterogeneous component storage\n\tcomponentMap: Map<string, ComponentType<any>>;\n\tconfig: ResolvedConfig;\n\tlayout?: StacksheetLayout;\n\trenderHeader?: false | ((props: HeaderRenderProps) => ReactNode);\n\tsheets: ContentMap<TMap>;\n\tstore: StoreApi<StacksheetSnapshot<TMap> & SheetActions<TMap>>;\n}\n\n/**\n * Root renderer component — manages the backdrop, scroll lock, snap points,\n * close reasons, focus restoration, keyboard/CloseWatcher dismissal, and\n * delegates per-panel rendering to `SheetPanel`.\n *\n * Mounted inside a Portal by `StacksheetProvider`.\n */\nexport function SheetRenderer<TMap extends object>({\n\tstore,\n\tconfig,\n\tsheets,\n\tcomponentMap,\n\tclassNames: classNamesProp,\n\tlayout,\n\trenderHeader,\n}: SheetRendererProps<TMap>) {\n\tconst isOpen = useStore(store, (s) => s.isOpen);\n\tconst stack = useStore(store, (s) => s.stack);\n\tconst rawClose = useStore(store, (s) => s.close);\n\tconst rawPop = useStore(store, (s) => s.pop);\n\n\tconst side = useResolvedSide(config);\n\tconst prefersReducedMotion = useReducedMotion() ?? false;\n\tconst classNames = useMemo(\n\t\t() => resolveClassNames(classNamesProp),\n\t\t[classNamesProp],\n\t);\n\tconst viewportHeight = useViewportHeight(\n\t\tisOpen && side === \"bottom\" && config.snapPoints.length > 0,\n\t);\n\n\tconst snapHeights = useMemo(\n\t\t() =>\n\t\t\tside === \"bottom\" && config.snapPoints.length > 0\n\t\t\t\t? resolveSnapPoints(config.snapPoints, viewportHeight)\n\t\t\t\t: [],\n\t\t[side, config.snapPoints, viewportHeight],\n\t);\n\n\tconst [internalSnapIndex, setInternalSnapIndex] = useState(\n\t\tsnapHeights.length > 0 ? snapHeights.length - 1 : 0,\n\t);\n\tconst activeSnapIndex = config.snapPointIndex ?? internalSnapIndex;\n\n\tconst handleSnap = useCallback(\n\t\t(index: number) => {\n\t\t\tsetInternalSnapIndex(index);\n\t\t\tconfig.onSnapPointChange?.(index);\n\t\t},\n\t\t[config.onSnapPointChange, config],\n\t);\n\n\tuseEffect(() => {\n\t\tif (isOpen && snapHeights.length > 0) {\n\t\t\tconst initial = config.snapPointIndex ?? snapHeights.length - 1;\n\t\t\tsetInternalSnapIndex(initial);\n\t\t}\n\t}, [isOpen, snapHeights.length, config.snapPointIndex]);\n\n\tconst closeReasonRef = useRef<CloseReason>(\"programmatic\");\n\n\tconst closeWith = useCallback(\n\t\t(reason: CloseReason) => {\n\t\t\tcloseReasonRef.current = reason;\n\t\t\trawClose();\n\t\t},\n\t\t[rawClose],\n\t);\n\n\tconst popWith = useCallback(\n\t\t(reason: CloseReason) => {\n\t\t\tcloseReasonRef.current = reason;\n\t\t\trawPop();\n\t\t},\n\t\t[rawPop],\n\t);\n\n\tconst close = useCallback(() => closeWith(\"programmatic\"), [closeWith]);\n\tconst pop = useCallback(() => popWith(\"programmatic\"), [popWith]);\n\n\tuseBodyScale(config, isOpen, prefersReducedMotion);\n\n\tconst triggerRef = useRef<Element | null>(null);\n\tconst wasOpenRef = useRef(false);\n\n\tuseEffect(() => {\n\t\tif (isOpen && !wasOpenRef.current) {\n\t\t\ttriggerRef.current = document.activeElement;\n\t\t} else if (!isOpen && wasOpenRef.current) {\n\t\t\tconst el = triggerRef.current;\n\t\t\tif (\n\t\t\t\tel &&\n\t\t\t\tel instanceof HTMLElement &&\n\t\t\t\tel !== document.body &&\n\t\t\t\tel.tagName !== \"BODY\"\n\t\t\t) {\n\t\t\t\tel.focus();\n\t\t\t}\n\t\t\ttriggerRef.current = null;\n\t\t}\n\t\twasOpenRef.current = isOpen;\n\t}, [isOpen]);\n\n\tconst stackLengthRef = useRef(stack.length);\n\tuseEffect(() => {\n\t\tstackLengthRef.current = stack.length;\n\t}, [stack.length]);\n\n\tuseEffect(() => {\n\t\tif (!(isOpen && config.closeOnEscape && config.dismissible)) {\n\t\t\treturn;\n\t\t}\n\n\t\tfunction handleKeyDown(e: KeyboardEvent) {\n\t\t\tif (e.key === \"Escape\") {\n\t\t\t\te.preventDefault();\n\t\t\t\tif (stackLengthRef.current > 1) {\n\t\t\t\t\tpopWith(\"escape\");\n\t\t\t\t} else {\n\t\t\t\t\tcloseWith(\"escape\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener(\"keydown\", handleKeyDown);\n\t\treturn () => document.removeEventListener(\"keydown\", handleKeyDown);\n\t}, [isOpen, config.closeOnEscape, config.dismissible, popWith, closeWith]);\n\n\tuseEffect(() => {\n\t\tif (\n\t\t\t!(isOpen && config.dismissible) ||\n\t\t\ttypeof globalThis.CloseWatcher === \"undefined\"\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst watcher = new globalThis.CloseWatcher();\n\t\twatcher.onclose = () => {\n\t\t\tif (stackLengthRef.current > 1) {\n\t\t\t\tpopWith(\"escape\");\n\t\t\t} else {\n\t\t\t\tcloseWith(\"escape\");\n\t\t\t}\n\t\t};\n\n\t\treturn () => watcher.destroy();\n\t}, [isOpen, config.dismissible, popWith, closeWith]);\n\n\tconst slideFrom = useMemo(() => getSlideFrom(side), [side]);\n\tconst slideTarget = useMemo(() => getSlideTarget(), []);\n\n\tconst spring = useMemo(\n\t\t() =>\n\t\t\tprefersReducedMotion\n\t\t\t\t? ({ type: \"tween\" as const, duration: 0 } as const)\n\t\t\t\t: ({\n\t\t\t\t\t\ttype: \"spring\" as const,\n\t\t\t\t\t\tdamping: config.spring.damping,\n\t\t\t\t\t\tstiffness: config.spring.stiffness,\n\t\t\t\t\t\tmass: config.spring.mass,\n\t\t\t\t\t} as const),\n\t\t[\n\t\t\tprefersReducedMotion,\n\t\t\tconfig.spring.damping,\n\t\t\tconfig.spring.stiffness,\n\t\t\tconfig.spring.mass,\n\t\t],\n\t);\n\tconst stackSpring = spring;\n\n\tconst isModal = config.modal;\n\tconst showOverlay = isModal && config.showOverlay;\n\tconst hasBackdropClass = classNames.backdrop !== \"\";\n\tconst backdropStyle: CSSProperties = {\n\t\tzIndex: config.zIndex,\n\t\twillChange: \"opacity\",\n\t\tcursor:\n\t\t\tconfig.closeOnBackdrop && config.dismissible ? \"pointer\" : undefined,\n\t\t...(hasBackdropClass\n\t\t\t? {}\n\t\t\t: { background: \"var(--overlay, rgba(0, 0, 0, 0.15))\" }),\n\t};\n\n\tconst handleExitComplete = useCallback(() => {\n\t\tif (stack.length === 0) {\n\t\t\tconfig.onCloseComplete?.(closeReasonRef.current);\n\t\t}\n\t}, [stack.length, config]);\n\n\tconst handleBackdropExitComplete = useCallback(() => {\n\t\trequestAnimationFrame(() => {\n\t\t\tvoid document.body.offsetHeight;\n\t\t});\n\t}, []);\n\n\tconst swipeClose = useCallback(() => closeWith(\"swipe\"), [closeWith]);\n\tconst swipePop = useCallback(() => popWith(\"swipe\"), [popWith]);\n\n\tconst shouldLockScroll = isOpen && isModal && config.lockScroll;\n\n\treturn (\n\t\t<>\n\t\t\t{showOverlay && (\n\t\t\t\t<AnimatePresence onExitComplete={handleBackdropExitComplete}>\n\t\t\t\t\t{isOpen && (\n\t\t\t\t\t\t<m.div\n\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\tclassName={`fixed inset-0 ${classNames.backdrop || \"\"}`}\n\t\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\tkey=\"stacksheet-backdrop\"\n\t\t\t\t\t\t\tonClick={\n\t\t\t\t\t\t\t\tconfig.closeOnBackdrop && config.dismissible\n\t\t\t\t\t\t\t\t\t? () => closeWith(\"backdrop\")\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tstyle={backdropStyle}\n\t\t\t\t\t\t\ttransition={spring}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</AnimatePresence>\n\t\t\t)}\n\n\t\t\t<RemoveScroll enabled={shouldLockScroll} forwardProps>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"pointer-events-none fixed inset-0 overflow-hidden\"\n\t\t\t\t\tstyle={{ zIndex: config.zIndex + 1 }}\n\t\t\t\t>\n\t\t\t\t\t<AnimatePresence onExitComplete={handleExitComplete}>\n\t\t\t\t\t\t{stack.map((item, index) => {\n\t\t\t\t\t\t\tconst depth = stack.length - 1 - index;\n\t\t\t\t\t\t\tconst isTop = depth === 0;\n\t\t\t\t\t\t\tconst isNested = index > 0;\n\t\t\t\t\t\t\tconst shouldRender = depth <= config.stacking.renderThreshold;\n\t\t\t\t\t\t\tconst Content = (componentMap.get(item.type) ??\n\t\t\t\t\t\t\t\tsheets[item.type as keyof TMap]) as\n\t\t\t\t\t\t\t\t| ComponentType<Record<string, unknown>>\n\t\t\t\t\t\t\t\t| undefined;\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<SheetPanel\n\t\t\t\t\t\t\t\t\tactiveSnapIndex={activeSnapIndex}\n\t\t\t\t\t\t\t\t\tContent={Content}\n\t\t\t\t\t\t\t\t\tclassNames={classNames}\n\t\t\t\t\t\t\t\t\tclose={close}\n\t\t\t\t\t\t\t\t\tconfig={config}\n\t\t\t\t\t\t\t\t\tdepth={depth}\n\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\tisNested={isNested}\n\t\t\t\t\t\t\t\t\tisTop={isTop}\n\t\t\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t\t\t\tlayout={layout}\n\t\t\t\t\t\t\t\t\tonSnap={handleSnap}\n\t\t\t\t\t\t\t\t\tpop={pop}\n\t\t\t\t\t\t\t\t\tprefersReducedMotion={prefersReducedMotion}\n\t\t\t\t\t\t\t\t\trenderHeader={renderHeader}\n\t\t\t\t\t\t\t\t\tshouldRender={shouldRender}\n\t\t\t\t\t\t\t\t\tside={side}\n\t\t\t\t\t\t\t\t\tslideFrom={slideFrom}\n\t\t\t\t\t\t\t\t\tslideTarget={slideTarget}\n\t\t\t\t\t\t\t\t\tsnapHeights={snapHeights}\n\t\t\t\t\t\t\t\t\tspring={spring}\n\t\t\t\t\t\t\t\t\tstackSpring={stackSpring}\n\t\t\t\t\t\t\t\t\tswipeClose={swipeClose}\n\t\t\t\t\t\t\t\t\tswipePop={swipePop}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</AnimatePresence>\n\t\t\t\t</div>\n\t\t\t</RemoveScroll>\n\t\t</>\n\t);\n}\n","declare const process: undefined | { env?: { NODE_ENV?: string } };\n\nimport type { SheetPresentationOptions } from \"../types\";\nimport type { AnyComponent, ResolvedItem } from \"./StoreTypes\";\n\nexport function resolvePresentationOptions(\n\tvalue: unknown,\n): SheetPresentationOptions | undefined {\n\tif (!(value && typeof value === \"object\")) {\n\t\treturn undefined;\n\t}\n\tconst candidate = value as SheetPresentationOptions;\n\tif (\n\t\tcandidate.ariaLabel !== undefined &&\n\t\ttypeof candidate.ariaLabel !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\treturn candidate;\n}\n\n/**\n * Dev-mode warning: detect likely inline arrow functions passed as ad-hoc components.\n * When a new component reference has the same displayName/name as an existing one,\n * it's almost always an inline arrow being re-created every render.\n */\nexport function warnInlineComponent(\n\tcomponent: AnyComponent,\n\tcomponentRegistry: Map<AnyComponent, string>,\n\twarnedNames: Set<string>,\n): void {\n\tif (\n\t\ttypeof process === \"undefined\" ||\n\t\tprocess?.env?.NODE_ENV === \"production\"\n\t) {\n\t\treturn;\n\t}\n\n\tconst name = component.displayName || component.name;\n\tif (!name) {\n\t\treturn;\n\t}\n\tif (warnedNames.has(name)) {\n\t\treturn;\n\t}\n\n\tfor (const [existing, key] of componentRegistry) {\n\t\tconst existingName = existing.displayName || existing.name;\n\t\tif (existingName === name) {\n\t\t\twarnedNames.add(name);\n\t\t\tconsole.warn(\n\t\t\t\t`[stacksheet] A new component reference with name \"${name}\" was registered ` +\n\t\t\t\t\t`(key: ${key}), but a different reference with the same name already exists. ` +\n\t\t\t\t\t`This usually means you're passing an inline arrow function (e.g. ` +\n\t\t\t\t\t\"open(() => <MySheet />)). Define the component outside of render to avoid \" +\n\t\t\t\t\t\"memory leaks and broken navigate() same-type detection.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/**\n * If `first` is a function (component), register it and return { type, id, data }.\n * Otherwise, pass through the string-based (type, id, data) args unchanged.\n */\nexport function resolveArgs(\n\tcomponentRegistry: Map<AnyComponent, string>,\n\tcomponentMap: Map<string, AnyComponent>,\n\tgetNextKey: () => string,\n\twarnedNames: Set<string>,\n\tfirst: unknown,\n\tsecond: unknown,\n\tthird: unknown,\n\tfourth?: unknown,\n): ResolvedItem {\n\tif (typeof first === \"function\") {\n\t\tconst component = first as AnyComponent;\n\n\t\tlet typeKey = componentRegistry.get(component);\n\t\tif (!typeKey) {\n\t\t\twarnInlineComponent(component, componentRegistry, warnedNames);\n\t\t\ttypeKey = getNextKey();\n\t\t\tcomponentRegistry.set(component, typeKey);\n\t\t\tcomponentMap.set(typeKey, component);\n\t\t}\n\n\t\tif (typeof second === \"string\") {\n\t\t\treturn {\n\t\t\t\tariaLabel: resolvePresentationOptions(fourth)?.ariaLabel,\n\t\t\t\ttype: typeKey,\n\t\t\t\tid: second,\n\t\t\t\tdata: (third ?? {}) as Record<string, unknown>,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tariaLabel: resolvePresentationOptions(third)?.ariaLabel,\n\t\t\ttype: typeKey,\n\t\t\tid: crypto.randomUUID(),\n\t\t\tdata: (second ?? {}) as Record<string, unknown>,\n\t\t};\n\t}\n\n\treturn {\n\t\tariaLabel: resolvePresentationOptions(fourth)?.ariaLabel,\n\t\ttype: first as string,\n\t\tid: second as string,\n\t\tdata: (third ?? {}) as Record<string, unknown>,\n\t};\n}\n","import { createStore } from \"zustand\";\nimport type { ResolvedConfig, SheetItem } from \"../types\";\nimport {\n\tresolveArgs,\n\tresolvePresentationOptions,\n\twarnInlineComponent,\n} from \"./StoreArgs\";\nimport type {\n\tAnyComponent,\n\tResolvedItem,\n\tSheetStoreBundle,\n\tStoreState,\n} from \"./StoreTypes\";\n\n/**\n * Create an isolated Zustand store for a sheet stack instance.\n *\n * Returns a store bundle containing the Zustand store plus two maps\n * that track ad-hoc (component-direct) registrations:\n * - `componentRegistry` — maps `ComponentType` → generated type key (dedup)\n * - `componentMap` — maps generated type key → `ComponentType` (renderer lookup)\n *\n * The ad-hoc counter is scoped per instance to prevent identity leaks across\n * multiple `createStacksheet()` calls or test runs.\n */\nexport function createSheetStore<TMap extends object>(\n\tconfig: ResolvedConfig,\n): SheetStoreBundle<TMap> {\n\ttype Item = SheetItem<Extract<keyof TMap, string>>;\n\n\tconst componentRegistry = new Map<AnyComponent, string>();\n\tconst componentMap = new Map<string, AnyComponent>();\n\n\t// Per-instance counter (not module-level) — prevents identity leaks across instances/tests\n\tlet adhocCounter = 0;\n\tfunction getNextKey() {\n\t\treturn `__adhoc_${adhocCounter++}`;\n\t}\n\n\t// Set of component names already warned about (avoid log spam)\n\tconst warnedNames = new Set<string>();\n\n\tfunction resolve(\n\t\tfirst: unknown,\n\t\tsecond: unknown,\n\t\tthird: unknown,\n\t\tfourth?: unknown,\n\t) {\n\t\treturn resolveArgs(\n\t\t\tcomponentRegistry,\n\t\t\tcomponentMap,\n\t\t\tgetNextKey,\n\t\t\twarnedNames,\n\t\t\tfirst,\n\t\t\tsecond,\n\t\t\tthird,\n\t\t\tfourth,\n\t\t);\n\t}\n\n\t/** Remove registry entries for type keys no longer in the stack */\n\tfunction pruneRegistry(remainingStack: readonly SheetItem[]) {\n\t\tconst usedTypes = new Set(remainingStack.map((item) => item.type));\n\t\tfor (const [component, typeKey] of componentRegistry) {\n\t\t\tif (!usedTypes.has(typeKey)) {\n\t\t\t\tcomponentRegistry.delete(component);\n\t\t\t\tcomponentMap.delete(typeKey);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst store = createStore<StoreState<TMap>>()((set, get) => {\n\t\t// ── Internal resolved methods (no double-resolution) ──\n\n\t\tfunction _openResolved({ type, id, data, ariaLabel }: ResolvedItem) {\n\t\t\tset({\n\t\t\t\tstack: [{ id, type, data, ariaLabel } as Item],\n\t\t\t\tisOpen: true,\n\t\t\t});\n\t\t}\n\n\t\tfunction _pushResolved({ type, id, data, ariaLabel }: ResolvedItem) {\n\t\t\tset((state) => {\n\t\t\t\tconst item = { id, type, data, ariaLabel } as Item;\n\t\t\t\tif (\n\t\t\t\t\tNumber.isFinite(config.maxDepth) &&\n\t\t\t\t\tstate.stack.length >= config.maxDepth\n\t\t\t\t) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstack: [...state.stack.slice(0, -1), item],\n\t\t\t\t\t\tisOpen: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tstack: [...state.stack, item],\n\t\t\t\t\tisOpen: true,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\n\t\tfunction _replaceResolved({ type, id, data, ariaLabel }: ResolvedItem) {\n\t\t\tset((state) => {\n\t\t\t\tconst item = { id, type, data, ariaLabel } as Item;\n\t\t\t\tif (state.stack.length === 0) {\n\t\t\t\t\treturn { stack: [item], isOpen: true };\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tstack: [...state.stack.slice(0, -1), item],\n\t\t\t\t\tisOpen: true,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tstack: [],\n\t\t\tisOpen: false,\n\n\t\t\topen(\n\t\t\t\tfirst: unknown,\n\t\t\t\tsecond?: unknown,\n\t\t\t\tthird?: unknown,\n\t\t\t\tfourth?: unknown,\n\t\t\t) {\n\t\t\t\t_openResolved(resolve(first, second, third, fourth));\n\t\t\t},\n\n\t\t\tpush(\n\t\t\t\tfirst: unknown,\n\t\t\t\tsecond?: unknown,\n\t\t\t\tthird?: unknown,\n\t\t\t\tfourth?: unknown,\n\t\t\t) {\n\t\t\t\t_pushResolved(resolve(first, second, third, fourth));\n\t\t\t},\n\n\t\t\treplace(\n\t\t\t\tfirst: unknown,\n\t\t\t\tsecond?: unknown,\n\t\t\t\tthird?: unknown,\n\t\t\t\tfourth?: unknown,\n\t\t\t) {\n\t\t\t\t_replaceResolved(resolve(first, second, third, fourth));\n\t\t\t},\n\n\t\t\tswap(first: unknown, second?: unknown, third?: unknown) {\n\t\t\t\tlet type: string;\n\t\t\t\tlet data: Record<string, unknown>;\n\t\t\t\tconst ariaLabel = resolvePresentationOptions(third)?.ariaLabel;\n\n\t\t\t\tif (typeof first === \"function\") {\n\t\t\t\t\tconst component = first as AnyComponent;\n\t\t\t\t\tlet typeKey = componentRegistry.get(component);\n\t\t\t\t\tif (!typeKey) {\n\t\t\t\t\t\twarnInlineComponent(component, componentRegistry, warnedNames);\n\t\t\t\t\t\ttypeKey = getNextKey();\n\t\t\t\t\t\tcomponentRegistry.set(component, typeKey);\n\t\t\t\t\t\tcomponentMap.set(typeKey, component);\n\t\t\t\t\t}\n\t\t\t\t\ttype = typeKey;\n\t\t\t\t\tdata = (second ?? {}) as Record<string, unknown>;\n\t\t\t\t} else {\n\t\t\t\t\ttype = first as string;\n\t\t\t\t\tdata = (second ?? {}) as Record<string, unknown>;\n\t\t\t\t}\n\n\t\t\t\tset((state) => {\n\t\t\t\t\tconst top = state.stack.at(-1);\n\t\t\t\t\tif (!top) {\n\t\t\t\t\t\treturn state;\n\t\t\t\t\t}\n\t\t\t\t\tconst newStack = [...state.stack];\n\t\t\t\t\tnewStack[newStack.length - 1] = {\n\t\t\t\t\t\tid: top.id,\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\tariaLabel: ariaLabel ?? top.ariaLabel,\n\t\t\t\t\t} as Item;\n\t\t\t\t\treturn { stack: newStack };\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tnavigate(\n\t\t\t\tfirst: unknown,\n\t\t\t\tsecond?: unknown,\n\t\t\t\tthird?: unknown,\n\t\t\t\tfourth?: unknown,\n\t\t\t) {\n\t\t\t\tconst resolved = resolve(first, second, third, fourth);\n\t\t\t\tconst { stack } = get();\n\t\t\t\tconst top = stack.at(-1);\n\n\t\t\t\tif (stack.length === 0) {\n\t\t\t\t\t_openResolved(resolved);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// For ad-hoc components, check if the top item's type maps to the same\n\t\t\t\t// component in the registry. For string types, compare directly.\n\t\t\t\tlet isSameType = top?.type === resolved.type;\n\t\t\t\tif (!isSameType && typeof first === \"function\") {\n\t\t\t\t\tconst topComponent = componentMap.get(top?.type ?? \"\");\n\t\t\t\t\tisSameType = topComponent === first;\n\t\t\t\t}\n\n\t\t\t\tif (isSameType) {\n\t\t\t\t\t_replaceResolved(resolved);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t_pushResolved(resolved);\n\t\t\t},\n\n\t\t\tsetData(first: unknown, second?: unknown, third?: unknown) {\n\t\t\t\t// setData always has an id: (type, id, data) or (Component, id, data)\n\t\t\t\tconst { id, data } = resolve(first, second, third);\n\t\t\t\tset((state) => {\n\t\t\t\t\tconst idx = state.stack.findIndex((item) => item.id === id);\n\t\t\t\t\tif (idx === -1) {\n\t\t\t\t\t\treturn state;\n\t\t\t\t\t}\n\t\t\t\t\tconst updated = [...state.stack];\n\t\t\t\t\tupdated[idx] = { ...updated[idx], data } as Item;\n\t\t\t\t\treturn { stack: updated };\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tremove(id) {\n\t\t\t\tset((state) => {\n\t\t\t\t\tconst next = state.stack.filter((item) => item.id !== id);\n\t\t\t\t\tif (next.length === state.stack.length) {\n\t\t\t\t\t\treturn state;\n\t\t\t\t\t}\n\t\t\t\t\tpruneRegistry(next);\n\t\t\t\t\tif (next.length === 0) {\n\t\t\t\t\t\treturn { stack: [], isOpen: false };\n\t\t\t\t\t}\n\t\t\t\t\treturn { stack: next };\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tpop() {\n\t\t\t\tset((state) => {\n\t\t\t\t\tif (state.stack.length <= 1) {\n\t\t\t\t\t\tpruneRegistry([]);\n\t\t\t\t\t\treturn { stack: [], isOpen: false };\n\t\t\t\t\t}\n\t\t\t\t\tconst next = state.stack.slice(0, -1);\n\t\t\t\t\tpruneRegistry(next);\n\t\t\t\t\treturn { stack: next, isOpen: true };\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclose() {\n\t\t\t\tpruneRegistry([]);\n\t\t\t\tset({ stack: [], isOpen: false });\n\t\t\t},\n\t\t};\n\t});\n\n\treturn { store, componentRegistry, componentMap };\n}\n","import { Portal } from \"@radix-ui/react-portal\";\nimport { createContext, useContext, useMemo } from \"react\";\nimport type { StoreApi } from \"zustand\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\nimport { resolveConfig } from \"./config\";\nimport { SheetRenderer } from \"./renderer\";\nimport { createSheetStore } from \"./store\";\nimport type {\n\tContentMap,\n\tResolvedConfig,\n\tSheetActions,\n\tStacksheetConfig,\n\tStacksheetInstance,\n\tStacksheetProviderProps,\n\tStacksheetSnapshot,\n} from \"./types\";\n\ntype StoreState<TMap extends object> = StacksheetSnapshot<TMap> &\n\tSheetActions<TMap>;\n\n/**\n * Create an isolated sheet stack instance with typed store, hooks, and provider.\n *\n * Works with both `interface` and `type` definitions:\n *\n * ```ts\n * // Using an interface\n * interface SheetDataMap {\n * \"bucket-create\": { onCreated?: (b: Bucket) => void };\n * \"bucket-edit\": { bucket: Bucket };\n * }\n *\n * // Using a type alias\n * type SheetDataMap = {\n * \"bucket-create\": { onCreated?: (b: Bucket) => void };\n * \"bucket-edit\": { bucket: Bucket };\n * };\n *\n * const { StacksheetProvider, useSheet, useStacksheetState } =\n * createStacksheet<SheetDataMap>();\n * ```\n *\n * Sheet content components receive their data as **spread props**:\n * ```ts\n * // Data map defines: \"bucket-edit\": { bucket: Bucket }\n * // Component receives: ({ bucket }: { bucket: Bucket }) => JSX.Element\n * ```\n *\n * Use `useSheetPanel()` inside content components to access `close()` and `back()`.\n */\nexport function createStacksheet<TMap extends object>(\n\tconfig?: StacksheetConfig,\n): StacksheetInstance<TMap> {\n\tconst resolved = resolveConfig(config);\n\tconst { store, componentMap } = createSheetStore<TMap>(resolved);\n\n\t// Context for the store — allows multiple instances\n\tconst StoreContext = createContext<{\n\t\tstore: StoreApi<StoreState<TMap>>;\n\t\tconfig: ResolvedConfig;\n\t} | null>(null);\n\n\tfunction useStoreContext() {\n\t\tconst ctx = useContext(StoreContext);\n\t\tif (!ctx) {\n\t\t\tthrow new Error(\n\t\t\t\t\"useSheet/useStacksheetState must be used within <StacksheetProvider>\",\n\t\t\t);\n\t\t}\n\t\treturn ctx;\n\t}\n\n\t// ── Provider ────────────────────────────────\n\n\tconst EMPTY_SHEETS = {} as ContentMap<TMap>;\n\n\tfunction StacksheetProvider({\n\t\tsheets = EMPTY_SHEETS,\n\t\tchildren,\n\t\tclassNames,\n\t\tlayout,\n\t\trenderHeader,\n\t}: StacksheetProviderProps<TMap>) {\n\t\tconst value = useMemo(() => ({ store, config: resolved }), []);\n\t\treturn (\n\t\t\t<StoreContext.Provider value={value}>\n\t\t\t\t{children}\n\t\t\t\t<Portal asChild={false}>\n\t\t\t\t\t<SheetRenderer<TMap>\n\t\t\t\t\t\tclassNames={classNames}\n\t\t\t\t\t\tcomponentMap={componentMap}\n\t\t\t\t\t\tconfig={resolved}\n\t\t\t\t\t\tlayout={layout}\n\t\t\t\t\t\trenderHeader={renderHeader}\n\t\t\t\t\t\tsheets={sheets}\n\t\t\t\t\t\tstore={store}\n\t\t\t\t\t/>\n\t\t\t\t</Portal>\n\t\t\t</StoreContext.Provider>\n\t\t);\n\t}\n\n\t// ── Hooks ───────────────────────────────────\n\n\tfunction useSheet(): SheetActions<TMap> {\n\t\tconst { store: s } = useStoreContext();\n\t\t// Actions are stable refs in Zustand v5 — read once, no subscription needed\n\t\treturn useMemo(() => {\n\t\t\tconst state = s.getState();\n\t\t\treturn {\n\t\t\t\topen: state.open,\n\t\t\t\tpush: state.push,\n\t\t\t\treplace: state.replace,\n\t\t\t\tswap: state.swap,\n\t\t\t\tnavigate: state.navigate,\n\t\t\t\tsetData: state.setData,\n\t\t\t\tremove: state.remove,\n\t\t\t\tpop: state.pop,\n\t\t\t\tclose: state.close,\n\t\t\t};\n\t\t}, [s]);\n\t}\n\n\tfunction useStacksheetState(): StacksheetSnapshot<TMap> {\n\t\tconst { store: s } = useStoreContext();\n\t\treturn useStore(\n\t\t\ts,\n\t\t\tuseShallow((state) => ({\n\t\t\t\tstack: state.stack,\n\t\t\t\tisOpen: state.isOpen,\n\t\t\t})),\n\t\t);\n\t}\n\n\treturn { StacksheetProvider, useSheet, useStacksheetState, store };\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport { Slot } from \"@radix-ui/react-slot\";\n\nimport { ArrowLeftIcon } from \"../icons\";\nimport { useSheetPanel } from \"../panel-context\";\nimport type { SheetOptionalContentPartProps } from \"./SheetPartTypes\";\n\nexport function SheetBack({\n\tasChild,\n\tclassName,\n\tstyle,\n\tchildren,\n}: SheetOptionalContentPartProps) {\n\tconst { back, isNested } = useSheetPanel();\n\n\tif (!isNested) {\n\t\treturn null;\n\t}\n\n\tconst Comp = asChild ? Slot : \"button\";\n\tconst defaults = asChild\n\t\t? undefined\n\t\t: \"flex min-h-11 min-w-11 shrink-0 cursor-pointer items-center justify-center rounded-md border-none bg-transparent p-0 text-inherit opacity-60 transition-opacity duration-150 hover:opacity-100\";\n\treturn (\n\t\t<Comp\n\t\t\taria-label={children ? undefined : \"Back\"}\n\t\t\tclassName={joinClassNames(defaults, className)}\n\t\t\tonClick={back}\n\t\t\tstyle={style}\n\t\t\ttype={asChild ? undefined : \"button\"}\n\t\t>\n\t\t\t{children ?? <ArrowLeftIcon />}\n\t\t</Comp>\n\t);\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport {\n\tRoot as ScrollAreaRoot,\n\tScrollbar as ScrollAreaScrollbar,\n\tThumb as ScrollAreaThumb,\n\tViewport as ScrollAreaViewport,\n} from \"@radix-ui/react-scroll-area\";\nimport { Slot } from \"@radix-ui/react-slot\";\n\nimport type { SheetPartProps } from \"./SheetPartTypes\";\n\nexport function SheetBody({\n\tasChild,\n\tclassName,\n\tstyle,\n\tchildren,\n}: SheetPartProps) {\n\tif (asChild) {\n\t\t// `relative min-h-0 flex-1` is structural for the panel flex layout.\n\t\treturn (\n\t\t\t<Slot\n\t\t\t\tclassName={joinClassNames(\"relative min-h-0 flex-1\", className)}\n\t\t\t\tdata-stacksheet-no-drag=\"\"\n\t\t\t\tstyle={style}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Slot>\n\t\t);\n\t}\n\n\treturn (\n\t\t<ScrollAreaRoot\n\t\t\tclassName={joinClassNames(\n\t\t\t\t\"relative flex min-h-0 flex-1 flex-col overflow-hidden\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tdata-stacksheet-no-drag=\"\"\n\t\t\tstyle={style}\n\t\t>\n\t\t\t<ScrollAreaViewport className=\"min-h-0 w-full flex-1 overscroll-contain\">\n\t\t\t\t{children}\n\t\t\t</ScrollAreaViewport>\n\t\t\t<ScrollAreaScrollbar\n\t\t\t\tclassName=\"flex w-2 touch-none select-none p-0.5\"\n\t\t\t\torientation=\"vertical\"\n\t\t\t>\n\t\t\t\t<ScrollAreaThumb className=\"relative flex-1 rounded bg-current/15\" />\n\t\t\t</ScrollAreaScrollbar>\n\t\t</ScrollAreaRoot>\n\t);\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport { Slot } from \"@radix-ui/react-slot\";\n\nimport { XIcon } from \"../icons\";\nimport { useSheetPanel } from \"../panel-context\";\nimport type { SheetOptionalContentPartProps } from \"./SheetPartTypes\";\n\nexport function SheetClose({\n\tasChild,\n\tclassName,\n\tstyle,\n\tchildren,\n}: SheetOptionalContentPartProps) {\n\tconst { close } = useSheetPanel();\n\tconst Comp = asChild ? Slot : \"button\";\n\tconst defaults = asChild\n\t\t? undefined\n\t\t: \"flex min-h-11 min-w-11 shrink-0 cursor-pointer items-center justify-center rounded-md border-none bg-transparent p-0 text-inherit opacity-60 transition-opacity duration-150 hover:opacity-100\";\n\treturn (\n\t\t<Comp\n\t\t\taria-label={children ? undefined : \"Close\"}\n\t\t\tclassName={joinClassNames(defaults, className)}\n\t\t\tonClick={close}\n\t\t\tstyle={style}\n\t\t\ttype={asChild ? undefined : \"button\"}\n\t\t>\n\t\t\t{children ?? <XIcon />}\n\t\t</Comp>\n\t);\n}\n","import { Slot } from \"@radix-ui/react-slot\";\nimport { useEffect } from \"react\";\n\nimport { useSheetPanel } from \"../panel-context\";\nimport type { SheetPartProps } from \"./SheetPartTypes\";\n\nexport function SheetDescription({\n\tasChild,\n\tclassName,\n\tstyle,\n\tchildren,\n}: SheetPartProps) {\n\tconst { panelId, registerDescription } = useSheetPanel();\n\n\tuseEffect(() => registerDescription(), [registerDescription]);\n\tconst Comp = asChild ? Slot : \"p\";\n\treturn (\n\t\t<Comp className={className} id={`${panelId}-desc`} style={style}>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport { Slot } from \"@radix-ui/react-slot\";\n\nimport type { SheetPartProps } from \"./SheetPartTypes\";\n\nexport function SheetFooter({\n\tasChild,\n\tclassName,\n\tstyle,\n\tchildren,\n}: SheetPartProps) {\n\tconst Comp = asChild ? Slot : \"footer\";\n\tconst defaults = asChild\n\t\t? \"shrink-0\"\n\t\t: \"flex shrink-0 items-center gap-2 border-t px-6 py-3\";\n\treturn (\n\t\t<Comp className={joinClassNames(defaults, className)} style={style}>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { KeyboardEvent as ReactKeyboardEvent } from \"react\";\n\nimport { useSheetPanel } from \"../panel-context\";\nimport type { SheetOptionalContentPartProps } from \"./SheetPartTypes\";\n\nexport function SheetHandle({\n\tasChild,\n\tclassName,\n\tstyle,\n\tchildren,\n}: SheetOptionalContentPartProps) {\n\tconst { close, back, isNested } = useSheetPanel();\n\tconst dismiss = isNested ? back : close;\n\tconst Comp = asChild ? Slot : \"div\";\n\tconst defaults = asChild\n\t\t? undefined\n\t\t: \"flex shrink-0 cursor-grab touch-none items-center justify-center pt-4 pb-1\";\n\treturn (\n\t\t<Comp\n\t\t\taria-label=\"Dismiss\"\n\t\t\tclassName={joinClassNames(defaults, className)}\n\t\t\tdata-stacksheet-handle=\"\"\n\t\t\tonClick={dismiss}\n\t\t\tonKeyDown={(e: ReactKeyboardEvent) => {\n\t\t\t\tif (e.key === \"Enter\" || e.key === \" \") {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tdismiss();\n\t\t\t\t}\n\t\t\t}}\n\t\t\trole=\"button\"\n\t\t\tstyle={style}\n\t\t\ttabIndex={0}\n\t\t>\n\t\t\t{children ?? (\n\t\t\t\t<div aria-hidden=\"true\" className=\"h-1 w-9 rounded-sm bg-current/25\" />\n\t\t\t)}\n\t\t</Comp>\n\t);\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport { Slot } from \"@radix-ui/react-slot\";\n\nimport type { SheetPartProps } from \"./SheetPartTypes\";\n\nexport function SheetHeader({\n\tasChild,\n\tclassName,\n\tstyle,\n\tchildren,\n}: SheetPartProps) {\n\tconst Comp = asChild ? Slot : \"header\";\n\t// Keep `shrink-0` even on asChild; without it, header collapses in a\n\t// flex-column panel layout. Drop the rest because it is decorative.\n\tconst defaults = asChild\n\t\t? \"shrink-0\"\n\t\t: \"flex h-14 shrink-0 items-center justify-between border-b px-6\";\n\treturn (\n\t\t<Comp className={joinClassNames(defaults, className)} style={style}>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport { Slot } from \"@radix-ui/react-slot\";\n\nimport { useSheetPanel } from \"../panel-context\";\nimport type { SheetPartProps } from \"./SheetPartTypes\";\n\nexport function SheetTitle({\n\tasChild,\n\tclassName,\n\tstyle,\n\tchildren,\n}: SheetPartProps) {\n\tconst { panelId } = useSheetPanel();\n\tconst Comp = asChild ? Slot : \"h2\";\n\tconst defaults = asChild ? undefined : \"font-semibold text-sm\";\n\treturn (\n\t\t<Comp\n\t\t\tclassName={joinClassNames(defaults, className)}\n\t\t\tid={`${panelId}-title`}\n\t\t\tstyle={style}\n\t\t>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n}\n","import { SheetBack } from \"./SheetBack\";\nimport { SheetBody } from \"./SheetBody\";\nimport { SheetClose } from \"./SheetClose\";\nimport { SheetDescription } from \"./SheetDescription\";\nimport { SheetFooter } from \"./SheetFooter\";\nimport { SheetHandle } from \"./SheetHandle\";\nimport { SheetHeader } from \"./SheetHeader\";\nimport { SheetTitle } from \"./SheetTitle\";\n\n/**\n * Composable Sheet Parts for building custom Sheet layouts.\n *\n * Use with `layout=\"composable\"` on the provider to opt into composable mode:\n * no auto header or scroll wrapper, full control over the Sheet structure.\n *\n * `Sheet.Title` and `Sheet.Description` are linked to the Panel's\n * `aria-labelledby` and `aria-describedby` via matching IDs.\n */\nexport const Sheet = {\n\tBack: SheetBack,\n\tBody: SheetBody,\n\tClose: SheetClose,\n\tDescription: SheetDescription,\n\tFooter: SheetFooter,\n\tHandle: SheetHandle,\n\tHeader: SheetHeader,\n\tTitle: SheetTitle,\n} as const;\n"],"mappings":"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"}
|
package/dist/media.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ResolvedConfig, Side } from "./types";
|
|
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,SAAS,CAAC;AAEpD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAavD;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAG5D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Side } from "./types";
|
|
2
|
+
export interface SheetPanelContextValue {
|
|
3
|
+
/** Pop the top sheet (go back one level) */
|
|
4
|
+
back: () => void;
|
|
5
|
+
/** Close the entire sheet stack */
|
|
6
|
+
close: () => void;
|
|
7
|
+
/** Whether a Sheet.Description is mounted inside this panel */
|
|
8
|
+
hasDescription: boolean;
|
|
9
|
+
/** Whether the stack has more than one sheet */
|
|
10
|
+
isNested: boolean;
|
|
11
|
+
/** Whether this is the top (active) sheet */
|
|
12
|
+
isTop: boolean;
|
|
13
|
+
/** Unique ID prefix for this panel (for aria-labelledby linking) */
|
|
14
|
+
panelId: string;
|
|
15
|
+
/** Called by Sheet.Description on mount to register its presence */
|
|
16
|
+
registerDescription: () => () => void;
|
|
17
|
+
/** Current resolved side (left/right/bottom) */
|
|
18
|
+
side: Side;
|
|
19
|
+
}
|
|
20
|
+
export declare const SheetPanelContext: import("react").Context<SheetPanelContextValue | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Access the current sheet panel's context.
|
|
23
|
+
* Must be called inside a component rendered by the sheet stack.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useSheetPanel(): SheetPanelContextValue;
|
|
26
|
+
//# sourceMappingURL=panel-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-context.d.ts","sourceRoot":"","sources":["../src/panel-context.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,MAAM,WAAW,sBAAsB;IACtC,4CAA4C;IAC5C,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,mCAAmC;IACnC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,+DAA+D;IAC/D,cAAc,EAAE,OAAO,CAAC;IACxB,gDAAgD;IAChD,QAAQ,EAAE,OAAO,CAAC;IAClB,6CAA6C;IAC7C,KAAK,EAAE,OAAO,CAAC;IACf,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,mBAAmB,EAAE,MAAM,MAAM,IAAI,CAAC;IACtC,gDAAgD;IAChD,IAAI,EAAE,IAAI,CAAC;CACX;AAED,eAAO,MAAM,iBAAiB,wDAE7B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,IAAI,sBAAsB,CAStD"}
|
package/dist/parts.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { SheetBack } from "./SheetParts/SheetBack";
|
|
2
|
+
export { SheetBody } from "./SheetParts/SheetBody";
|
|
3
|
+
export { SheetClose } from "./SheetParts/SheetClose";
|
|
4
|
+
export { SheetDescription } from "./SheetParts/SheetDescription";
|
|
5
|
+
export { SheetFooter } from "./SheetParts/SheetFooter";
|
|
6
|
+
export { SheetHandle } from "./SheetParts/SheetHandle";
|
|
7
|
+
export { SheetHeader } from "./SheetParts/SheetHeader";
|
|
8
|
+
export { Sheet } from "./SheetParts/SheetParts";
|
|
9
|
+
export type { SheetBackProps, SheetBodyProps, SheetCloseProps, SheetDescriptionProps, SheetFooterProps, SheetHandleProps, SheetHeaderProps, SheetOptionalContentPartProps, SheetPartProps, SheetTitleProps, } from "./SheetParts/SheetPartTypes";
|
|
10
|
+
export { SheetTitle } from "./SheetParts/SheetTitle";
|
|
11
|
+
//# sourceMappingURL=parts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../src/parts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,YAAY,EACX,cAAc,EACd,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,6BAA6B,EAC7B,cAAc,EACd,eAAe,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
import type { ResolvedConfig } from "./types";
|
|
3
|
+
export declare function usePanelHeight(panelRef: RefObject<HTMLDivElement | null>, hasSnapPoints: boolean): number;
|
|
4
|
+
export declare function useViewportHeight(active: boolean): number;
|
|
5
|
+
export declare function useBodyScale(config: ResolvedConfig, isOpen: boolean, prefersReducedMotion: boolean): void;
|
|
6
|
+
//# sourceMappingURL=renderer-effects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer-effects.d.ts","sourceRoot":"","sources":["../src/renderer-effects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAoC,MAAM,OAAO,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,cAAc,CAC7B,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAC1C,aAAa,EAAE,OAAO,GACpB,MAAM,CAmBR;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CA4BzD;AAED,wBAAgB,YAAY,CAC3B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,OAAO,EACf,oBAAoB,EAAE,OAAO,QAsC7B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import type { getStackTransform, SlideValues } from "./stacking";
|
|
3
|
+
import type { Side, StacksheetClassNames } from "./types";
|
|
4
|
+
export type ResolvedClassNames = Required<StacksheetClassNames>;
|
|
5
|
+
export declare function resolveClassNames(cn?: StacksheetClassNames): ResolvedClassNames;
|
|
6
|
+
export declare function buildAriaProps(isTop: boolean, isModal: boolean, isComposable: boolean, ariaLabel: string, panelId: string, hasDescription: boolean): Record<string, string | undefined>;
|
|
7
|
+
export declare function getDragTransform(side: Side, offset: number): {
|
|
8
|
+
x?: number;
|
|
9
|
+
y?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare const VISUAL_TWEEN: {
|
|
12
|
+
type: "tween";
|
|
13
|
+
duration: number;
|
|
14
|
+
ease: "easeOut";
|
|
15
|
+
};
|
|
16
|
+
export declare function buildPanelStyle(panelStyles: CSSProperties, isTop: boolean, hasPanelClass: boolean, isDragging: boolean): CSSProperties;
|
|
17
|
+
export declare function buildPanelTransition(isDragging: boolean, isTop: boolean, spring: Record<string, unknown>, stackSpring: Record<string, unknown>): {
|
|
18
|
+
type: "tween";
|
|
19
|
+
duration: number;
|
|
20
|
+
} | {
|
|
21
|
+
borderRadius: {
|
|
22
|
+
type: "tween";
|
|
23
|
+
duration: number;
|
|
24
|
+
ease: "easeOut";
|
|
25
|
+
};
|
|
26
|
+
boxShadow: {
|
|
27
|
+
type: "tween";
|
|
28
|
+
duration: number;
|
|
29
|
+
ease: "easeOut";
|
|
30
|
+
};
|
|
31
|
+
type?: undefined;
|
|
32
|
+
duration?: undefined;
|
|
33
|
+
};
|
|
34
|
+
export declare function computeSnapYOffset(side: Side, snapHeights: number[], activeSnapIndex: number, measuredHeight: number): number;
|
|
35
|
+
export declare function getBottomSlideDistance(measuredHeight: number): number;
|
|
36
|
+
export declare function resolveSlideFrom(side: Side, slideFrom: SlideValues, measuredHeight: number): SlideValues;
|
|
37
|
+
export declare function buildAnimateTarget(slideTarget: SlideValues, stackOffset: {
|
|
38
|
+
x?: number;
|
|
39
|
+
y?: number;
|
|
40
|
+
}, dragOffset: {
|
|
41
|
+
x?: number;
|
|
42
|
+
y?: number;
|
|
43
|
+
}, transform: ReturnType<typeof getStackTransform>, animatedRadius: Record<string, number>, transition: Record<string, unknown>, snapYOffset: number, isTop: boolean): {
|
|
44
|
+
boxShadow: string;
|
|
45
|
+
transition: Record<string, unknown>;
|
|
46
|
+
scale: number;
|
|
47
|
+
opacity: number;
|
|
48
|
+
x?: string | number;
|
|
49
|
+
y?: string | number;
|
|
50
|
+
};
|
|
51
|
+
export declare function getInitialRadius(side: Side): Record<string, number>;
|
|
52
|
+
export declare function getShadow(isNested: boolean): string;
|
|
53
|
+
//# sourceMappingURL=renderer-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer-helpers.d.ts","sourceRoot":"","sources":["../src/renderer-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAC;AAQhE,wBAAgB,iBAAiB,CAChC,EAAE,CAAC,EAAE,oBAAoB,GACvB,kBAAkB,CASpB;AAED,wBAAgB,cAAc,CAC7B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,OAAO,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,OAAO,GACrB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAiBpC;AAED,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACZ;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAc5B;AAED,eAAO,MAAM,YAAY;;;;CAIxB,CAAC;AAEF,wBAAgB,eAAe,CAC9B,WAAW,EAAE,aAAa,EAC1B,KAAK,EAAE,OAAO,EACd,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,OAAO,GACjB,aAAa,CAaf;AAED,wBAAgB,oBAAoB,CACnC,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;EAQpC;AAED,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EAAE,EACrB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,GACpB,MAAM,CAKR;AAED,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAQrE;AAED,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,WAAW,EACtB,cAAc,EAAE,MAAM,GACpB,WAAW,CAKb;AAED,wBAAgB,kBAAkB,CACjC,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACvC,UAAU,EAAE;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACtC,SAAS,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,EAC/C,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO;;;;;;;EAiBd;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUnE;AAOD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
var CloseWatcher: (new () => {
|
|
3
|
+
onclose: (() => void) | null;
|
|
4
|
+
destroy: () => void;
|
|
5
|
+
}) | undefined;
|
|
6
|
+
}
|
|
7
|
+
import { type ComponentType, type ReactNode } from "react";
|
|
8
|
+
import type { StoreApi } from "zustand";
|
|
9
|
+
import type { ContentMap, HeaderRenderProps, ResolvedConfig, SheetActions, StacksheetClassNames, StacksheetLayout, StacksheetSnapshot } from "./types";
|
|
10
|
+
interface SheetRendererProps<TMap extends object> {
|
|
11
|
+
classNames?: StacksheetClassNames;
|
|
12
|
+
/** Ad-hoc component map (type key → component) */
|
|
13
|
+
componentMap: Map<string, ComponentType<any>>;
|
|
14
|
+
config: ResolvedConfig;
|
|
15
|
+
layout?: StacksheetLayout;
|
|
16
|
+
renderHeader?: false | ((props: HeaderRenderProps) => ReactNode);
|
|
17
|
+
sheets: ContentMap<TMap>;
|
|
18
|
+
store: StoreApi<StacksheetSnapshot<TMap> & SheetActions<TMap>>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Root renderer component — manages the backdrop, scroll lock, snap points,
|
|
22
|
+
* close reasons, focus restoration, keyboard/CloseWatcher dismissal, and
|
|
23
|
+
* delegates per-panel rendering to `SheetPanel`.
|
|
24
|
+
*
|
|
25
|
+
* Mounted inside a Portal by `StacksheetProvider`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function SheetRenderer<TMap extends object>({ store, config, sheets, componentMap, classNames: classNamesProp, layout, renderHeader, }: SheetRendererProps<TMap>): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.tsx"],"names":[],"mappings":"AACA,OAAO,CAAC,MAAM,CAAC;IACd,IAAI,YAAY,EACb,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,GACjE,SAAS,CAAC;CACb;AAGD,OAAO,EACN,KAAK,aAAa,EAElB,KAAK,SAAS,EAMd,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQxC,OAAO,KAAK,EAEX,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,SAAS,CAAC;AAEjB,UAAU,kBAAkB,CAAC,IAAI,SAAS,MAAM;IAC/C,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,kDAAkD;IAElD,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,YAAY,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE,iBAAiB,KAAK,SAAS,CAAC,CAAC;IACjE,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,EAAE,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;CAC/D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,SAAS,MAAM,EAAE,EAClD,KAAK,EACL,MAAM,EACN,MAAM,EACN,YAAY,EACZ,UAAU,EAAE,cAAc,EAC1B,MAAM,EACN,YAAY,GACZ,EAAE,kBAAkB,CAAC,IAAI,CAAC,2CAmQ1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sheet-panel.d.ts","sourceRoot":"","sources":["../src/sheet-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SnapPoint } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve all snap points to sorted pixel heights (ascending).
|
|
4
|
+
* Returns an array of heights in px that the drawer should snap to.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveSnapPoints(points: SnapPoint[], viewportHeight: number): number[];
|
|
7
|
+
/**
|
|
8
|
+
* Given the current drag offset (from fully open), resolved snap heights,
|
|
9
|
+
* the panel height, and release velocity, find the best snap point index.
|
|
10
|
+
*
|
|
11
|
+
* `dragOffset` is positive in the dismiss direction (downward for bottom sheets).
|
|
12
|
+
* Snap heights are "how tall the drawer should be" (ascending order).
|
|
13
|
+
*
|
|
14
|
+
* Returns -1 if the gesture indicates full dismissal.
|
|
15
|
+
*/
|
|
16
|
+
export declare function findSnapTarget(dragOffset: number, panelHeight: number, snapHeights: number[], velocity: number, currentIndex: number, sequential: boolean): number;
|
|
17
|
+
/**
|
|
18
|
+
* Get the Y offset for a snap point relative to fully open (0 offset).
|
|
19
|
+
* Returns the number of pixels the drawer should be translated down from fully open.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getSnapOffset(snapIndex: number, snapHeights: number[], panelHeight: number): number;
|
|
22
|
+
//# sourceMappingURL=snap-points.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snap-points.d.ts","sourceRoot":"","sources":["../src/snap-points.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA8CzC;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,SAAS,EAAE,EACnB,cAAc,EAAE,MAAM,GACpB,MAAM,EAAE,CAsBV;AAWD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EAAE,EACrB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,OAAO,GACjB,MAAM,CAwDR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EAAE,EACrB,WAAW,EAAE,MAAM,GACjB,MAAM,CAMR"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spring presets inspired by iOS animation feel.
|
|
3
|
+
*
|
|
4
|
+
* - `subtle` — Barely noticeable bounce, professional.
|
|
5
|
+
* - `snappy` — Quick, responsive for interactions.
|
|
6
|
+
* - `stiff` — Very quick, controlled. Panels, drawers. **(default)**
|
|
7
|
+
*/
|
|
8
|
+
export declare const springs: {
|
|
9
|
+
readonly subtle: {
|
|
10
|
+
readonly stiffness: 300;
|
|
11
|
+
readonly damping: 30;
|
|
12
|
+
readonly mass: 1;
|
|
13
|
+
};
|
|
14
|
+
readonly snappy: {
|
|
15
|
+
readonly stiffness: 400;
|
|
16
|
+
readonly damping: 28;
|
|
17
|
+
readonly mass: 0.8;
|
|
18
|
+
};
|
|
19
|
+
readonly stiff: {
|
|
20
|
+
readonly stiffness: 400;
|
|
21
|
+
readonly damping: 40;
|
|
22
|
+
readonly mass: 1;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export type SpringPreset = keyof typeof springs;
|
|
26
|
+
//# sourceMappingURL=springs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"springs.d.ts","sourceRoot":"","sources":["../src/springs.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;CAI6B,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,OAAO,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import type { ResolvedConfig, Side, StackingConfig } from "./types";
|
|
3
|
+
export interface StackTransform {
|
|
4
|
+
borderRadius: number;
|
|
5
|
+
offset: number;
|
|
6
|
+
opacity: number;
|
|
7
|
+
scale: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Compute visual transforms for a panel at a given depth.
|
|
11
|
+
* depth=0 is the top (foreground) panel.
|
|
12
|
+
* Panels beyond renderThreshold are clamped to the edge position and faded out.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getStackTransform(depth: number, stacking: StackingConfig): StackTransform;
|
|
15
|
+
/**
|
|
16
|
+
* Border radius values for the animate target.
|
|
17
|
+
* Must be animated (not static CSS) so Motion applies scale correction
|
|
18
|
+
* when panels are scaled. See: https://motion.dev/docs/react-layout-animations#scale-correction
|
|
19
|
+
*/
|
|
20
|
+
export declare function getAnimatedBorderRadius(side: Side, depth: number, stacking: StackingConfig): Record<string, number>;
|
|
21
|
+
export interface SlideValues {
|
|
22
|
+
x?: string | number;
|
|
23
|
+
y?: string | number;
|
|
24
|
+
}
|
|
25
|
+
/** Motion initial/exit values for sliding from the given side. */
|
|
26
|
+
export declare function getSlideFrom(side: Side): SlideValues;
|
|
27
|
+
/** Motion animate target — the resting position. */
|
|
28
|
+
export declare function getSlideTarget(): SlideValues;
|
|
29
|
+
/** Translate offset that pushes stacked panels away from the stack edge. */
|
|
30
|
+
export declare function getStackOffset(side: Side, offset: number): {
|
|
31
|
+
x?: number;
|
|
32
|
+
y?: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Fixed-position styles for a panel, accounting for side, width, and depth.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getPanelStyles(side: Side, config: ResolvedConfig, index: number): CSSProperties;
|
|
38
|
+
//# 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,SAAS,CAAC;AAIpE,MAAM,WAAW,cAAc;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACtB,cAAc,CAiBhB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB;AAID,MAAM,WAAW,WAAW;IAC3B,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACpB;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAWpD;AAED,oDAAoD;AACpD,wBAAgB,cAAc,IAAI,WAAW,CAE5C;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAC7B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACZ;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAc5B;AAiBD;;GAEG;AACH,wBAAgB,cAAc,CAC7B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,MAAM,GACX,aAAa,CAoCf"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-duration:initial}}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing,.25rem) * 0)}.inset-x-0{inset-inline:calc(var(--spacing,.25rem) * 0)}.top-0{top:calc(var(--spacing,.25rem) * 0)}.bottom-0{bottom:calc(var(--spacing,.25rem) * 0)}.z-10{z-index:10}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.flex{display:flex}.hidden{display:none}.inline{display:inline}.h-1{height:calc(var(--spacing,.25rem) * 1)}.h-8{height:calc(var(--spacing,.25rem) * 8)}.h-14{height:calc(var(--spacing,.25rem) * 14)}.h-\[5px\]{height:5px}.min-h-0{min-height:calc(var(--spacing,.25rem) * 0)}.min-h-11{min-height:calc(var(--spacing,.25rem) * 11)}.w-1{width:calc(var(--spacing,.25rem) * 1)}.w-2{width:calc(var(--spacing,.25rem) * 2)}.w-6{width:calc(var(--spacing,.25rem) * 6)}.w-9{width:calc(var(--spacing,.25rem) * 9)}.w-full{width:100%}.min-w-11{min-width:calc(var(--spacing,.25rem) * 11)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing,.25rem) * 2)}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded{border-radius:.25rem}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md,.375rem)}.rounded-sm{border-radius:var(--radius-sm,.25rem)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-none{--tw-border-style:none;border-style:none}.bg-black\/5{background-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.bg-black\/5{background-color:color-mix(in oklab, var(--color-black,#000) 5%, transparent)}}.bg-current\/15{background-color:currentColor}@supports (color:color-mix(in lab, red, red)){.bg-current\/15{background-color:color-mix(in oklab, currentcolor 15%, transparent)}}.bg-current\/20{background-color:currentColor}@supports (color:color-mix(in lab, red, red)){.bg-current\/20{background-color:color-mix(in oklab, currentcolor 20%, transparent)}}.bg-current\/25{background-color:currentColor}@supports (color:color-mix(in lab, red, red)){.bg-current\/25{background-color:color-mix(in oklab, currentcolor 25%, transparent)}}.bg-transparent{background-color:#0000}.p-0{padding:calc(var(--spacing,.25rem) * 0)}.p-0\.5{padding:calc(var(--spacing,.25rem) * .5)}.px-4{padding-inline:calc(var(--spacing,.25rem) * 4)}.px-6{padding-inline:calc(var(--spacing,.25rem) * 6)}.py-3{padding-block:calc(var(--spacing,.25rem) * 3)}.pt-2\.5{padding-top:calc(var(--spacing,.25rem) * 2.5)}.pt-4{padding-top:calc(var(--spacing,.25rem) * 4)}.pb-1{padding-bottom:calc(var(--spacing,.25rem) * 1)}.pb-2{padding-bottom:calc(var(--spacing,.25rem) * 2)}.text-sm{font-size:var(--text-sm,.875rem);line-height:var(--tw-leading,var(--text-sm--line-height,calc(1.25 / .875)))}.font-semibold{--tw-font-weight:var(--font-weight-semibold,600);font-weight:var(--font-weight-semibold,600)}.text-inherit{color:inherit}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function,cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration,var(--default-transition-duration,.15s))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:opacity-100:hover{opacity:1}}[data-stacksheet-no-drag] [data-radix-scroll-area-viewport]>div{display:block!important}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}
|