@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.
- package/README.md +6 -0
- package/dist/BottomSheetEngine-CIT9Htti.d.cts +219 -0
- package/dist/BottomSheetEngine-Df9MwBbm.d.ts +219 -0
- package/dist/element.cjs +95 -440
- package/dist/element.d.cts +3 -56
- package/dist/element.d.ts +3 -56
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +95 -440
- package/dist/index.cjs +84 -494
- package/dist/index.d.cts +3 -84
- package/dist/index.d.ts +3 -84
- package/dist/index.js +84 -494
- package/dist/integrations/formik.d.cts +2 -8
- package/dist/integrations/formik.d.ts +2 -8
- package/dist/integrations/react-hook-form.d.cts +2 -11
- package/dist/integrations/react-hook-form.d.ts +2 -11
- package/dist/overlay.cjs +0 -87
- package/dist/overlay.d.cts +1 -137
- package/dist/overlay.d.ts +1 -137
- package/dist/overlay.js +0 -87
- package/dist/preact.d.cts +2 -2
- package/dist/preact.d.ts +2 -2
- package/dist/preact.js +0 -1
- package/dist/qwik.cjs +87 -439
- package/dist/qwik.d.cts +3 -24
- package/dist/qwik.d.ts +3 -24
- package/dist/qwik.js +87 -439
- package/dist/react.cjs +91 -496
- package/dist/react.d.cts +16 -158
- package/dist/react.d.ts +16 -158
- package/dist/react.js +91 -496
- package/dist/solid.cjs +87 -439
- package/dist/solid.d.cts +4 -31
- package/dist/solid.d.ts +4 -31
- package/dist/solid.js +87 -439
- package/dist/styles.css +27 -102
- package/dist/svelte.cjs +139 -462
- package/dist/svelte.d.ts +9 -2
- package/dist/svelte.js +139 -462
- package/dist/themes/ios.css +0 -3
- package/dist/themes/material.css +0 -3
- package/dist/themes/vercel.css +0 -3
- package/dist/{transform-Brkf-wzo.d.cts → transform-jVfAikE9.d.cts} +0 -1
- package/dist/{transform-Brkf-wzo.d.ts → transform-jVfAikE9.d.ts} +0 -1
- package/dist/vue.cjs +104 -446
- package/dist/vue.d.ts +7 -1
- package/dist/vue.js +105 -447
- package/package.json +3 -3
- package/dist/BottomSheetEngine-CvSVbo6c.d.cts +0 -704
- 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-
|
|
2
|
-
export { c as SnapPoint } from './BottomSheetEngine-
|
|
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-
|
|
7
|
+
import './transform-jVfAikE9.cjs';
|
|
8
8
|
|
|
9
|
-
type EngineOptionsForProps = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "
|
|
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-
|
|
2
|
-
export { c as SnapPoint } from './BottomSheetEngine-
|
|
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-
|
|
7
|
+
import './transform-jVfAikE9.js';
|
|
8
8
|
|
|
9
|
-
type EngineOptionsForProps = Omit<EngineOptions, "element" | "handle" | "scrollContainer" | "backdrop" | "
|
|
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>>;
|