@surdeddd/bottom-sheet 0.1.0 → 0.2.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.
Files changed (50) hide show
  1. package/README.md +6 -0
  2. package/dist/BottomSheetEngine-CIT9Htti.d.cts +219 -0
  3. package/dist/BottomSheetEngine-Df9MwBbm.d.ts +219 -0
  4. package/dist/element.cjs +95 -440
  5. package/dist/element.d.cts +3 -56
  6. package/dist/element.d.ts +3 -56
  7. package/dist/element.iife.global.js +2 -2
  8. package/dist/element.js +95 -440
  9. package/dist/index.cjs +84 -494
  10. package/dist/index.d.cts +3 -84
  11. package/dist/index.d.ts +3 -84
  12. package/dist/index.js +84 -494
  13. package/dist/integrations/formik.d.cts +2 -8
  14. package/dist/integrations/formik.d.ts +2 -8
  15. package/dist/integrations/react-hook-form.d.cts +2 -11
  16. package/dist/integrations/react-hook-form.d.ts +2 -11
  17. package/dist/overlay.cjs +0 -87
  18. package/dist/overlay.d.cts +1 -137
  19. package/dist/overlay.d.ts +1 -137
  20. package/dist/overlay.js +0 -87
  21. package/dist/preact.d.cts +2 -2
  22. package/dist/preact.d.ts +2 -2
  23. package/dist/preact.js +0 -1
  24. package/dist/qwik.cjs +87 -439
  25. package/dist/qwik.d.cts +3 -24
  26. package/dist/qwik.d.ts +3 -24
  27. package/dist/qwik.js +87 -439
  28. package/dist/react.cjs +91 -496
  29. package/dist/react.d.cts +16 -158
  30. package/dist/react.d.ts +16 -158
  31. package/dist/react.js +91 -496
  32. package/dist/solid.cjs +87 -439
  33. package/dist/solid.d.cts +4 -31
  34. package/dist/solid.d.ts +4 -31
  35. package/dist/solid.js +87 -439
  36. package/dist/styles.css +27 -102
  37. package/dist/svelte.cjs +139 -462
  38. package/dist/svelte.d.ts +9 -2
  39. package/dist/svelte.js +139 -462
  40. package/dist/themes/ios.css +0 -3
  41. package/dist/themes/material.css +0 -3
  42. package/dist/themes/vercel.css +0 -3
  43. package/dist/{transform-Brkf-wzo.d.cts → transform-jVfAikE9.d.cts} +0 -1
  44. package/dist/{transform-Brkf-wzo.d.ts → transform-jVfAikE9.d.ts} +0 -1
  45. package/dist/vue.cjs +104 -446
  46. package/dist/vue.d.ts +7 -1
  47. package/dist/vue.js +105 -447
  48. package/package.json +3 -3
  49. package/dist/BottomSheetEngine-CvSVbo6c.d.cts +0 -704
  50. package/dist/BottomSheetEngine-DbO8rW_3.d.ts +0 -704
package/dist/react.d.cts CHANGED
@@ -1,143 +1,64 @@
1
- import { b as EngineOptions, E as EngineState, B as BottomSheetEngine, S as SnapPointDef, a as SheetMode } from './BottomSheetEngine-CvSVbo6c.cjs';
2
- export { c as SnapPoint } from './BottomSheetEngine-CvSVbo6c.cjs';
1
+ import { b as EngineOptions, E as EngineState, j as ScrimUpdate, f as ScrimOverlayOptions, B as BottomSheetEngine, S as SnapPointDef, a as SheetMode } from './BottomSheetEngine-CIT9Htti.cjs';
2
+ export { c as SnapPoint } from './BottomSheetEngine-CIT9Htti.cjs';
3
3
  import { OverlayOptions, OverlayState, Overlay as OverlayEngine } from './overlay.cjs';
4
4
  export { OverlayEdge } from './overlay.cjs';
5
5
  import * as react from 'react';
6
6
  import { CSSProperties, ReactNode } from 'react';
7
- import './transform-Brkf-wzo.cjs';
7
+ import './transform-jVfAikE9.cjs';
8
8
 
9
- type EngineOptionsForProps = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "screenComponent">;
10
- /**
11
- * Header content for the sheet. Two forms are supported:
12
- * - **Static node**: `header={<h2>Title</h2>}` — rendered once and never
13
- * updated when the active snap changes.
14
- * - **Render function**: `header={state => <h2>{state.activeId}</h2>}` —
15
- * called on every settled snap change with the current `EngineState`,
16
- * so the header can morph per snap (e.g. minimized header vs full
17
- * header). The function fires from the same `useSyncExternalStore`
18
- * subscription that drives the rest of the component, so identity is
19
- * stable between snaps and only re-renders on transitions.
20
- */
9
+ type EngineOptionsForProps = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "scrim">;
21
10
  type HeaderProp = ReactNode | ((state: EngineState) => ReactNode);
22
11
  type BottomSheetProps = EngineOptionsForProps & {
23
- /** Render the dimmed overlay behind the sheet. Default: true. */
24
12
  backdrop?: boolean;
25
- /** Close when the backdrop is clicked. Default: true. */
26
13
  closeOnBackdrop?: boolean;
27
- /** Optional className appended to the root sheet element. */
28
14
  className?: string;
29
15
  style?: CSSProperties;
30
- /**
31
- * Header content (above the scrollable content; doubles as drag handle
32
- * area). Accepts either a static `ReactNode` or a function
33
- * `(state: EngineState) => ReactNode` that re-renders on every snap
34
- * transition — letting consumers show different markup per snap state
35
- * (e.g. minimized vs half vs full).
36
- */
37
16
  header?: HeaderProp;
38
- /** Children become the scrollable content area. */
39
17
  children?: ReactNode;
40
- /** Slot above the sheet, anchored to the left. */
41
18
  leftButton?: ReactNode;
42
- /** Slot above the sheet, anchored to the right. */
43
19
  rightButton?: ReactNode;
44
- /** Element rendered behind the sheet, fading in with progress. */
45
20
  screen?: ReactNode;
46
- /** Fired whenever active snap changes. */
47
21
  onChange?: (state: EngineState) => void;
48
- /** Visually hidden label for screen readers. */
49
22
  ariaLabel?: string;
50
- /** ID of an existing heading element inside the sheet (preferred over ariaLabel). */
51
23
  ariaLabelledBy?: string;
52
- /** Skip rendering on the server to avoid hydration mismatches. Default: false. */
53
24
  noSSR?: boolean;
54
25
  };
55
- /**
56
- * Imperative handle returned by `<BottomSheet ref={…}>`.
57
- *
58
- * Opt-in literal-id typing — pass a string-literal union as `TId` to get
59
- * compile-time errors on typos:
60
- *
61
- * ```ts
62
- * // Default (back-compat): TId = string, anything goes
63
- * const ref = useRef<BottomSheetHandle>(null);
64
- * ref.current?.snapTo("anything"); // ✓ compiles, fails silently at runtime
65
- *
66
- * // Opt-in: typo-safe
67
- * const ref = useRef<BottomSheetHandle<"min" | "half" | "full">>(null);
68
- * ref.current?.snapTo("haf"); // ❌ TS2345
69
- * ref.current?.snapTo("half"); // ✓
70
- * ```
71
- *
72
- * `TId` defaults to `string` so existing call sites compile unchanged.
73
- * The underlying engine stays `string`-typed; the literal narrowing is a
74
- * TS-only convenience layered on top of the runtime.
75
- */
76
26
  type BottomSheetHandle<TId extends string = string> = {
77
27
  snapTo: (id: TId) => Promise<void>;
78
28
  open: (id?: TId) => Promise<void>;
79
29
  close: () => Promise<void>;
80
30
  setAllowed: (ids: TId[], snap?: TId) => void;
31
+ setSnapPoints: (points: EngineOptions["snapPoints"], allowed?: string[]) => void;
32
+ setScrim: (opts: ScrimUpdate) => void;
33
+ setScrimOverlay: (opts: ScrimOverlayOptions) => () => void;
81
34
  state: EngineState & {
82
35
  activeId: TId;
83
36
  };
37
+ getEngine: () => BottomSheetEngine | null;
84
38
  };
85
- /**
86
- * React component built on the headless engine. For full control, use
87
- * `useBottomSheet` directly and assemble your own JSX.
88
- */
89
39
  declare const BottomSheet: react.ForwardRefExoticComponent<EngineOptionsForProps & {
90
- /** Render the dimmed overlay behind the sheet. Default: true. */
91
40
  backdrop?: boolean;
92
- /** Close when the backdrop is clicked. Default: true. */
93
41
  closeOnBackdrop?: boolean;
94
- /** Optional className appended to the root sheet element. */
95
42
  className?: string;
96
43
  style?: CSSProperties;
97
- /**
98
- * Header content (above the scrollable content; doubles as drag handle
99
- * area). Accepts either a static `ReactNode` or a function
100
- * `(state: EngineState) => ReactNode` that re-renders on every snap
101
- * transition — letting consumers show different markup per snap state
102
- * (e.g. minimized vs half vs full).
103
- */
104
44
  header?: HeaderProp;
105
- /** Children become the scrollable content area. */
106
45
  children?: ReactNode;
107
- /** Slot above the sheet, anchored to the left. */
108
46
  leftButton?: ReactNode;
109
- /** Slot above the sheet, anchored to the right. */
110
47
  rightButton?: ReactNode;
111
- /** Element rendered behind the sheet, fading in with progress. */
112
48
  screen?: ReactNode;
113
- /** Fired whenever active snap changes. */
114
49
  onChange?: (state: EngineState) => void;
115
- /** Visually hidden label for screen readers. */
116
50
  ariaLabel?: string;
117
- /** ID of an existing heading element inside the sheet (preferred over ariaLabel). */
118
51
  ariaLabelledBy?: string;
119
- /** Skip rendering on the server to avoid hydration mismatches. Default: false. */
120
52
  noSSR?: boolean;
121
53
  } & react.RefAttributes<BottomSheetHandle<string>>>;
122
54
 
123
55
  type UseBottomSheetRefs = {
124
- sheetRef: React.RefObject<HTMLElement>;
125
- handleRef: React.RefObject<HTMLElement>;
126
- contentRef: React.RefObject<HTMLElement>;
127
- backdropRef: React.RefObject<HTMLElement>;
128
- screenRef: React.RefObject<HTMLElement>;
56
+ sheetRef: React.RefObject<HTMLElement | null>;
57
+ handleRef: React.RefObject<HTMLElement | null>;
58
+ contentRef: React.RefObject<HTMLElement | null>;
59
+ backdropRef: React.RefObject<HTMLElement | null>;
60
+ screenRef: React.RefObject<HTMLElement | null>;
129
61
  };
130
- /**
131
- * Return shape of `useBottomSheet`. Optionally narrows to a literal-id union
132
- * `TId` when the consumer explicitly types the call site:
133
- *
134
- * ```ts
135
- * const sheet = useBottomSheet<"min" | "full">({ snapPoints: [...] });
136
- * sheet.snapTo("min"); // ✓
137
- * ```
138
- *
139
- * Without an explicit type argument `TId` defaults to `string`.
140
- */
141
62
  type UseBottomSheetReturn<TId extends string = string> = UseBottomSheetRefs & {
142
63
  state: EngineState & {
143
64
  activeId: TId;
@@ -146,43 +67,19 @@ type UseBottomSheetReturn<TId extends string = string> = UseBottomSheetRefs & {
146
67
  open: (id?: TId) => Promise<void>;
147
68
  close: () => Promise<void>;
148
69
  setAllowed: (ids: TId[], snap?: TId) => void;
149
- /**
150
- * @deprecated React Strict Mode double-invokes the layout effect — the
151
- * effect tears down (engineRef.current = null), the next render reads
152
- * this field as `null` for one frame, and only the second mount restores
153
- * a live engine. Consumers calling methods through this field during that
154
- * window get `null`. Use `getEngine()` instead — it lazy-reads the live
155
- * ref and is safe across Strict Mode and across resize/setSnapPoints
156
- * paths that don't fire React-tracked events. Will be removed in v2.
157
- */
158
70
  engine: BottomSheetEngine | null;
159
- /** Lazy accessor — always reads the live engine, even after external
160
- * mutations (resize, setSnapPoints) that don't fire React-tracked events.
161
- * Strict-Mode-safe: returns the current ref at call time, not a stale
162
- * snapshot from the last commit. */
163
71
  getEngine: () => BottomSheetEngine | null;
164
72
  };
165
- /**
166
- * Headless React hook. Wires the engine to refs and subscribes to its events
167
- * via `useSyncExternalStore` for tear-free state in concurrent mode.
168
- *
169
- * The snapshot is cached in a ref and only refreshed when a notify fires,
170
- * so React's identity check doesn't trigger an infinite loop (the engine's
171
- * `state` getter constructs a fresh object every call).
172
- */
173
- type HookOpts<TId extends string> = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "screenComponent" | "snapPoints" | "allowed" | "initial"> & {
73
+ type HookOpts<TId extends string> = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "scrim" | "snapPoints" | "allowed" | "initial"> & {
174
74
  snapPoints: SnapPointDef<TId>[] | ReadonlyArray<SnapPointDef<TId>>;
175
75
  allowed?: TId[] | ReadonlyArray<TId>;
176
76
  initial?: TId;
177
- /** Called after a snap commit settles. Mirrors the engine's `snap` event. */
178
77
  onSnap?: (id: TId) => void;
179
78
  };
180
79
  declare function useBottomSheet<TId extends string = string>(opts: HookOpts<TId>): UseBottomSheetReturn<TId>;
181
80
 
182
81
  type OverlayProps = Omit<OverlayOptions, "element" | "backdrop"> & {
183
- /** Controlled open state. If omitted, the overlay is uncontrolled. */
184
82
  open?: boolean;
185
- /** Render the backdrop. Default: true. */
186
83
  backdrop?: boolean;
187
84
  className?: string;
188
85
  style?: CSSProperties;
@@ -197,15 +94,8 @@ type OverlayHandle = {
197
94
  toggle: () => Promise<void>;
198
95
  state: OverlayState;
199
96
  };
200
- /**
201
- * Bottom-anchored slide-up overlay panel. Distinct from `<BottomSheet>`:
202
- * no drag, no snap points, single binary state. CSS-transition animated
203
- * (no spring) — lighter weight, predictable timing.
204
- */
205
97
  declare const Overlay: react.ForwardRefExoticComponent<Omit<OverlayOptions, "element" | "backdrop"> & {
206
- /** Controlled open state. If omitted, the overlay is uncontrolled. */
207
98
  open?: boolean;
208
- /** Render the backdrop. Default: true. */
209
99
  backdrop?: boolean;
210
100
  className?: string;
211
101
  style?: CSSProperties;
@@ -216,52 +106,31 @@ declare const Overlay: react.ForwardRefExoticComponent<Omit<OverlayOptions, "ele
216
106
  } & react.RefAttributes<OverlayHandle>>;
217
107
 
218
108
  type UseOverlayReturn = {
219
- panelRef: React.RefObject<HTMLElement>;
220
- backdropRef: React.RefObject<HTMLElement>;
109
+ panelRef: React.RefObject<HTMLElement | null>;
110
+ backdropRef: React.RefObject<HTMLElement | null>;
221
111
  state: OverlayState;
222
112
  open: () => Promise<void>;
223
113
  close: () => Promise<void>;
224
114
  toggle: () => Promise<void>;
225
- /**
226
- * Lazy accessor for the underlying engine. Returns null on SSR or before
227
- * the layout effect mounts the engine. Use this — not a snapshot — so you
228
- * always read the current instance.
229
- */
230
115
  getEngine: () => OverlayEngine | null;
231
116
  };
232
117
  declare const useOverlay: (opts: Omit<OverlayOptions, "element" | "backdrop">) => UseOverlayReturn;
233
118
 
234
- /**
235
- * JSON-serializable sheet configuration for CMS-driven / A-B / plugin /
236
- * server-driven UI. Functions can't be JSON, so handlers live in the
237
- * sibling `eventHandlers` prop keyed by `events.{onSnap,onOpen,onClose}`.
238
- *
239
- * Treat configs as immutable — derived props are memoized by config
240
- * identity, mutating in place leaves stale snap geometry behind.
241
- */
242
119
  type SheetConfig = {
243
- /** Schema version. Must be `1` for the current wrapper. */
244
120
  version: 1;
245
- /** Ordered list of snap points (smallest → largest). Required. */
246
121
  snapPoints: Array<{
247
122
  id: string;
248
123
  size: number | string;
249
124
  }>;
250
- /** Initial snap id. Falls back to first allowed (or first overall). */
251
125
  initial?: string;
252
- /** Subset of snap-point ids the sheet may settle on right now. */
253
126
  allowed?: string[];
254
- /** Direction the sheet expands from. Default: "bottom". */
255
127
  mode?: SheetMode;
256
- /** Animation strategy. Default: "spring". */
257
128
  animation?: "spring" | "tween";
258
- /** Spring config when `animation: "spring"`. */
259
129
  spring?: {
260
130
  stiffness?: number;
261
131
  damping?: number;
262
132
  mass?: number;
263
133
  };
264
- /** Behavior toggles. All optional; missing keys fall back to engine defaults. */
265
134
  behavior?: {
266
135
  focusTrap?: boolean;
267
136
  closeOnEscape?: boolean;
@@ -269,11 +138,6 @@ type SheetConfig = {
269
138
  lockBodyScroll?: boolean;
270
139
  rubberBand?: boolean;
271
140
  };
272
- /**
273
- * Map event name → handler key. The actual functions live in the
274
- * `eventHandlers` prop on the wrapper component, keyed by the same
275
- * string. Missing handler keys are tolerated (warn + no-op).
276
- */
277
141
  events?: {
278
142
  onSnap?: string;
279
143
  onOpen?: string;
@@ -288,12 +152,6 @@ type BottomSheetFromConfigProps = {
288
152
  header?: ReactNode;
289
153
  body?: ReactNode;
290
154
  };
291
- /**
292
- * Memoize derived props by content (JSON.stringify) instead of identity.
293
- * Set when fetching via SWR / TanStack Query / RSC loaders that hand back
294
- * a fresh object on every cache hit — prevents engine rebuilds on byte-
295
- * identical revalidations. Default false keeps the cheap identity path.
296
- */
297
155
  stableContent?: boolean;
298
156
  };
299
157
  declare const BottomSheetFromConfig: react.ForwardRefExoticComponent<BottomSheetFromConfigProps & react.RefAttributes<BottomSheetHandle>>;
package/dist/react.d.ts CHANGED
@@ -1,143 +1,64 @@
1
- import { b as EngineOptions, E as EngineState, B as BottomSheetEngine, S as SnapPointDef, a as SheetMode } from './BottomSheetEngine-DbO8rW_3.js';
2
- export { c as SnapPoint } from './BottomSheetEngine-DbO8rW_3.js';
1
+ import { b as EngineOptions, E as EngineState, j as ScrimUpdate, f as ScrimOverlayOptions, B as BottomSheetEngine, S as SnapPointDef, a as SheetMode } from './BottomSheetEngine-Df9MwBbm.js';
2
+ export { c as SnapPoint } from './BottomSheetEngine-Df9MwBbm.js';
3
3
  import { OverlayOptions, OverlayState, Overlay as OverlayEngine } from './overlay.js';
4
4
  export { OverlayEdge } from './overlay.js';
5
5
  import * as react from 'react';
6
6
  import { CSSProperties, ReactNode } from 'react';
7
- import './transform-Brkf-wzo.js';
7
+ import './transform-jVfAikE9.js';
8
8
 
9
- type EngineOptionsForProps = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "screenComponent">;
10
- /**
11
- * Header content for the sheet. Two forms are supported:
12
- * - **Static node**: `header={<h2>Title</h2>}` — rendered once and never
13
- * updated when the active snap changes.
14
- * - **Render function**: `header={state => <h2>{state.activeId}</h2>}` —
15
- * called on every settled snap change with the current `EngineState`,
16
- * so the header can morph per snap (e.g. minimized header vs full
17
- * header). The function fires from the same `useSyncExternalStore`
18
- * subscription that drives the rest of the component, so identity is
19
- * stable between snaps and only re-renders on transitions.
20
- */
9
+ type EngineOptionsForProps = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "scrim">;
21
10
  type HeaderProp = ReactNode | ((state: EngineState) => ReactNode);
22
11
  type BottomSheetProps = EngineOptionsForProps & {
23
- /** Render the dimmed overlay behind the sheet. Default: true. */
24
12
  backdrop?: boolean;
25
- /** Close when the backdrop is clicked. Default: true. */
26
13
  closeOnBackdrop?: boolean;
27
- /** Optional className appended to the root sheet element. */
28
14
  className?: string;
29
15
  style?: CSSProperties;
30
- /**
31
- * Header content (above the scrollable content; doubles as drag handle
32
- * area). Accepts either a static `ReactNode` or a function
33
- * `(state: EngineState) => ReactNode` that re-renders on every snap
34
- * transition — letting consumers show different markup per snap state
35
- * (e.g. minimized vs half vs full).
36
- */
37
16
  header?: HeaderProp;
38
- /** Children become the scrollable content area. */
39
17
  children?: ReactNode;
40
- /** Slot above the sheet, anchored to the left. */
41
18
  leftButton?: ReactNode;
42
- /** Slot above the sheet, anchored to the right. */
43
19
  rightButton?: ReactNode;
44
- /** Element rendered behind the sheet, fading in with progress. */
45
20
  screen?: ReactNode;
46
- /** Fired whenever active snap changes. */
47
21
  onChange?: (state: EngineState) => void;
48
- /** Visually hidden label for screen readers. */
49
22
  ariaLabel?: string;
50
- /** ID of an existing heading element inside the sheet (preferred over ariaLabel). */
51
23
  ariaLabelledBy?: string;
52
- /** Skip rendering on the server to avoid hydration mismatches. Default: false. */
53
24
  noSSR?: boolean;
54
25
  };
55
- /**
56
- * Imperative handle returned by `<BottomSheet ref={…}>`.
57
- *
58
- * Opt-in literal-id typing — pass a string-literal union as `TId` to get
59
- * compile-time errors on typos:
60
- *
61
- * ```ts
62
- * // Default (back-compat): TId = string, anything goes
63
- * const ref = useRef<BottomSheetHandle>(null);
64
- * ref.current?.snapTo("anything"); // ✓ compiles, fails silently at runtime
65
- *
66
- * // Opt-in: typo-safe
67
- * const ref = useRef<BottomSheetHandle<"min" | "half" | "full">>(null);
68
- * ref.current?.snapTo("haf"); // ❌ TS2345
69
- * ref.current?.snapTo("half"); // ✓
70
- * ```
71
- *
72
- * `TId` defaults to `string` so existing call sites compile unchanged.
73
- * The underlying engine stays `string`-typed; the literal narrowing is a
74
- * TS-only convenience layered on top of the runtime.
75
- */
76
26
  type BottomSheetHandle<TId extends string = string> = {
77
27
  snapTo: (id: TId) => Promise<void>;
78
28
  open: (id?: TId) => Promise<void>;
79
29
  close: () => Promise<void>;
80
30
  setAllowed: (ids: TId[], snap?: TId) => void;
31
+ setSnapPoints: (points: EngineOptions["snapPoints"], allowed?: string[]) => void;
32
+ setScrim: (opts: ScrimUpdate) => void;
33
+ setScrimOverlay: (opts: ScrimOverlayOptions) => () => void;
81
34
  state: EngineState & {
82
35
  activeId: TId;
83
36
  };
37
+ getEngine: () => BottomSheetEngine | null;
84
38
  };
85
- /**
86
- * React component built on the headless engine. For full control, use
87
- * `useBottomSheet` directly and assemble your own JSX.
88
- */
89
39
  declare const BottomSheet: react.ForwardRefExoticComponent<EngineOptionsForProps & {
90
- /** Render the dimmed overlay behind the sheet. Default: true. */
91
40
  backdrop?: boolean;
92
- /** Close when the backdrop is clicked. Default: true. */
93
41
  closeOnBackdrop?: boolean;
94
- /** Optional className appended to the root sheet element. */
95
42
  className?: string;
96
43
  style?: CSSProperties;
97
- /**
98
- * Header content (above the scrollable content; doubles as drag handle
99
- * area). Accepts either a static `ReactNode` or a function
100
- * `(state: EngineState) => ReactNode` that re-renders on every snap
101
- * transition — letting consumers show different markup per snap state
102
- * (e.g. minimized vs half vs full).
103
- */
104
44
  header?: HeaderProp;
105
- /** Children become the scrollable content area. */
106
45
  children?: ReactNode;
107
- /** Slot above the sheet, anchored to the left. */
108
46
  leftButton?: ReactNode;
109
- /** Slot above the sheet, anchored to the right. */
110
47
  rightButton?: ReactNode;
111
- /** Element rendered behind the sheet, fading in with progress. */
112
48
  screen?: ReactNode;
113
- /** Fired whenever active snap changes. */
114
49
  onChange?: (state: EngineState) => void;
115
- /** Visually hidden label for screen readers. */
116
50
  ariaLabel?: string;
117
- /** ID of an existing heading element inside the sheet (preferred over ariaLabel). */
118
51
  ariaLabelledBy?: string;
119
- /** Skip rendering on the server to avoid hydration mismatches. Default: false. */
120
52
  noSSR?: boolean;
121
53
  } & react.RefAttributes<BottomSheetHandle<string>>>;
122
54
 
123
55
  type UseBottomSheetRefs = {
124
- sheetRef: React.RefObject<HTMLElement>;
125
- handleRef: React.RefObject<HTMLElement>;
126
- contentRef: React.RefObject<HTMLElement>;
127
- backdropRef: React.RefObject<HTMLElement>;
128
- screenRef: React.RefObject<HTMLElement>;
56
+ sheetRef: React.RefObject<HTMLElement | null>;
57
+ handleRef: React.RefObject<HTMLElement | null>;
58
+ contentRef: React.RefObject<HTMLElement | null>;
59
+ backdropRef: React.RefObject<HTMLElement | null>;
60
+ screenRef: React.RefObject<HTMLElement | null>;
129
61
  };
130
- /**
131
- * Return shape of `useBottomSheet`. Optionally narrows to a literal-id union
132
- * `TId` when the consumer explicitly types the call site:
133
- *
134
- * ```ts
135
- * const sheet = useBottomSheet<"min" | "full">({ snapPoints: [...] });
136
- * sheet.snapTo("min"); // ✓
137
- * ```
138
- *
139
- * Without an explicit type argument `TId` defaults to `string`.
140
- */
141
62
  type UseBottomSheetReturn<TId extends string = string> = UseBottomSheetRefs & {
142
63
  state: EngineState & {
143
64
  activeId: TId;
@@ -146,43 +67,19 @@ type UseBottomSheetReturn<TId extends string = string> = UseBottomSheetRefs & {
146
67
  open: (id?: TId) => Promise<void>;
147
68
  close: () => Promise<void>;
148
69
  setAllowed: (ids: TId[], snap?: TId) => void;
149
- /**
150
- * @deprecated React Strict Mode double-invokes the layout effect — the
151
- * effect tears down (engineRef.current = null), the next render reads
152
- * this field as `null` for one frame, and only the second mount restores
153
- * a live engine. Consumers calling methods through this field during that
154
- * window get `null`. Use `getEngine()` instead — it lazy-reads the live
155
- * ref and is safe across Strict Mode and across resize/setSnapPoints
156
- * paths that don't fire React-tracked events. Will be removed in v2.
157
- */
158
70
  engine: BottomSheetEngine | null;
159
- /** Lazy accessor — always reads the live engine, even after external
160
- * mutations (resize, setSnapPoints) that don't fire React-tracked events.
161
- * Strict-Mode-safe: returns the current ref at call time, not a stale
162
- * snapshot from the last commit. */
163
71
  getEngine: () => BottomSheetEngine | null;
164
72
  };
165
- /**
166
- * Headless React hook. Wires the engine to refs and subscribes to its events
167
- * via `useSyncExternalStore` for tear-free state in concurrent mode.
168
- *
169
- * The snapshot is cached in a ref and only refreshed when a notify fires,
170
- * so React's identity check doesn't trigger an infinite loop (the engine's
171
- * `state` getter constructs a fresh object every call).
172
- */
173
- type HookOpts<TId extends string> = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "screenComponent" | "snapPoints" | "allowed" | "initial"> & {
73
+ type HookOpts<TId extends string> = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "scrim" | "snapPoints" | "allowed" | "initial"> & {
174
74
  snapPoints: SnapPointDef<TId>[] | ReadonlyArray<SnapPointDef<TId>>;
175
75
  allowed?: TId[] | ReadonlyArray<TId>;
176
76
  initial?: TId;
177
- /** Called after a snap commit settles. Mirrors the engine's `snap` event. */
178
77
  onSnap?: (id: TId) => void;
179
78
  };
180
79
  declare function useBottomSheet<TId extends string = string>(opts: HookOpts<TId>): UseBottomSheetReturn<TId>;
181
80
 
182
81
  type OverlayProps = Omit<OverlayOptions, "element" | "backdrop"> & {
183
- /** Controlled open state. If omitted, the overlay is uncontrolled. */
184
82
  open?: boolean;
185
- /** Render the backdrop. Default: true. */
186
83
  backdrop?: boolean;
187
84
  className?: string;
188
85
  style?: CSSProperties;
@@ -197,15 +94,8 @@ type OverlayHandle = {
197
94
  toggle: () => Promise<void>;
198
95
  state: OverlayState;
199
96
  };
200
- /**
201
- * Bottom-anchored slide-up overlay panel. Distinct from `<BottomSheet>`:
202
- * no drag, no snap points, single binary state. CSS-transition animated
203
- * (no spring) — lighter weight, predictable timing.
204
- */
205
97
  declare const Overlay: react.ForwardRefExoticComponent<Omit<OverlayOptions, "element" | "backdrop"> & {
206
- /** Controlled open state. If omitted, the overlay is uncontrolled. */
207
98
  open?: boolean;
208
- /** Render the backdrop. Default: true. */
209
99
  backdrop?: boolean;
210
100
  className?: string;
211
101
  style?: CSSProperties;
@@ -216,52 +106,31 @@ declare const Overlay: react.ForwardRefExoticComponent<Omit<OverlayOptions, "ele
216
106
  } & react.RefAttributes<OverlayHandle>>;
217
107
 
218
108
  type UseOverlayReturn = {
219
- panelRef: React.RefObject<HTMLElement>;
220
- backdropRef: React.RefObject<HTMLElement>;
109
+ panelRef: React.RefObject<HTMLElement | null>;
110
+ backdropRef: React.RefObject<HTMLElement | null>;
221
111
  state: OverlayState;
222
112
  open: () => Promise<void>;
223
113
  close: () => Promise<void>;
224
114
  toggle: () => Promise<void>;
225
- /**
226
- * Lazy accessor for the underlying engine. Returns null on SSR or before
227
- * the layout effect mounts the engine. Use this — not a snapshot — so you
228
- * always read the current instance.
229
- */
230
115
  getEngine: () => OverlayEngine | null;
231
116
  };
232
117
  declare const useOverlay: (opts: Omit<OverlayOptions, "element" | "backdrop">) => UseOverlayReturn;
233
118
 
234
- /**
235
- * JSON-serializable sheet configuration for CMS-driven / A-B / plugin /
236
- * server-driven UI. Functions can't be JSON, so handlers live in the
237
- * sibling `eventHandlers` prop keyed by `events.{onSnap,onOpen,onClose}`.
238
- *
239
- * Treat configs as immutable — derived props are memoized by config
240
- * identity, mutating in place leaves stale snap geometry behind.
241
- */
242
119
  type SheetConfig = {
243
- /** Schema version. Must be `1` for the current wrapper. */
244
120
  version: 1;
245
- /** Ordered list of snap points (smallest → largest). Required. */
246
121
  snapPoints: Array<{
247
122
  id: string;
248
123
  size: number | string;
249
124
  }>;
250
- /** Initial snap id. Falls back to first allowed (or first overall). */
251
125
  initial?: string;
252
- /** Subset of snap-point ids the sheet may settle on right now. */
253
126
  allowed?: string[];
254
- /** Direction the sheet expands from. Default: "bottom". */
255
127
  mode?: SheetMode;
256
- /** Animation strategy. Default: "spring". */
257
128
  animation?: "spring" | "tween";
258
- /** Spring config when `animation: "spring"`. */
259
129
  spring?: {
260
130
  stiffness?: number;
261
131
  damping?: number;
262
132
  mass?: number;
263
133
  };
264
- /** Behavior toggles. All optional; missing keys fall back to engine defaults. */
265
134
  behavior?: {
266
135
  focusTrap?: boolean;
267
136
  closeOnEscape?: boolean;
@@ -269,11 +138,6 @@ type SheetConfig = {
269
138
  lockBodyScroll?: boolean;
270
139
  rubberBand?: boolean;
271
140
  };
272
- /**
273
- * Map event name → handler key. The actual functions live in the
274
- * `eventHandlers` prop on the wrapper component, keyed by the same
275
- * string. Missing handler keys are tolerated (warn + no-op).
276
- */
277
141
  events?: {
278
142
  onSnap?: string;
279
143
  onOpen?: string;
@@ -288,12 +152,6 @@ type BottomSheetFromConfigProps = {
288
152
  header?: ReactNode;
289
153
  body?: ReactNode;
290
154
  };
291
- /**
292
- * Memoize derived props by content (JSON.stringify) instead of identity.
293
- * Set when fetching via SWR / TanStack Query / RSC loaders that hand back
294
- * a fresh object on every cache hit — prevents engine rebuilds on byte-
295
- * identical revalidations. Default false keeps the cheap identity path.
296
- */
297
155
  stableContent?: boolean;
298
156
  };
299
157
  declare const BottomSheetFromConfig: react.ForwardRefExoticComponent<BottomSheetFromConfigProps & react.RefAttributes<BottomSheetHandle>>;