@howells/stacksheet
Advanced tools
+125
-116
@@ -43,6 +43,6 @@ import * as zustand from 'zustand'; | ||
| backdrop?: string; | ||
| /** Applied to the header bar */ | ||
| header?: string; | ||
| /** Applied to each panel container */ | ||
| panel?: string; | ||
| /** Applied to the header bar */ | ||
| header?: string; | ||
| } | ||
@@ -59,3 +59,11 @@ interface HeaderRenderProps { | ||
| } | ||
| interface SheetPresentationOptions { | ||
| /** Override the dialog aria-label for this specific sheet instance. */ | ||
| ariaLabel?: string; | ||
| } | ||
| interface SheetItem<TType extends string = string> { | ||
| /** Optional per-sheet presentation metadata */ | ||
| ariaLabel?: string; | ||
| /** Data payload passed when opening the sheet */ | ||
| data: Record<string, unknown>; | ||
| /** Unique identifier for this sheet instance */ | ||
@@ -65,6 +73,5 @@ id: string; | ||
| type: TType; | ||
| /** Data payload passed when opening the sheet */ | ||
| data: Record<string, unknown>; | ||
| } | ||
| type Side = "left" | "right" | "bottom"; | ||
| type StacksheetLayout = "classic" | "composable"; | ||
| interface ResponsiveSide { | ||
@@ -76,4 +83,2 @@ desktop: Side; | ||
| interface StackingConfig { | ||
| /** Scale reduction per depth level (default: 0.04) */ | ||
| scaleStep: number; | ||
| /** Pixel offset per depth level — shifts panels away from the stack edge (default: 16) */ | ||
@@ -87,2 +92,4 @@ offsetStep: number; | ||
| renderThreshold: number; | ||
| /** Scale reduction per depth level (default: 0.04) */ | ||
| scaleStep: number; | ||
| } | ||
@@ -92,89 +99,89 @@ interface SpringConfig { | ||
| damping: number; | ||
| /** Mass — higher = more momentum (default: 0.8) */ | ||
| mass: number; | ||
| /** Stiffness — higher = snappier (default: 170) */ | ||
| stiffness: number; | ||
| /** Mass — higher = more momentum (default: 0.8) */ | ||
| mass: number; | ||
| } | ||
| interface StacksheetConfig { | ||
| /** Maximum stack depth. Default: Infinity (unlimited) */ | ||
| maxDepth?: number; | ||
| /** Default aria-label for dialog panels. Default: "Sheet dialog" */ | ||
| ariaLabel?: string; | ||
| /** Mobile breakpoint in px. Default: 768 */ | ||
| breakpoint?: number; | ||
| /** Close on backdrop click. Default: true */ | ||
| closeOnBackdrop?: boolean; | ||
| /** Close on ESC key. Default: true */ | ||
| closeOnEscape?: boolean; | ||
| /** Close on backdrop click. Default: true */ | ||
| closeOnBackdrop?: boolean; | ||
| /** Show backdrop overlay when open. Default: true */ | ||
| showOverlay?: boolean; | ||
| /** Fraction of panel dimension to trigger close (0-1). Default: 0.25 */ | ||
| closeThreshold?: number; | ||
| /** Allow any form of dismissal (drag, backdrop, escape). Default: true */ | ||
| dismissible?: boolean; | ||
| /** Enable drag-to-dismiss. Default: true */ | ||
| drag?: boolean; | ||
| /** Lock body scroll when open. Default: true */ | ||
| lockScroll?: boolean; | ||
| /** Panel width in px. Default: 420 */ | ||
| width?: number; | ||
| /** Maximum stack depth. Default: Infinity (unlimited) */ | ||
| maxDepth?: number; | ||
| /** Maximum panel width as CSS value. Default: "90vw" */ | ||
| maxWidth?: string; | ||
| /** Mobile breakpoint in px. Default: 768 */ | ||
| breakpoint?: number; | ||
| /** Modal mode — overlay + scroll lock + focus trap. Default: true */ | ||
| modal?: boolean; | ||
| /** Called when the last panel's exit animation completes (stack fully closed) */ | ||
| onCloseComplete?: (reason: CloseReason) => void; | ||
| /** Called when the top panel's entrance animation completes */ | ||
| onOpenComplete?: () => void; | ||
| /** Called when the active snap point changes. */ | ||
| onSnapPointChange?: (index: number) => void; | ||
| /** Scale factor applied to background (0-1). Default: 0.97 */ | ||
| scaleBackgroundAmount?: number; | ||
| /** Scale down [data-stacksheet-wrapper] when sheets open. Default: false */ | ||
| shouldScaleBackground?: boolean; | ||
| /** Show backdrop overlay when open. Default: true */ | ||
| showOverlay?: boolean; | ||
| /** Sheet slide-from side. Default: { desktop: "right", mobile: "bottom" } */ | ||
| side?: SideConfig; | ||
| /** Stacking visual parameters */ | ||
| stacking?: Partial<StackingConfig>; | ||
| /** Spring animation parameters — preset name or custom config */ | ||
| spring?: SpringPreset | Partial<SpringConfig>; | ||
| /** Base z-index. Default: 100 */ | ||
| zIndex?: number; | ||
| /** Default aria-label for dialog panels. Default: "Sheet dialog" */ | ||
| ariaLabel?: string; | ||
| /** Called when the top panel's entrance animation completes */ | ||
| onOpenComplete?: () => void; | ||
| /** Called when the last panel's exit animation completes (stack fully closed) */ | ||
| onCloseComplete?: (reason: CloseReason) => void; | ||
| /** Currently active snap point index (controlled). */ | ||
| snapPointIndex?: number; | ||
| /** Snap positions for bottom sheets. Numbers 0-1 = viewport fraction, >1 = px, strings = CSS lengths. */ | ||
| snapPoints?: SnapPoint[]; | ||
| /** Currently active snap point index (controlled). */ | ||
| snapPointIndex?: number; | ||
| /** Called when the active snap point changes. */ | ||
| onSnapPointChange?: (index: number) => void; | ||
| /** When true, velocity can't skip intermediate snap points. Default: false */ | ||
| snapToSequentialPoints?: boolean; | ||
| /** Enable drag-to-dismiss. Default: true */ | ||
| drag?: boolean; | ||
| /** Fraction of panel dimension to trigger close (0-1). Default: 0.25 */ | ||
| closeThreshold?: number; | ||
| /** Spring animation parameters — preset name or custom config */ | ||
| spring?: SpringPreset | Partial<SpringConfig>; | ||
| /** Stacking visual parameters */ | ||
| stacking?: Partial<StackingConfig>; | ||
| /** Velocity threshold (px/ms) to trigger close. Default: 0.5 */ | ||
| velocityThreshold?: number; | ||
| /** Allow any form of dismissal (drag, backdrop, escape). Default: true */ | ||
| dismissible?: boolean; | ||
| /** Modal mode — overlay + scroll lock + focus trap. Default: true */ | ||
| modal?: boolean; | ||
| /** Scale down [data-stacksheet-wrapper] when sheets open. Default: false */ | ||
| shouldScaleBackground?: boolean; | ||
| /** Scale factor applied to background (0-1). Default: 0.97 */ | ||
| scaleBackgroundAmount?: number; | ||
| /** Panel width in px. Default: 420 */ | ||
| width?: number; | ||
| /** Base z-index. Default: 100 */ | ||
| zIndex?: number; | ||
| } | ||
| /** Fully resolved config — all fields required */ | ||
| interface ResolvedConfig { | ||
| maxDepth: number; | ||
| ariaLabel: string; | ||
| breakpoint: number; | ||
| closeOnBackdrop: boolean; | ||
| closeOnEscape: boolean; | ||
| closeOnBackdrop: boolean; | ||
| showOverlay: boolean; | ||
| closeThreshold: number; | ||
| dismissible: boolean; | ||
| drag: boolean; | ||
| lockScroll: boolean; | ||
| width: number; | ||
| maxDepth: number; | ||
| maxWidth: string; | ||
| breakpoint: number; | ||
| modal: boolean; | ||
| onCloseComplete?: (reason: CloseReason) => void; | ||
| onOpenComplete?: () => void; | ||
| onSnapPointChange?: (index: number) => void; | ||
| scaleBackgroundAmount: number; | ||
| shouldScaleBackground: boolean; | ||
| showOverlay: boolean; | ||
| side: ResponsiveSide; | ||
| stacking: StackingConfig; | ||
| spring: SpringConfig; | ||
| zIndex: number; | ||
| ariaLabel: string; | ||
| onOpenComplete?: () => void; | ||
| onCloseComplete?: (reason: CloseReason) => void; | ||
| snapPointIndex?: number; | ||
| snapPoints: SnapPoint[]; | ||
| snapPointIndex?: number; | ||
| onSnapPointChange?: (index: number) => void; | ||
| snapToSequentialPoints: boolean; | ||
| drag: boolean; | ||
| closeThreshold: number; | ||
| spring: SpringConfig; | ||
| stacking: StackingConfig; | ||
| velocityThreshold: number; | ||
| dismissible: boolean; | ||
| modal: boolean; | ||
| shouldScaleBackground: boolean; | ||
| scaleBackgroundAmount: number; | ||
| width: number; | ||
| zIndex: number; | ||
| } | ||
@@ -188,36 +195,38 @@ /** Component rendered inside a sheet panel — receives data as spread props */ | ||
| interface StacksheetSnapshot<TMap extends object> { | ||
| /** Whether any sheets are currently visible */ | ||
| isOpen: boolean; | ||
| /** Current sheet stack, ordered bottom to top */ | ||
| stack: SheetItem<Extract<keyof TMap, string>>[]; | ||
| /** Whether any sheets are currently visible */ | ||
| isOpen: boolean; | ||
| } | ||
| interface SheetActions<TMap extends object> { | ||
| /** Clear entire stack */ | ||
| close(): void; | ||
| /** Smart: empty→open, same type on top→replace, different→push */ | ||
| navigate<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K], options?: SheetPresentationOptions): void; | ||
| /** Smart navigate with an ad-hoc component */ | ||
| navigate<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData, options?: SheetPresentationOptions): void; | ||
| /** Smart navigate with an ad-hoc component (explicit id) */ | ||
| navigate<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData, options?: SheetPresentationOptions): void; | ||
| /** Replace stack with a single item */ | ||
| open<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void; | ||
| open<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K], options?: SheetPresentationOptions): void; | ||
| /** Replace stack with an ad-hoc component */ | ||
| open<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData): void; | ||
| open<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData, options?: SheetPresentationOptions): void; | ||
| /** Replace stack with an ad-hoc component (explicit id) */ | ||
| open<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData): void; | ||
| open<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData, options?: SheetPresentationOptions): void; | ||
| /** Pop top item; close if last */ | ||
| pop(): void; | ||
| /** Push onto stack (replaces top at maxDepth) */ | ||
| push<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void; | ||
| push<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K], options?: SheetPresentationOptions): void; | ||
| /** Push an ad-hoc component onto the stack */ | ||
| push<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData): void; | ||
| push<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData, options?: SheetPresentationOptions): void; | ||
| /** Push an ad-hoc component onto the stack (explicit id) */ | ||
| push<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData): void; | ||
| push<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData, options?: SheetPresentationOptions): void; | ||
| /** Remove a specific sheet by id; close if last */ | ||
| remove(id: string): void; | ||
| /** Swap the top item */ | ||
| replace<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void; | ||
| replace<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K], options?: SheetPresentationOptions): void; | ||
| /** Swap the top item with an ad-hoc component */ | ||
| replace<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData): void; | ||
| replace<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData, options?: SheetPresentationOptions): void; | ||
| /** Swap the top item with an ad-hoc component (explicit id) */ | ||
| replace<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData): void; | ||
| /** Swap the top item's content in place (no animation) */ | ||
| swap<K extends Extract<keyof TMap, string>>(type: K, data: TMap[K]): void; | ||
| /** Swap the top item's content with an ad-hoc component (no animation) */ | ||
| swap<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData): void; | ||
| /** Smart: empty→open, same type on top→replace, different→push */ | ||
| navigate<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void; | ||
| /** Smart navigate with an ad-hoc component */ | ||
| navigate<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData): void; | ||
| /** Smart navigate with an ad-hoc component (explicit id) */ | ||
| navigate<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData): void; | ||
| replace<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData, options?: SheetPresentationOptions): void; | ||
| /** Update data on a sheet by id (no animation) */ | ||
@@ -227,12 +236,8 @@ setData<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void; | ||
| setData<TData extends Record<string, unknown>>(component: ComponentType<TData>, id: string, data: TData): void; | ||
| /** Remove a specific sheet by id; close if last */ | ||
| remove(id: string): void; | ||
| /** Pop top item; close if last */ | ||
| pop(): void; | ||
| /** Clear entire stack */ | ||
| close(): void; | ||
| /** Swap the top item's content in place (no animation) */ | ||
| swap<K extends Extract<keyof TMap, string>>(type: K, data: TMap[K], options?: SheetPresentationOptions): void; | ||
| /** Swap the top item's content with an ad-hoc component (no animation) */ | ||
| swap<TData extends Record<string, unknown>>(component: ComponentType<TData>, data: TData, options?: SheetPresentationOptions): void; | ||
| } | ||
| interface StacksheetProviderProps<TMap extends object> { | ||
| /** Map of sheet type keys to content components (optional — only needed for type registry pattern) */ | ||
| sheets?: ContentMap<TMap>; | ||
| /** Your application content */ | ||
@@ -242,9 +247,13 @@ children: ReactNode; | ||
| classNames?: StacksheetClassNames; | ||
| /** Panel layout mode. `composable` disables the auto header and scroll wrapper. */ | ||
| layout?: StacksheetLayout; | ||
| /** | ||
| * Controls the panel header rendering mode. | ||
| * Controls the classic-mode header rendering. | ||
| * - `undefined` — renders the default close/back header (classic mode) | ||
| * - `function` — custom header renderer (classic mode with custom header) | ||
| * - `false` — no auto header, no auto scroll wrapper (composable mode — use Sheet.* parts) | ||
| * - `false` — legacy alias for composable mode. Prefer `layout="composable"`. | ||
| */ | ||
| renderHeader?: false | ((props: HeaderRenderProps) => ReactNode); | ||
| /** Map of sheet type keys to content components (optional — only needed for type registry pattern) */ | ||
| sheets?: ContentMap<TMap>; | ||
| } | ||
@@ -254,2 +263,4 @@ interface StacksheetInstance<TMap extends object> { | ||
| StacksheetProvider: ComponentType<StacksheetProviderProps<TMap>>; | ||
| /** Raw Zustand store for advanced use */ | ||
| store: zustand.StoreApi<StacksheetSnapshot<TMap> & SheetActions<TMap>>; | ||
| /** Hook returning sheet actions */ | ||
@@ -259,4 +270,2 @@ useSheet: () => SheetActions<TMap>; | ||
| useStacksheetState: () => StacksheetSnapshot<TMap>; | ||
| /** Raw Zustand store for advanced use */ | ||
| store: zustand.StoreApi<StacksheetSnapshot<TMap> & SheetActions<TMap>>; | ||
| } | ||
@@ -305,6 +314,8 @@ | ||
| interface SheetPanelContextValue { | ||
| /** Pop the top sheet (go back one level) */ | ||
| back: () => void; | ||
| /** Close the entire sheet stack */ | ||
| close: () => void; | ||
| /** Pop the top sheet (go back one level) */ | ||
| back: () => void; | ||
| /** Whether a Sheet.Description is mounted inside this panel */ | ||
| hasDescription: boolean; | ||
| /** Whether the stack has more than one sheet */ | ||
@@ -316,8 +327,6 @@ isNested: boolean; | ||
| panelId: string; | ||
| /** Called by Sheet.Description on mount to register its presence */ | ||
| registerDescription: () => () => void; | ||
| /** Current resolved side (left/right/bottom) */ | ||
| side: Side; | ||
| /** Whether a Sheet.Description is mounted inside this panel */ | ||
| hasDescription: boolean; | ||
| /** Called by Sheet.Description on mount to register its presence */ | ||
| registerDescription: () => () => void; | ||
| } | ||
@@ -333,6 +342,6 @@ /** | ||
| asChild?: boolean; | ||
| /** Custom handle content. Defaults to a centered grab bar. */ | ||
| children?: ReactNode; | ||
| className?: string; | ||
| style?: CSSProperties; | ||
| /** Custom handle content. Defaults to a centered grab bar. */ | ||
| children?: ReactNode; | ||
| } | ||
@@ -342,5 +351,5 @@ declare function SheetHandle({ asChild, className, style, children, }: SheetHandleProps): react_jsx_runtime.JSX.Element; | ||
| asChild?: boolean; | ||
| children: ReactNode; | ||
| className?: string; | ||
| style?: CSSProperties; | ||
| children: ReactNode; | ||
| } | ||
@@ -350,5 +359,5 @@ declare function SheetHeader({ asChild, className, style, children, }: SheetHeaderProps): react_jsx_runtime.JSX.Element; | ||
| asChild?: boolean; | ||
| children: ReactNode; | ||
| className?: string; | ||
| style?: CSSProperties; | ||
| children: ReactNode; | ||
| } | ||
@@ -358,5 +367,5 @@ declare function SheetTitle({ asChild, className, style, children }: SheetTitleProps): react_jsx_runtime.JSX.Element; | ||
| asChild?: boolean; | ||
| children: ReactNode; | ||
| className?: string; | ||
| style?: CSSProperties; | ||
| children: ReactNode; | ||
| } | ||
@@ -367,5 +376,5 @@ declare function SheetDescription({ asChild, className, style, children, }: SheetDescriptionProps): react_jsx_runtime.JSX.Element; | ||
| asChild?: boolean; | ||
| children: ReactNode; | ||
| className?: string; | ||
| style?: CSSProperties; | ||
| children: ReactNode; | ||
| } | ||
@@ -375,5 +384,5 @@ declare function SheetBody({ asChild, className, style, children }: SheetBodyProps): react_jsx_runtime.JSX.Element; | ||
| asChild?: boolean; | ||
| children: ReactNode; | ||
| className?: string; | ||
| style?: CSSProperties; | ||
| children: ReactNode; | ||
| } | ||
@@ -383,6 +392,6 @@ declare function SheetFooter({ asChild, className, style, children, }: SheetFooterProps): react_jsx_runtime.JSX.Element; | ||
| asChild?: boolean; | ||
| /** Custom content. Defaults to an X icon. */ | ||
| children?: ReactNode; | ||
| className?: string; | ||
| style?: CSSProperties; | ||
| /** Custom content. Defaults to an X icon. */ | ||
| children?: ReactNode; | ||
| } | ||
@@ -392,6 +401,6 @@ declare function SheetClose({ asChild, className, style, children }: SheetCloseProps): react_jsx_runtime.JSX.Element; | ||
| asChild?: boolean; | ||
| /** Custom content. Defaults to an arrow-left icon. */ | ||
| children?: ReactNode; | ||
| className?: string; | ||
| style?: CSSProperties; | ||
| /** Custom content. Defaults to an arrow-left icon. */ | ||
| children?: ReactNode; | ||
| } | ||
@@ -402,3 +411,3 @@ declare function SheetBack({ asChild, className, style, children }: SheetBackProps): react_jsx_runtime.JSX.Element | null; | ||
| * | ||
| * Use with `renderHeader={false}` on the provider to opt into | ||
| * Use with `layout="composable"` on the provider to opt into | ||
| * composable mode — no auto header or scroll wrapper, full control | ||
@@ -405,0 +414,0 @@ * over the panel's structure. |
+94
-37
@@ -171,5 +171,5 @@ // src/create.tsx | ||
| case "em": { | ||
| const fontSize = typeof document !== "undefined" ? Number.parseFloat( | ||
| const fontSize = typeof document === "undefined" ? 16 : Number.parseFloat( | ||
| getComputedStyle(document.documentElement).fontSize | ||
| ) : 16; | ||
| ); | ||
| return value * fontSize; | ||
@@ -699,2 +699,23 @@ } | ||
| } | ||
| function useViewportHeight(active) { | ||
| const getHeight = useCallback2( | ||
| () => typeof window === "undefined" ? 0 : window.visualViewport?.height ?? window.innerHeight, | ||
| [] | ||
| ); | ||
| const [height, setHeight] = useState2(() => getHeight()); | ||
| useEffect3(() => { | ||
| if (!active || typeof window === "undefined") { | ||
| return; | ||
| } | ||
| const update = () => setHeight(getHeight()); | ||
| update(); | ||
| window.addEventListener("resize", update); | ||
| window.visualViewport?.addEventListener("resize", update); | ||
| return () => { | ||
| window.removeEventListener("resize", update); | ||
| window.visualViewport?.removeEventListener("resize", update); | ||
| }; | ||
| }, [active, getHeight]); | ||
| return height; | ||
| } | ||
| function buildPanelStyle(panelStyles, isTop, hasPanelClass, isDragging) { | ||
@@ -788,3 +809,3 @@ return { | ||
| } | ||
| function PanelInnerContent({ | ||
| var PanelInnerContent = memo(function PanelInnerContent2({ | ||
| isComposable, | ||
@@ -812,2 +833,9 @@ shouldRender, | ||
| ] }); | ||
| }); | ||
| PanelInnerContent.displayName = "PanelInnerContent"; | ||
| function resolvePanelLayout(layout, renderHeader) { | ||
| if (layout) { | ||
| return layout; | ||
| } | ||
| return renderHeader === false ? "composable" : "classic"; | ||
| } | ||
@@ -879,2 +907,3 @@ function BottomHandle({ onDismiss }) { | ||
| onSnap, | ||
| layout, | ||
| renderHeader, | ||
@@ -925,3 +954,3 @@ slideFrom, | ||
| ); | ||
| const ariaLabel = (typeof item.data?.__ariaLabel === "string" ? item.data.__ariaLabel : void 0) ?? config.ariaLabel; | ||
| const ariaLabel = item.ariaLabel ?? (typeof item.data?.__ariaLabel === "string" ? item.data.__ariaLabel : void 0) ?? config.ariaLabel; | ||
| const panelId = `stacksheet-${item.id}`; | ||
@@ -955,3 +984,4 @@ const [hasDescription, setHasDescription] = useState2(false); | ||
| ); | ||
| const isComposable = renderHeader === false; | ||
| const panelLayout = resolvePanelLayout(layout, renderHeader); | ||
| const isComposable = panelLayout === "composable"; | ||
| const hasPanelClass = classNames.panel !== ""; | ||
@@ -965,8 +995,11 @@ const dragOffset = getDragTransform(side, dragState.offset); | ||
| ); | ||
| const headerProps = { | ||
| isNested, | ||
| onBack: pop, | ||
| onClose: close, | ||
| side | ||
| }; | ||
| const headerProps = useMemo( | ||
| () => ({ | ||
| isNested, | ||
| onBack: pop, | ||
| onClose: close, | ||
| side | ||
| }), | ||
| [close, isNested, pop, side] | ||
| ); | ||
| const ariaProps = buildAriaProps( | ||
@@ -1118,2 +1151,3 @@ isTop, | ||
| classNames: classNamesProp, | ||
| layout, | ||
| renderHeader | ||
@@ -1131,8 +1165,8 @@ }) { | ||
| ); | ||
| const viewportHeight = useViewportHeight( | ||
| isOpen && side === "bottom" && config.snapPoints.length > 0 | ||
| ); | ||
| const snapHeights = useMemo( | ||
| () => side === "bottom" && config.snapPoints.length > 0 ? resolveSnapPoints( | ||
| config.snapPoints, | ||
| typeof window !== "undefined" ? window.innerHeight : 0 | ||
| ) : [], | ||
| [side, config.snapPoints] | ||
| () => side === "bottom" && config.snapPoints.length > 0 ? resolveSnapPoints(config.snapPoints, viewportHeight) : [], | ||
| [side, config.snapPoints, viewportHeight] | ||
| ); | ||
@@ -1300,2 +1334,3 @@ const [internalSnapIndex, setInternalSnapIndex] = useState2( | ||
| item, | ||
| layout, | ||
| onSnap: handleSnap, | ||
@@ -1341,2 +1376,12 @@ pop, | ||
| import { createStore } from "zustand"; | ||
| function resolvePresentationOptions(value) { | ||
| if (!(value && typeof value === "object")) { | ||
| return void 0; | ||
| } | ||
| const candidate = value; | ||
| if (candidate.ariaLabel !== void 0 && typeof candidate.ariaLabel !== "string") { | ||
| return void 0; | ||
| } | ||
| return candidate; | ||
| } | ||
| function warnInlineComponent(component, componentRegistry, warnedNames) { | ||
@@ -1364,3 +1409,3 @@ if (typeof process === "undefined" || process?.env?.NODE_ENV === "production") { | ||
| } | ||
| function resolveArgs(componentRegistry, componentMap, getNextKey, warnedNames, first, second, third) { | ||
| function resolveArgs(componentRegistry, componentMap, getNextKey, warnedNames, first, second, third, fourth) { | ||
| if (typeof first === "function") { | ||
@@ -1377,2 +1422,3 @@ const component = first; | ||
| return { | ||
| ariaLabel: resolvePresentationOptions(fourth)?.ariaLabel, | ||
| type: typeKey, | ||
@@ -1384,2 +1430,3 @@ id: second, | ||
| return { | ||
| ariaLabel: resolvePresentationOptions(third)?.ariaLabel, | ||
| type: typeKey, | ||
@@ -1391,2 +1438,3 @@ id: crypto.randomUUID(), | ||
| return { | ||
| ariaLabel: resolvePresentationOptions(fourth)?.ariaLabel, | ||
| type: first, | ||
@@ -1405,3 +1453,3 @@ id: second, | ||
| const warnedNames = /* @__PURE__ */ new Set(); | ||
| function resolve(first, second, third) { | ||
| function resolve(first, second, third, fourth) { | ||
| return resolveArgs( | ||
@@ -1414,3 +1462,4 @@ componentRegistry, | ||
| second, | ||
| third | ||
| third, | ||
| fourth | ||
| ); | ||
@@ -1428,11 +1477,11 @@ } | ||
| const store = createStore()((set, get) => { | ||
| function _openResolved({ type, id, data }) { | ||
| function _openResolved({ type, id, data, ariaLabel }) { | ||
| set({ | ||
| stack: [{ id, type, data }], | ||
| stack: [{ id, type, data, ariaLabel }], | ||
| isOpen: true | ||
| }); | ||
| } | ||
| function _pushResolved({ type, id, data }) { | ||
| function _pushResolved({ type, id, data, ariaLabel }) { | ||
| set((state) => { | ||
| const item = { id, type, data }; | ||
| const item = { id, type, data, ariaLabel }; | ||
| if (Number.isFinite(config.maxDepth) && state.stack.length >= config.maxDepth) { | ||
@@ -1450,5 +1499,5 @@ return { | ||
| } | ||
| function _replaceResolved({ type, id, data }) { | ||
| function _replaceResolved({ type, id, data, ariaLabel }) { | ||
| set((state) => { | ||
| const item = { id, type, data }; | ||
| const item = { id, type, data, ariaLabel }; | ||
| if (state.stack.length === 0) { | ||
@@ -1466,14 +1515,15 @@ return { stack: [item], isOpen: true }; | ||
| isOpen: false, | ||
| open(first, second, third) { | ||
| _openResolved(resolve(first, second, third)); | ||
| open(first, second, third, fourth) { | ||
| _openResolved(resolve(first, second, third, fourth)); | ||
| }, | ||
| push(first, second, third) { | ||
| _pushResolved(resolve(first, second, third)); | ||
| push(first, second, third, fourth) { | ||
| _pushResolved(resolve(first, second, third, fourth)); | ||
| }, | ||
| replace(first, second, third) { | ||
| _replaceResolved(resolve(first, second, third)); | ||
| replace(first, second, third, fourth) { | ||
| _replaceResolved(resolve(first, second, third, fourth)); | ||
| }, | ||
| swap(first, second) { | ||
| swap(first, second, third) { | ||
| let type; | ||
| let data; | ||
| const ariaLabel = resolvePresentationOptions(third)?.ariaLabel; | ||
| if (typeof first === "function") { | ||
@@ -1500,8 +1550,13 @@ const component = first; | ||
| const newStack = [...state.stack]; | ||
| newStack[newStack.length - 1] = { id: top.id, type, data }; | ||
| newStack[newStack.length - 1] = { | ||
| id: top.id, | ||
| type, | ||
| data, | ||
| ariaLabel: ariaLabel ?? top.ariaLabel | ||
| }; | ||
| return { stack: newStack }; | ||
| }); | ||
| }, | ||
| navigate(first, second, third) { | ||
| const resolved = resolve(first, second, third); | ||
| navigate(first, second, third, fourth) { | ||
| const resolved = resolve(first, second, third, fourth); | ||
| const { stack } = get(); | ||
@@ -1589,2 +1644,3 @@ const top = stack.at(-1); | ||
| classNames, | ||
| layout, | ||
| renderHeader | ||
@@ -1601,2 +1657,3 @@ }) { | ||
| config: resolved, | ||
| layout, | ||
| renderHeader, | ||
@@ -1769,3 +1826,3 @@ sheets, | ||
| function SheetClose({ asChild, className, style, children }) { | ||
| const { close, back, isNested } = useSheetPanel(); | ||
| const { close } = useSheetPanel(); | ||
| const Comp = asChild ? Slot : "button"; | ||
@@ -1777,3 +1834,3 @@ return /* @__PURE__ */ jsx4( | ||
| className: `flex h-8 w-8 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 ${className ?? ""}`, | ||
| onClick: isNested ? back : close, | ||
| onClick: close, | ||
| style, | ||
@@ -1780,0 +1837,0 @@ type: asChild ? void 0 : "button", |
+2
-2
@@ -1,2 +0,2 @@ | ||
| /*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */ | ||
| @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-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--spacing:.25rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--font-weight-semibold:600;--radius-sm:.25rem;--radius-md:.375rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.bottom-0{bottom:calc(var(--spacing)*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)*1)}.h-8{height:calc(var(--spacing)*8)}.h-10{height:calc(var(--spacing)*10)}.h-14{height:calc(var(--spacing)*14)}.min-h-0{min-height:calc(var(--spacing)*0)}.w-2{width:calc(var(--spacing)*2)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-\[5px\]{width:5px}.w-full{width:100%}.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}.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)*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-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.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-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\/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-current\/35{background-color:currentColor}@supports (color:color-mix(in lab, red, red)){.bg-current\/35{background-color:color-mix(in oklab,currentcolor 35%,transparent)}}.bg-transparent{background-color:#0000}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-3{padding-block:calc(var(--spacing)*3)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-4{padding-top:calc(var(--spacing)*4)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-inherit{color:inherit}.opacity-60{opacity:.6}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.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));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.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-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false} | ||
| /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */ | ||
| @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-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-semibold:600;--radius-sm:.25rem;--radius-md:.375rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.top-0{top:calc(var(--spacing) * 0)}.bottom-0{bottom:calc(var(--spacing) * 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) * 1)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-14{height:calc(var(--spacing) * 14)}.min-h-0{min-height:calc(var(--spacing) * 0)}.w-2{width:calc(var(--spacing) * 2)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-\[5px\]{width:5px}.w-full{width:100%}.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) * 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-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.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-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\/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-current\/35{background-color:currentColor}@supports (color:color-mix(in lab, red, red)){.bg-current\/35{background-color:color-mix(in oklab, currentcolor 35%, transparent)}}.bg-transparent{background-color:#0000}.p-0{padding:calc(var(--spacing) * 0)}.p-0\.5{padding:calc(var(--spacing) * .5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-3{padding-block:calc(var(--spacing) * 3)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-inherit{color:inherit}.opacity-60{opacity:.6}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.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));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.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-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false} |
+27
-31
| { | ||
| "name": "@howells/stacksheet", | ||
| "version": "1.1.11", | ||
| "version": "1.2.0", | ||
| "private": false, | ||
@@ -35,17 +35,2 @@ "description": "Typed, animated sheet stack system. Zustand store + Motion animations with Apple-style depth stacking.", | ||
| }, | ||
| "scripts": { | ||
| "build": "tsup && pnpm run build:styles", | ||
| "build:styles": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --minify", | ||
| "dev": "pnpm build && pnpm --filter stacksheet-docs dev", | ||
| "dev:lib": "tsup --watch", | ||
| "format": "ultracite fix --unsafe", | ||
| "lint": "biome check src --write --unsafe", | ||
| "prepack": "pnpm build", | ||
| "docs": "tsx scripts/generate-docs.ts", | ||
| "test": "vitest run", | ||
| "test:watch": "vitest", | ||
| "typecheck": "tsc --noEmit", | ||
| "prepare": "husky", | ||
| "knip": "knip" | ||
| }, | ||
| "keywords": [ | ||
@@ -66,5 +51,5 @@ "sheet", | ||
| "focus-trap-react": "^12.0.0", | ||
| "motion": "^12.0.0", | ||
| "motion": "^12.38.0", | ||
| "react-remove-scroll": "^2.7.2", | ||
| "zustand": "^5.0.0" | ||
| "zustand": "^5.0.12" | ||
| }, | ||
@@ -76,20 +61,31 @@ "peerDependencies": { | ||
| "devDependencies": { | ||
| "@tailwindcss/cli": "^4.1.17", | ||
| "@biomejs/biome": "^2.3.14", | ||
| "@types/react": "^19.0.0", | ||
| "@types/react-dom": "^19.0.0", | ||
| "@biomejs/biome": "^2.4.10", | ||
| "@tailwindcss/cli": "^4.2.2", | ||
| "@types/react": "^19.2.14", | ||
| "@types/react-dom": "^19.2.3", | ||
| "husky": "^9.1.7", | ||
| "knip": "^5.83.1", | ||
| "lint-staged": "^16.2.7", | ||
| "next": "^16.1.6", | ||
| "tailwindcss": "^4.1.17", | ||
| "knip": "^6.3.0", | ||
| "lint-staged": "^16.4.0", | ||
| "next": "^16.2.2", | ||
| "tailwindcss": "^4.2.2", | ||
| "tsup": "^8.5.1", | ||
| "typescript": "^5.7.0", | ||
| "ultracite": "^7.1.5", | ||
| "vitest": "^4.0.18" | ||
| "typescript": "^6.0.2", | ||
| "ultracite": "^7.4.3", | ||
| "vitest": "^4.1.2" | ||
| }, | ||
| "packageManager": "pnpm@10.12.4", | ||
| "lint-staged": { | ||
| "*.{js,ts,jsx,tsx,json,jsonc,css}": "biome format --write --no-errors-on-unmatched" | ||
| }, | ||
| "scripts": { | ||
| "build": "tsup && pnpm run build:styles", | ||
| "build:styles": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --minify", | ||
| "dev": "pnpm build && pnpm --filter stacksheet-docs dev", | ||
| "dev:lib": "tsup --watch", | ||
| "format": "ultracite fix --unsafe", | ||
| "lint": "biome check src --write --unsafe", | ||
| "test": "vitest run", | ||
| "test:watch": "vitest", | ||
| "typecheck": "tsc --noEmit", | ||
| "knip": "knip" | ||
| } | ||
| } | ||
| } |
Sorry, the diff of this file is too big to display
210834
3.36%2243
3.03%Updated
Updated