@howells/stacksheet 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5,28 +5,16 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  /**
6
6
  * Spring presets inspired by iOS animation feel.
7
7
  *
8
- * - `soft` — Very gentle, slow settle. Loaders, radial pickers.
9
8
  * - `subtle` — Barely noticeable bounce, professional.
10
- * - `natural` — Balanced, general-purpose default.
11
9
  * - `snappy` — Quick, responsive for interactions.
12
10
  * - `stiff` — Very quick, controlled. Panels, drawers. **(default)**
13
11
  */
14
12
  declare const springs: {
15
- readonly soft: {
16
- readonly stiffness: 120;
17
- readonly damping: 18;
18
- readonly mass: 1;
19
- };
20
13
  readonly subtle: {
21
14
  readonly stiffness: 300;
22
15
  readonly damping: 30;
23
16
  readonly mass: 1;
24
17
  };
25
- readonly natural: {
26
- readonly stiffness: 200;
27
- readonly damping: 20;
28
- readonly mass: 1;
29
- };
30
18
  readonly snappy: {
31
19
  readonly stiffness: 400;
32
20
  readonly damping: 28;
@@ -40,6 +28,15 @@ declare const springs: {
40
28
  };
41
29
  type SpringPreset = keyof typeof springs;
42
30
 
31
+ /** Why the sheet stack was closed or popped */
32
+ type CloseReason = "escape" | "backdrop" | "swipe" | "programmatic";
33
+ /**
34
+ * A snap point for bottom sheets.
35
+ * - `number` 0-1: fraction of viewport height (e.g. 0.5 = 50vh)
36
+ * - `number` > 1: pixel value (e.g. 300 = 300px)
37
+ * - `string`: CSS length (e.g. "148px", "30rem")
38
+ */
39
+ type SnapPoint = number | string;
43
40
  interface StacksheetClassNames {
44
41
  /** Applied to backdrop overlay */
45
42
  backdrop?: string;
@@ -75,13 +72,13 @@ type SideConfig = Side | ResponsiveSide;
75
72
  interface StackingConfig {
76
73
  /** Scale reduction per depth level (default: 0.04) */
77
74
  scaleStep: number;
78
- /** Horizontal/vertical offset per depth level in px (default: 24) */
75
+ /** Pixel offset per depth level shifts panels away from the stack edge (default: 16) */
79
76
  offsetStep: number;
80
77
  /** Opacity reduction per depth level (default: 0) */
81
78
  opacityStep: number;
82
79
  /** Border radius applied to stacked panels in px (default: 12) */
83
80
  radius: number;
84
- /** Max depth before content stops rendering (default: 5) */
81
+ /** Max depth before content stops rendering (default: 3) */
85
82
  renderThreshold: number;
86
83
  }
87
84
  interface SpringConfig {
@@ -122,7 +119,15 @@ interface StacksheetConfig {
122
119
  /** Called when the top panel's entrance animation completes */
123
120
  onOpenComplete?: () => void;
124
121
  /** Called when the last panel's exit animation completes (stack fully closed) */
125
- onCloseComplete?: () => void;
122
+ onCloseComplete?: (reason: CloseReason) => void;
123
+ /** Snap positions for bottom sheets. Numbers 0-1 = viewport fraction, >1 = px, strings = CSS lengths. */
124
+ snapPoints?: SnapPoint[];
125
+ /** Currently active snap point index (controlled). */
126
+ snapPointIndex?: number;
127
+ /** Called when the active snap point changes. */
128
+ onSnapPointChange?: (index: number) => void;
129
+ /** When true, velocity can't skip intermediate snap points. Default: false */
130
+ snapToSequentialPoints?: boolean;
126
131
  /** Enable drag-to-dismiss. Default: true */
127
132
  drag?: boolean;
128
133
  /** Fraction of panel dimension to trigger close (0-1). Default: 0.25 */
@@ -154,7 +159,11 @@ interface ResolvedConfig {
154
159
  zIndex: number;
155
160
  ariaLabel: string;
156
161
  onOpenComplete?: () => void;
157
- onCloseComplete?: () => void;
162
+ onCloseComplete?: (reason: CloseReason) => void;
163
+ snapPoints: SnapPoint[];
164
+ snapPointIndex?: number;
165
+ onSnapPointChange?: (index: number) => void;
166
+ snapToSequentialPoints: boolean;
158
167
  drag: boolean;
159
168
  closeThreshold: number;
160
169
  velocityThreshold: number;
@@ -166,16 +175,16 @@ interface ResolvedConfig {
166
175
  /** Component rendered inside a sheet panel — receives data as spread props */
167
176
  type SheetContentComponent<TData = unknown> = ComponentType<TData extends Record<string, unknown> ? TData : Record<string, unknown>>;
168
177
  /** Map of sheet type → content component */
169
- type ContentMap<TMap extends Record<string, unknown>> = {
178
+ type ContentMap<TMap extends object> = {
170
179
  [K in keyof TMap]: SheetContentComponent<TMap[K]>;
171
180
  };
172
- interface StacksheetSnapshot<TMap extends Record<string, unknown>> {
181
+ interface StacksheetSnapshot<TMap extends object> {
173
182
  /** Current sheet stack, ordered bottom to top */
174
183
  stack: SheetItem<Extract<keyof TMap, string>>[];
175
184
  /** Whether any sheets are currently visible */
176
185
  isOpen: boolean;
177
186
  }
178
- interface SheetActions<TMap extends Record<string, unknown>> {
187
+ interface SheetActions<TMap extends object> {
179
188
  /** Replace stack with a single item */
180
189
  open<K extends Extract<keyof TMap, string>>(type: K, id: string, data: TMap[K]): void;
181
190
  /** Replace stack with an ad-hoc component */
@@ -215,7 +224,7 @@ interface SheetActions<TMap extends Record<string, unknown>> {
215
224
  /** Clear entire stack */
216
225
  close(): void;
217
226
  }
218
- interface StacksheetProviderProps<TMap extends Record<string, unknown>> {
227
+ interface StacksheetProviderProps<TMap extends object> {
219
228
  /** Map of sheet type keys to content components (optional — only needed for type registry pattern) */
220
229
  sheets?: ContentMap<TMap>;
221
230
  /** Your application content */
@@ -230,7 +239,7 @@ interface StacksheetProviderProps<TMap extends Record<string, unknown>> {
230
239
  */
231
240
  renderHeader?: false | ((props: HeaderRenderProps) => ReactNode);
232
241
  }
233
- interface StacksheetInstance<TMap extends Record<string, unknown>> {
242
+ interface StacksheetInstance<TMap extends object> {
234
243
  /** Provider component — wrap your app, pass sheets map */
235
244
  StacksheetProvider: ComponentType<StacksheetProviderProps<TMap>>;
236
245
  /** Hook returning sheet actions */
@@ -241,19 +250,40 @@ interface StacksheetInstance<TMap extends Record<string, unknown>> {
241
250
  store: zustand.StoreApi<StacksheetSnapshot<TMap> & SheetActions<TMap>>;
242
251
  }
243
252
 
253
+ /** Merge user-provided config with defaults. Resolves union types (side, spring) to concrete values. */
244
254
  declare function resolveConfig(config?: StacksheetConfig): ResolvedConfig;
245
255
 
246
256
  /**
247
257
  * Create an isolated sheet stack instance with typed store, hooks, and provider.
248
258
  *
259
+ * Works with both `interface` and `type` definitions:
260
+ *
249
261
  * ```ts
250
- * const { StacksheetProvider, useSheet, useStacksheetState } = createStacksheet<{
262
+ * // Using an interface
263
+ * interface SheetDataMap {
264
+ * "bucket-create": { onCreated?: (b: Bucket) => void };
265
+ * "bucket-edit": { bucket: Bucket };
266
+ * }
267
+ *
268
+ * // Using a type alias
269
+ * type SheetDataMap = {
251
270
  * "bucket-create": { onCreated?: (b: Bucket) => void };
252
271
  * "bucket-edit": { bucket: Bucket };
253
- * }>();
272
+ * };
273
+ *
274
+ * const { StacksheetProvider, useSheet, useStacksheetState } =
275
+ * createStacksheet<SheetDataMap>();
254
276
  * ```
277
+ *
278
+ * Sheet content components receive their data as **spread props**:
279
+ * ```ts
280
+ * // Data map defines: "bucket-edit": { bucket: Bucket }
281
+ * // Component receives: ({ bucket }: { bucket: Bucket }) => JSX.Element
282
+ * ```
283
+ *
284
+ * Use `useSheetPanel()` inside content components to access `close()` and `back()`.
255
285
  */
256
- declare function createStacksheet<TMap extends Record<string, unknown>>(config?: StacksheetConfig): StacksheetInstance<TMap>;
286
+ declare function createStacksheet<TMap extends object>(config?: StacksheetConfig): StacksheetInstance<TMap>;
257
287
 
258
288
  /**
259
289
  * Returns true when viewport width is at or below the breakpoint.
@@ -344,6 +374,16 @@ interface SheetBackProps {
344
374
  children?: ReactNode;
345
375
  }
346
376
  declare function SheetBack({ asChild, className, style, children }: SheetBackProps): react_jsx_runtime.JSX.Element | null;
377
+ /**
378
+ * Composable sheet parts for building custom panel layouts.
379
+ *
380
+ * Use with `renderHeader={false}` on the provider to opt into
381
+ * composable mode — no auto header or scroll wrapper, full control
382
+ * over the panel's structure.
383
+ *
384
+ * `Sheet.Title` and `Sheet.Description` are linked to the panel's
385
+ * `aria-labelledby` and `aria-describedby` via matching IDs.
386
+ */
347
387
  declare const Sheet: {
348
388
  readonly Handle: typeof SheetHandle;
349
389
  readonly Header: typeof SheetHeader;
@@ -378,4 +418,4 @@ declare function getSlideFrom(side: Side): SlideValues;
378
418
  */
379
419
  declare function getPanelStyles(side: Side, config: ResolvedConfig, _depth: number, index: number): CSSProperties;
380
420
 
381
- export { type ContentMap, type HeaderRenderProps, type ResolvedConfig, type ResponsiveSide, Sheet, type SheetActions, type SheetBackProps, type SheetBodyProps, type SheetCloseProps, type SheetContentComponent, type SheetDescriptionProps, type SheetFooterProps, type SheetHandleProps, type SheetHeaderProps, type SheetItem, type SheetPanelContextValue, type SheetTitleProps, type Side, type SideConfig, type SpringConfig, type SpringPreset, type StackingConfig, type StacksheetClassNames, type StacksheetConfig, type StacksheetInstance, type StacksheetProviderProps, type StacksheetSnapshot, createStacksheet, getPanelStyles, getSlideFrom, getStackTransform, resolveConfig, springs, useIsMobile, useResolvedSide, useSheetPanel };
421
+ export { type CloseReason, type ContentMap, type HeaderRenderProps, type ResolvedConfig, type ResponsiveSide, Sheet, type SheetActions, type SheetBackProps, type SheetBodyProps, type SheetCloseProps, type SheetContentComponent, type SheetDescriptionProps, type SheetFooterProps, type SheetHandleProps, type SheetHeaderProps, type SheetItem, type SheetPanelContextValue, type SheetTitleProps, type Side, type SideConfig, type SnapPoint, type SpringConfig, type SpringPreset, type StackingConfig, type StacksheetClassNames, type StacksheetConfig, type StacksheetInstance, type StacksheetProviderProps, type StacksheetSnapshot, createStacksheet, getPanelStyles, getSlideFrom, getStackTransform, resolveConfig, springs, useIsMobile, useResolvedSide, useSheetPanel };