@surdeddd/bottom-sheet 0.1.0 → 0.3.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 (57) hide show
  1. package/README.md +57 -21
  2. package/dist/BottomSheetEngine-CAymrH-P.d.cts +285 -0
  3. package/dist/BottomSheetEngine-DcqcuudN.d.ts +285 -0
  4. package/dist/element.cjs +775 -537
  5. package/dist/element.d.cts +9 -57
  6. package/dist/element.d.ts +9 -57
  7. package/dist/element.iife.global.js +2 -2
  8. package/dist/element.js +775 -537
  9. package/dist/index.cjs +760 -600
  10. package/dist/index.d.cts +18 -85
  11. package/dist/index.d.ts +18 -85
  12. package/dist/index.js +758 -601
  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 +168 -122
  18. package/dist/overlay.d.cts +14 -137
  19. package/dist/overlay.d.ts +14 -137
  20. package/dist/overlay.js +168 -122
  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 +667 -519
  25. package/dist/qwik.d.cts +3 -24
  26. package/dist/qwik.d.ts +3 -24
  27. package/dist/qwik.js +668 -520
  28. package/dist/react.cjs +873 -648
  29. package/dist/react.d.cts +34 -159
  30. package/dist/react.d.ts +34 -159
  31. package/dist/react.js +873 -648
  32. package/dist/solid.cjs +703 -560
  33. package/dist/solid.d.cts +264 -32
  34. package/dist/solid.d.ts +264 -32
  35. package/dist/solid.js +704 -561
  36. package/dist/solid.source.jsx +3215 -0
  37. package/dist/styles.css +37 -112
  38. package/dist/svelte-core.cjs +3149 -0
  39. package/dist/svelte-core.js +3147 -0
  40. package/dist/svelte-src/BottomSheet.svelte +210 -0
  41. package/dist/svelte-src/index.js +2 -0
  42. package/dist/svelte.cjs +718 -547
  43. package/dist/svelte.d.cts +100 -0
  44. package/dist/svelte.d.ts +15 -4
  45. package/dist/svelte.js +719 -548
  46. package/dist/themes/ios.css +0 -3
  47. package/dist/themes/material.css +0 -3
  48. package/dist/themes/vercel.css +0 -3
  49. package/dist/{transform-Brkf-wzo.d.cts → transform-jVfAikE9.d.cts} +0 -1
  50. package/dist/{transform-Brkf-wzo.d.ts → transform-jVfAikE9.d.ts} +0 -1
  51. package/dist/vue.cjs +677 -526
  52. package/dist/vue.d.cts +78 -0
  53. package/dist/vue.d.ts +12 -2
  54. package/dist/vue.js +678 -527
  55. package/package.json +105 -45
  56. package/dist/BottomSheetEngine-CvSVbo6c.d.cts +0 -704
  57. package/dist/BottomSheetEngine-DbO8rW_3.d.ts +0 -704
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  > Universal, headless bottom-sheet engine. **One core, eight adapters, GPU-accelerated, fully tested.**
4
4
 
5
- ![bundle](https://img.shields.io/badge/core-15.8%20KB%20gzip-1a1614?style=flat-square)
6
- ![tests](https://img.shields.io/badge/tests-327%20unit-2ea44f?style=flat-square)
5
+ ![bundle](https://img.shields.io/badge/core-16.8%20KB%20gzip-1a1614?style=flat-square)
6
+ ![tests](https://img.shields.io/badge/tests-392%20unit-2ea44f?style=flat-square)
7
7
  ![ts](https://img.shields.io/badge/TypeScript-strict-3178c6?style=flat-square&logo=typescript&logoColor=white)
8
8
  ![license](https://img.shields.io/badge/license-MIT-dc3522?style=flat-square)
9
9
 
@@ -11,6 +11,12 @@ A framework-agnostic bottom-sheet primitive. Spring physics, Pointer Events,
11
11
  GPU-only motion, full keyboard a11y, hardware-back interception, multi-sheet
12
12
  stacking — and the exact same engine behind every adapter.
13
13
 
14
+ ## 🚀 [Live demo → bottom-sheet-demo.vercel.app](https://bottom-sheet-demo.vercel.app)
15
+
16
+ <p align="center">
17
+ <img src="https://raw.githubusercontent.com/Surdeddd/BottomSheet/main/docs/gifs/01-drag-to-close.gif" alt="drag to close — spring physics" width="380" />
18
+ </p>
19
+
14
20
  ```
15
21
 
16
22
  ┌───────────────────────────────────────┐
@@ -41,7 +47,7 @@ stacking — and the exact same engine behind every adapter.
41
47
  | WCAG 2.1 AA keyboard slider | partial | — | **✓** |
42
48
  | Multi-sheet stacking | — | — | **✓** |
43
49
  | Sheet-manager registry (typed) | — | — | **✓** |
44
- | Tests (unit + e2e) | partial | partial | **253 + 32** |
50
+ | Tests (unit + e2e) | partial | partial | **392 + 164** |
45
51
 
46
52
  ## Install
47
53
 
@@ -164,7 +170,7 @@ Drop-in usage from a static HTML page. The IIFE bundle registers
164
170
  rel="stylesheet"
165
171
  href="https://unpkg.com/@surdeddd/bottom-sheet/dist/styles.css"
166
172
  />
167
- <script src="https://unpkg.com/@surdeddd/bottom-sheet/dist/element.iife.js"></script>
173
+ <script src="https://unpkg.com/@surdeddd/bottom-sheet/dist/element.iife.global.js"></script>
168
174
  <bottom-sheet
169
175
  snap-points='[{"id":"min","size":96},{"id":"full","size":"85%"}]'
170
176
  initial="min"
@@ -211,23 +217,53 @@ type SnapPoint =
211
217
 
212
218
  ### Engine options
213
219
 
214
- | Option | Default | What it does |
215
- | ---------------- | ------------- | -------------------------------------------------- |
216
- | `snapPoints` | required | Ordered list of `{ id, size }` |
217
- | `allowed` | all ids | Subset the sheet may settle on right now |
218
- | `initial` | first allowed | Snap id to start at |
219
- | `mode` | `"bottom"` | `bottom \| top \| left \| right` |
220
- | `animation` | `"spring"` | `spring \| tween` |
221
- | `spring` | snappy | `{ stiffness, damping, mass }` |
222
- | `flickVelocity` | `0.65 px/ms` | Mobile flick threshold |
223
- | `dragThreshold` | `18 px` | Below this, drag snaps back |
224
- | `rubberBand` | `true` | iOS-style soft over-drag |
225
- | `backdropRange` | `[0, 1]` | Progress range over which backdrop fades |
226
- | `focusTrap` | `false` | Trap Tab focus inside the sheet when open |
227
- | `closeOnEscape` | `true` | Listen for Escape and close |
228
- | `closeOnBack` | `false` | Intercept Android back button (history.popstate) |
229
- | `lockBodyScroll` | `true` | iOS-safe body lock (`position: fixed`) |
230
- | `inertSiblings` | `false` | Mark page siblings `inert` while open (full modal) |
220
+ | Option | Default | What it does |
221
+ | ---------------- | ------------- | ---------------------------------------------------------------------- |
222
+ | `snapPoints` | required | Ordered list of `{ id, size }` |
223
+ | `allowed` | all ids | Subset the sheet may settle on right now |
224
+ | `initial` | first allowed | Snap id to start at |
225
+ | `mode` | `"bottom"` | `bottom`, `top`, `left`, `right` |
226
+ | `animation` | `"spring"` | `spring`, `tween`, `ios-spring`, `material-bounce`, `linear`, `snappy` |
227
+ | `spring` | snappy | `{ stiffness, damping, mass }` |
228
+ | `flickVelocity` | `0.65 px/ms` | Mobile flick threshold |
229
+ | `dragThreshold` | `18 px` | Below this, drag snaps back |
230
+ | `rubberBand` | `true` | iOS-style soft over-drag |
231
+ | `backdropRange` | `[0, 1]` | Progress range over which backdrop fades |
232
+ | `focusTrap` | `false` | Trap Tab focus inside the sheet when open |
233
+ | `closeOnEscape` | `true` | Listen for Escape and close |
234
+ | `closeOnBack` | `false` | Intercept Android back button (history.popstate) |
235
+ | `lockBodyScroll` | `true` | iOS-safe body lock (`position: fixed`) |
236
+ | `stackEffect` | `false` | iOS card-stack: back sheets scale down per depth |
237
+ | `inertSiblings` | `false` | Mark page siblings `inert` while open (full modal) |
238
+
239
+ ### Anchored elements, docked bars & scrim stages
240
+
241
+ Pin UI around the sheet — it rides the motion on the compositor (zero JS per
242
+ frame) and shows/hides per state with configurable animations:
243
+
244
+ ```ts
245
+ engine.addAnchor({
246
+ element: closeBtn,
247
+ position: 'sheet-top-right', // rides the sheet edge; 9 screen positions too
248
+ showOn: ['half', 'full'], // snap ids or a predicate
249
+ animation: 'pop', // fade | scale | slide | pop | custom keyframes
250
+ });
251
+
252
+ engine.addAnchor({
253
+ element: tabBar,
254
+ position: 'dock-bottom', // full-width bar; the sheet slides under it
255
+ });
256
+
257
+ engine.setScrimStages({
258
+ stages: [
259
+ { for: 'peek', element: teaser },
260
+ { forRange: [0.5, 1], element: expanded },
261
+ ],
262
+ animation: 'fade',
263
+ });
264
+ ```
265
+
266
+ [Full anchors & stages docs →](docs/anchors.md)
231
267
 
232
268
  ### Events
233
269
 
@@ -0,0 +1,285 @@
1
+ import { T as TransformAxis } from './transform-jVfAikE9.cjs';
2
+
3
+ type SnapPoint = number | `${number}%` | "fit" | "full" | (string & {});
4
+ type SnapPointDef<Id extends string = string> = {
5
+ id: Id;
6
+ size: SnapPoint;
7
+ };
8
+ type SnapId<T extends readonly SnapPointDef<string>[] | {
9
+ snapPoints: readonly SnapPointDef<string>[];
10
+ }> = T extends {
11
+ snapPoints: readonly SnapPointDef<infer U>[];
12
+ } ? U : T extends readonly SnapPointDef<infer U>[] ? U : never;
13
+ type SheetMode = TransformAxis;
14
+ type ScrimPreset = "subtle" | "standard" | "monitoring" | "cinematic";
15
+ type ScrimPresetConfig = {
16
+ color: string;
17
+ blur: string | undefined;
18
+ range: [number, number];
19
+ interactive: boolean;
20
+ };
21
+ declare const SCRIM_PRESETS: Readonly<Record<ScrimPreset, ScrimPresetConfig>>;
22
+ type ScrimUpdate = {
23
+ color?: string | null;
24
+ blur?: string | null;
25
+ interactive?: boolean;
26
+ range?: [number, number];
27
+ preset?: ScrimPreset;
28
+ mode?: "full" | "above-sheet" | "off";
29
+ tapToClose?: boolean;
30
+ enabled?: boolean;
31
+ };
32
+ type ScrimOverlayPosition = "top-left" | "top-center" | "top-right" | "center-left" | "center" | "center-right" | "bottom-left" | "bottom-center" | "bottom-right" | "sheet-top-left" | "sheet-top-center" | "sheet-top-right";
33
+ type ScrimOverlayOptions = {
34
+ children: HTMLElement | DocumentFragment;
35
+ position?: ScrimOverlayPosition;
36
+ interactive?: boolean;
37
+ inset?: string;
38
+ };
39
+ type SheetEventMap = {
40
+ "before-snap": {
41
+ id: string;
42
+ size: number;
43
+ cancel: () => void;
44
+ previousId: string;
45
+ };
46
+ snap: {
47
+ id: string;
48
+ size: number;
49
+ };
50
+ progress: {
51
+ value: number;
52
+ size: number;
53
+ };
54
+ dragstart: {
55
+ size: number;
56
+ };
57
+ drag: {
58
+ size: number;
59
+ delta: number;
60
+ };
61
+ dragend: {
62
+ size: number;
63
+ velocity: number;
64
+ };
65
+ close: void;
66
+ open: {
67
+ id: string;
68
+ };
69
+ };
70
+ type EngineOptions = {
71
+ element: HTMLElement;
72
+ handle?: HTMLElement;
73
+ scrollContainer?: HTMLElement;
74
+ backdrop?: HTMLElement;
75
+ scrim?: HTMLElement;
76
+ screenComponent?: HTMLElement;
77
+ mode?: SheetMode;
78
+ snapPoints: SnapPointDef[];
79
+ allowed?: string[];
80
+ initial?: string;
81
+ duration?: number;
82
+ easing?: (t: number) => number;
83
+ respectReducedMotion?: boolean;
84
+ flickVelocity?: number;
85
+ dragThreshold?: number;
86
+ rubberBand?: boolean;
87
+ backdropRange?: [number, number];
88
+ screenRange?: [number, number];
89
+ scrimMode?: "full" | "above-sheet" | "off";
90
+ scrimColor?: string;
91
+ scrimBlur?: string;
92
+ scrimInteractive?: boolean;
93
+ scrimTapToClose?: boolean;
94
+ scrimPreset?: ScrimPreset;
95
+ animation?: "spring" | "tween" | "ios-spring" | "material-bounce" | "linear" | "snappy";
96
+ spring?: {
97
+ stiffness?: number;
98
+ damping?: number;
99
+ mass?: number;
100
+ };
101
+ focusTrap?: boolean;
102
+ initialFocus?: string | HTMLElement;
103
+ closeOnEscape?: boolean;
104
+ lockBodyScroll?: boolean;
105
+ closeOnBack?: boolean;
106
+ routedTo?: string;
107
+ inertSiblings?: boolean;
108
+ persistKey?: string;
109
+ autoCollapseAfter?: number;
110
+ linkedSheets?: BottomSheetEngineLike[];
111
+ viewTransitions?: boolean;
112
+ stackEffect?: boolean;
113
+ };
114
+
115
+ type BottomSheetEngineLike = BottomSheetEngine;
116
+ type TeardownScope = {
117
+ add: (fn: (() => void) | null | undefined) => void;
118
+ };
119
+ type Plugin = {
120
+ name: string;
121
+ install: (engine: BottomSheetEngine, scope: TeardownScope) => void | (() => void);
122
+ };
123
+ type EngineState = {
124
+ size: number;
125
+ activeId: string;
126
+ isDragging: boolean;
127
+ isAnimating: boolean;
128
+ progress: number;
129
+ };
130
+
131
+ type AnchorAnimationPreset = "fade" | "scale" | "slide" | "pop" | "none";
132
+ type AnchorAnimationSpec = AnchorAnimationPreset | {
133
+ preset?: AnchorAnimationPreset;
134
+ enter?: Keyframe[];
135
+ exit?: Keyframe[];
136
+ duration?: number;
137
+ easing?: string;
138
+ respectReducedMotion?: boolean;
139
+ };
140
+ type AnchorTransitionHandle = {
141
+ finished: Promise<void>;
142
+ cancel: () => void;
143
+ };
144
+ declare function runAnchorTransition(el: HTMLElement, spec: AnchorAnimationSpec | undefined, phase: "enter" | "exit"): AnchorTransitionHandle;
145
+
146
+ type AnchorState = {
147
+ activeId: string;
148
+ size: number;
149
+ progress: number;
150
+ };
151
+ type AnchorPosition = ScrimOverlayPosition | "dock-bottom" | "dock-top";
152
+ type AnchorOptions = {
153
+ element: HTMLElement;
154
+ position?: AnchorPosition;
155
+ inset?: string;
156
+ showOn?: string[] | ((state: AnchorState) => boolean);
157
+ fadeRange?: [number, number];
158
+ interactive?: boolean;
159
+ animation?: AnchorAnimationSpec;
160
+ };
161
+ type AnchorHandle = {
162
+ wrapper: HTMLElement;
163
+ detach: () => void;
164
+ syncZ: (z: number) => void;
165
+ };
166
+
167
+ type ScrimStageDef = {
168
+ id?: string;
169
+ for?: string | string[];
170
+ forRange?: [number, number];
171
+ element: HTMLElement;
172
+ position?: ScrimOverlayPosition;
173
+ inset?: string;
174
+ interactive?: boolean;
175
+ animation?: AnchorAnimationSpec;
176
+ };
177
+ type ScrimStagesOptions = {
178
+ stages: ScrimStageDef[];
179
+ position?: ScrimOverlayPosition;
180
+ inset?: string;
181
+ interactive?: boolean;
182
+ animation?: AnchorAnimationSpec;
183
+ };
184
+
185
+ type Listener<K extends keyof SheetEventMap> = (payload: SheetEventMap[K]) => void;
186
+ declare class BottomSheetEngine {
187
+ private id;
188
+ private element;
189
+ private handle;
190
+ private scrollContainer?;
191
+ private backdrop?;
192
+ private screenComponent?;
193
+ private scrimParent;
194
+ private mode;
195
+ private flickVelocity;
196
+ private dragThreshold;
197
+ private rubberBandEnabled;
198
+ private scrim;
199
+ private aria;
200
+ private animation;
201
+ private lifecycle;
202
+ private closeOnBack;
203
+ private routedTo;
204
+ private snapPointsRaw;
205
+ private snaps;
206
+ private activeId;
207
+ private size;
208
+ private gesture;
209
+ private rootEl;
210
+ private destroyed;
211
+ private currentViewTransition;
212
+ private currentAbort;
213
+ private sizeWriteSentinel;
214
+ private progressWriteSentinel;
215
+ private isTopSheet;
216
+ private progressPayload;
217
+ private dragContextBuf;
218
+ private bus;
219
+ private persistKey;
220
+ private linkedSheets;
221
+ private scrollCache;
222
+ private teardowns;
223
+ private anchors;
224
+ private anchorHost;
225
+ private stackZ;
226
+ private detachScrimStages;
227
+ private stackEffectEnabled;
228
+ private stackEffectPrimed;
229
+ private transformTemplate;
230
+ constructor(opts: EngineOptions);
231
+ get state(): EngineState;
232
+ on<K extends keyof SheetEventMap>(event: K, fn: Listener<K>): () => void;
233
+ use(plugin: Plugin): this;
234
+ setLinkedSheets(sheets: BottomSheetEngine[]): void;
235
+ getAllowedIds(): string[];
236
+ snapTo(id: string, velocityOrOpts?: number | {
237
+ velocity?: number;
238
+ signal?: AbortSignal;
239
+ }, _skipBeforeSnap?: boolean): Promise<void>;
240
+ dragTo(targetSize: number, velocityOrOpts?: number | {
241
+ velocity?: number;
242
+ signal?: AbortSignal;
243
+ }): Promise<void>;
244
+ open(id?: string): Promise<void>;
245
+ close(): Promise<void>;
246
+ setAllowed(ids: string[], snap?: string): void;
247
+ setBackdropRange(range: [number, number]): void;
248
+ setScreenRange(range: [number, number]): void;
249
+ setScrimColor(color: string | undefined | null): void;
250
+ setScrimBlur(blur: string | undefined | null): void;
251
+ setScrimInteractive(interactive: boolean): void;
252
+ setScrim(opts: ScrimUpdate): void;
253
+ setScrimMode(mode: "full" | "above-sheet" | "off"): void;
254
+ setScrimTapToClose(enabled: boolean): void;
255
+ setScrimEnabled(enabled: boolean): void;
256
+ setScrimOverlay(opts: ScrimOverlayOptions): () => void;
257
+ addAnchor(opts: AnchorOptions): () => void;
258
+ setScrimStages(opts: ScrimStagesOptions | null): () => void;
259
+ getScrimState(): {
260
+ mode: "full" | "above-sheet" | "off";
261
+ enabled: boolean;
262
+ };
263
+ setSnapPoints(points: EngineOptions["snapPoints"], allowed?: string[]): void;
264
+ destroy(): void;
265
+ private emit;
266
+ private newCycle;
267
+ private emitBeforeSnap;
268
+ private recomputeSnaps;
269
+ private getAllowedRange;
270
+ private allowedIdsBySize;
271
+ private updateAriaSlider;
272
+ private registerInStack;
273
+ private applyStackDepth;
274
+ private attach;
275
+ private attachFeatures;
276
+ private settleAfterDrag;
277
+ private haptic;
278
+ private applySize;
279
+ private computeProgress;
280
+ private handleOpen;
281
+ private resyncAfterResize;
282
+ private handleClose;
283
+ }
284
+
285
+ export { type AnchorOptions as A, BottomSheetEngine as B, type EngineState as E, type Plugin as P, type ScrimStagesOptions as S, type TeardownScope as T, type SnapPointDef as a, type SheetMode as b, type EngineOptions as c, type SnapPoint as d, type SheetEventMap as e, type ScrimOverlayPosition as f, type AnchorAnimationPreset as g, type AnchorAnimationSpec as h, type AnchorHandle as i, type AnchorPosition as j, type AnchorState as k, SCRIM_PRESETS as l, type ScrimOverlayOptions as m, type ScrimPreset as n, type ScrimPresetConfig as o, type ScrimStageDef as p, type ScrimUpdate as q, type SnapId as r, runAnchorTransition as s };
@@ -0,0 +1,285 @@
1
+ import { T as TransformAxis } from './transform-jVfAikE9.js';
2
+
3
+ type SnapPoint = number | `${number}%` | "fit" | "full" | (string & {});
4
+ type SnapPointDef<Id extends string = string> = {
5
+ id: Id;
6
+ size: SnapPoint;
7
+ };
8
+ type SnapId<T extends readonly SnapPointDef<string>[] | {
9
+ snapPoints: readonly SnapPointDef<string>[];
10
+ }> = T extends {
11
+ snapPoints: readonly SnapPointDef<infer U>[];
12
+ } ? U : T extends readonly SnapPointDef<infer U>[] ? U : never;
13
+ type SheetMode = TransformAxis;
14
+ type ScrimPreset = "subtle" | "standard" | "monitoring" | "cinematic";
15
+ type ScrimPresetConfig = {
16
+ color: string;
17
+ blur: string | undefined;
18
+ range: [number, number];
19
+ interactive: boolean;
20
+ };
21
+ declare const SCRIM_PRESETS: Readonly<Record<ScrimPreset, ScrimPresetConfig>>;
22
+ type ScrimUpdate = {
23
+ color?: string | null;
24
+ blur?: string | null;
25
+ interactive?: boolean;
26
+ range?: [number, number];
27
+ preset?: ScrimPreset;
28
+ mode?: "full" | "above-sheet" | "off";
29
+ tapToClose?: boolean;
30
+ enabled?: boolean;
31
+ };
32
+ type ScrimOverlayPosition = "top-left" | "top-center" | "top-right" | "center-left" | "center" | "center-right" | "bottom-left" | "bottom-center" | "bottom-right" | "sheet-top-left" | "sheet-top-center" | "sheet-top-right";
33
+ type ScrimOverlayOptions = {
34
+ children: HTMLElement | DocumentFragment;
35
+ position?: ScrimOverlayPosition;
36
+ interactive?: boolean;
37
+ inset?: string;
38
+ };
39
+ type SheetEventMap = {
40
+ "before-snap": {
41
+ id: string;
42
+ size: number;
43
+ cancel: () => void;
44
+ previousId: string;
45
+ };
46
+ snap: {
47
+ id: string;
48
+ size: number;
49
+ };
50
+ progress: {
51
+ value: number;
52
+ size: number;
53
+ };
54
+ dragstart: {
55
+ size: number;
56
+ };
57
+ drag: {
58
+ size: number;
59
+ delta: number;
60
+ };
61
+ dragend: {
62
+ size: number;
63
+ velocity: number;
64
+ };
65
+ close: void;
66
+ open: {
67
+ id: string;
68
+ };
69
+ };
70
+ type EngineOptions = {
71
+ element: HTMLElement;
72
+ handle?: HTMLElement;
73
+ scrollContainer?: HTMLElement;
74
+ backdrop?: HTMLElement;
75
+ scrim?: HTMLElement;
76
+ screenComponent?: HTMLElement;
77
+ mode?: SheetMode;
78
+ snapPoints: SnapPointDef[];
79
+ allowed?: string[];
80
+ initial?: string;
81
+ duration?: number;
82
+ easing?: (t: number) => number;
83
+ respectReducedMotion?: boolean;
84
+ flickVelocity?: number;
85
+ dragThreshold?: number;
86
+ rubberBand?: boolean;
87
+ backdropRange?: [number, number];
88
+ screenRange?: [number, number];
89
+ scrimMode?: "full" | "above-sheet" | "off";
90
+ scrimColor?: string;
91
+ scrimBlur?: string;
92
+ scrimInteractive?: boolean;
93
+ scrimTapToClose?: boolean;
94
+ scrimPreset?: ScrimPreset;
95
+ animation?: "spring" | "tween" | "ios-spring" | "material-bounce" | "linear" | "snappy";
96
+ spring?: {
97
+ stiffness?: number;
98
+ damping?: number;
99
+ mass?: number;
100
+ };
101
+ focusTrap?: boolean;
102
+ initialFocus?: string | HTMLElement;
103
+ closeOnEscape?: boolean;
104
+ lockBodyScroll?: boolean;
105
+ closeOnBack?: boolean;
106
+ routedTo?: string;
107
+ inertSiblings?: boolean;
108
+ persistKey?: string;
109
+ autoCollapseAfter?: number;
110
+ linkedSheets?: BottomSheetEngineLike[];
111
+ viewTransitions?: boolean;
112
+ stackEffect?: boolean;
113
+ };
114
+
115
+ type BottomSheetEngineLike = BottomSheetEngine;
116
+ type TeardownScope = {
117
+ add: (fn: (() => void) | null | undefined) => void;
118
+ };
119
+ type Plugin = {
120
+ name: string;
121
+ install: (engine: BottomSheetEngine, scope: TeardownScope) => void | (() => void);
122
+ };
123
+ type EngineState = {
124
+ size: number;
125
+ activeId: string;
126
+ isDragging: boolean;
127
+ isAnimating: boolean;
128
+ progress: number;
129
+ };
130
+
131
+ type AnchorAnimationPreset = "fade" | "scale" | "slide" | "pop" | "none";
132
+ type AnchorAnimationSpec = AnchorAnimationPreset | {
133
+ preset?: AnchorAnimationPreset;
134
+ enter?: Keyframe[];
135
+ exit?: Keyframe[];
136
+ duration?: number;
137
+ easing?: string;
138
+ respectReducedMotion?: boolean;
139
+ };
140
+ type AnchorTransitionHandle = {
141
+ finished: Promise<void>;
142
+ cancel: () => void;
143
+ };
144
+ declare function runAnchorTransition(el: HTMLElement, spec: AnchorAnimationSpec | undefined, phase: "enter" | "exit"): AnchorTransitionHandle;
145
+
146
+ type AnchorState = {
147
+ activeId: string;
148
+ size: number;
149
+ progress: number;
150
+ };
151
+ type AnchorPosition = ScrimOverlayPosition | "dock-bottom" | "dock-top";
152
+ type AnchorOptions = {
153
+ element: HTMLElement;
154
+ position?: AnchorPosition;
155
+ inset?: string;
156
+ showOn?: string[] | ((state: AnchorState) => boolean);
157
+ fadeRange?: [number, number];
158
+ interactive?: boolean;
159
+ animation?: AnchorAnimationSpec;
160
+ };
161
+ type AnchorHandle = {
162
+ wrapper: HTMLElement;
163
+ detach: () => void;
164
+ syncZ: (z: number) => void;
165
+ };
166
+
167
+ type ScrimStageDef = {
168
+ id?: string;
169
+ for?: string | string[];
170
+ forRange?: [number, number];
171
+ element: HTMLElement;
172
+ position?: ScrimOverlayPosition;
173
+ inset?: string;
174
+ interactive?: boolean;
175
+ animation?: AnchorAnimationSpec;
176
+ };
177
+ type ScrimStagesOptions = {
178
+ stages: ScrimStageDef[];
179
+ position?: ScrimOverlayPosition;
180
+ inset?: string;
181
+ interactive?: boolean;
182
+ animation?: AnchorAnimationSpec;
183
+ };
184
+
185
+ type Listener<K extends keyof SheetEventMap> = (payload: SheetEventMap[K]) => void;
186
+ declare class BottomSheetEngine {
187
+ private id;
188
+ private element;
189
+ private handle;
190
+ private scrollContainer?;
191
+ private backdrop?;
192
+ private screenComponent?;
193
+ private scrimParent;
194
+ private mode;
195
+ private flickVelocity;
196
+ private dragThreshold;
197
+ private rubberBandEnabled;
198
+ private scrim;
199
+ private aria;
200
+ private animation;
201
+ private lifecycle;
202
+ private closeOnBack;
203
+ private routedTo;
204
+ private snapPointsRaw;
205
+ private snaps;
206
+ private activeId;
207
+ private size;
208
+ private gesture;
209
+ private rootEl;
210
+ private destroyed;
211
+ private currentViewTransition;
212
+ private currentAbort;
213
+ private sizeWriteSentinel;
214
+ private progressWriteSentinel;
215
+ private isTopSheet;
216
+ private progressPayload;
217
+ private dragContextBuf;
218
+ private bus;
219
+ private persistKey;
220
+ private linkedSheets;
221
+ private scrollCache;
222
+ private teardowns;
223
+ private anchors;
224
+ private anchorHost;
225
+ private stackZ;
226
+ private detachScrimStages;
227
+ private stackEffectEnabled;
228
+ private stackEffectPrimed;
229
+ private transformTemplate;
230
+ constructor(opts: EngineOptions);
231
+ get state(): EngineState;
232
+ on<K extends keyof SheetEventMap>(event: K, fn: Listener<K>): () => void;
233
+ use(plugin: Plugin): this;
234
+ setLinkedSheets(sheets: BottomSheetEngine[]): void;
235
+ getAllowedIds(): string[];
236
+ snapTo(id: string, velocityOrOpts?: number | {
237
+ velocity?: number;
238
+ signal?: AbortSignal;
239
+ }, _skipBeforeSnap?: boolean): Promise<void>;
240
+ dragTo(targetSize: number, velocityOrOpts?: number | {
241
+ velocity?: number;
242
+ signal?: AbortSignal;
243
+ }): Promise<void>;
244
+ open(id?: string): Promise<void>;
245
+ close(): Promise<void>;
246
+ setAllowed(ids: string[], snap?: string): void;
247
+ setBackdropRange(range: [number, number]): void;
248
+ setScreenRange(range: [number, number]): void;
249
+ setScrimColor(color: string | undefined | null): void;
250
+ setScrimBlur(blur: string | undefined | null): void;
251
+ setScrimInteractive(interactive: boolean): void;
252
+ setScrim(opts: ScrimUpdate): void;
253
+ setScrimMode(mode: "full" | "above-sheet" | "off"): void;
254
+ setScrimTapToClose(enabled: boolean): void;
255
+ setScrimEnabled(enabled: boolean): void;
256
+ setScrimOverlay(opts: ScrimOverlayOptions): () => void;
257
+ addAnchor(opts: AnchorOptions): () => void;
258
+ setScrimStages(opts: ScrimStagesOptions | null): () => void;
259
+ getScrimState(): {
260
+ mode: "full" | "above-sheet" | "off";
261
+ enabled: boolean;
262
+ };
263
+ setSnapPoints(points: EngineOptions["snapPoints"], allowed?: string[]): void;
264
+ destroy(): void;
265
+ private emit;
266
+ private newCycle;
267
+ private emitBeforeSnap;
268
+ private recomputeSnaps;
269
+ private getAllowedRange;
270
+ private allowedIdsBySize;
271
+ private updateAriaSlider;
272
+ private registerInStack;
273
+ private applyStackDepth;
274
+ private attach;
275
+ private attachFeatures;
276
+ private settleAfterDrag;
277
+ private haptic;
278
+ private applySize;
279
+ private computeProgress;
280
+ private handleOpen;
281
+ private resyncAfterResize;
282
+ private handleClose;
283
+ }
284
+
285
+ export { type AnchorOptions as A, BottomSheetEngine as B, type EngineState as E, type Plugin as P, type ScrimStagesOptions as S, type TeardownScope as T, type SnapPointDef as a, type SheetMode as b, type EngineOptions as c, type SnapPoint as d, type SheetEventMap as e, type ScrimOverlayPosition as f, type AnchorAnimationPreset as g, type AnchorAnimationSpec as h, type AnchorHandle as i, type AnchorPosition as j, type AnchorState as k, SCRIM_PRESETS as l, type ScrimOverlayOptions as m, type ScrimPreset as n, type ScrimPresetConfig as o, type ScrimStageDef as p, type ScrimUpdate as q, type SnapId as r, runAnchorTransition as s };