@surdeddd/bottom-sheet 0.12.0 → 0.13.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 (58) hide show
  1. package/README.md +52 -1
  2. package/dist/{BottomSheetEngine-D6oiEfZ4.d.cts → BottomSheetCore-CsIjyq7C.d.cts} +60 -5
  3. package/dist/{BottomSheetEngine-Dhy0X_e9.d.ts → BottomSheetCore-D16lsa6g.d.ts} +60 -5
  4. package/dist/BottomSheetEngine-BYjAVrmd.d.cts +7 -0
  5. package/dist/BottomSheetEngine-YuCNugZn.d.ts +7 -0
  6. package/dist/core.cjs +3476 -0
  7. package/dist/core.d.cts +3 -0
  8. package/dist/core.d.ts +3 -0
  9. package/dist/core.js +3474 -0
  10. package/dist/debug.cjs +109 -0
  11. package/dist/debug.d.cts +22 -0
  12. package/dist/debug.d.ts +22 -0
  13. package/dist/debug.js +107 -0
  14. package/dist/element.cjs +972 -685
  15. package/dist/element.d.cts +2 -1
  16. package/dist/element.d.ts +2 -1
  17. package/dist/element.iife.global.js +2 -2
  18. package/dist/element.js +972 -685
  19. package/dist/features.cjs +533 -0
  20. package/dist/features.d.cts +13 -0
  21. package/dist/features.d.ts +13 -0
  22. package/dist/features.js +526 -0
  23. package/dist/index-DdYLOIIT.d.ts +15 -0
  24. package/dist/index-dfrzw-lI.d.cts +15 -0
  25. package/dist/index.cjs +805 -534
  26. package/dist/index.d.cts +6 -15
  27. package/dist/index.d.ts +6 -15
  28. package/dist/index.js +799 -535
  29. package/dist/integrations/formik.d.cts +1 -1
  30. package/dist/integrations/formik.d.ts +1 -1
  31. package/dist/integrations/react-hook-form.d.cts +1 -1
  32. package/dist/integrations/react-hook-form.d.ts +1 -1
  33. package/dist/overlay.cjs +6 -5
  34. package/dist/overlay.js +6 -5
  35. package/dist/preact.d.cts +2 -1
  36. package/dist/preact.d.ts +2 -1
  37. package/dist/qwik-lib/index.qwik.cjs +4267 -0
  38. package/dist/qwik-lib/index.qwik.mjs +4267 -0
  39. package/dist/qwik.cjs +798 -534
  40. package/dist/qwik.d.cts +2 -2
  41. package/dist/qwik.d.ts +2 -2
  42. package/dist/qwik.js +798 -534
  43. package/dist/react.cjs +798 -534
  44. package/dist/react.d.cts +3 -2
  45. package/dist/react.d.ts +3 -2
  46. package/dist/react.js +798 -534
  47. package/dist/solid.cjs +798 -534
  48. package/dist/solid.d.cts +63 -4
  49. package/dist/solid.d.ts +63 -4
  50. package/dist/solid.js +798 -534
  51. package/dist/solid.source.jsx +798 -534
  52. package/dist/svelte-core.cjs +798 -534
  53. package/dist/svelte-core.js +798 -534
  54. package/dist/svelte.cjs +798 -534
  55. package/dist/svelte.js +798 -534
  56. package/dist/vue.cjs +909 -637
  57. package/dist/vue.js +909 -637
  58. package/package.json +63 -11
package/README.md CHANGED
@@ -2,7 +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-%E2%89%A422.5%20KB%20gzip%20budget-1a1614?style=flat-square)
5
+ ![bundle](https://img.shields.io/badge/core-%E2%89%A424%20KB%20gzip%20budget-1a1614?style=flat-square)
6
+ ![slim](https://img.shields.io/badge/slim%20core-%E2%89%A419.5%20KB%20gzip-1a1614?style=flat-square)
6
7
  ![tests](https://img.shields.io/badge/tests-500%2B%20unit-2ea44f?style=flat-square)
7
8
  ![ts](https://img.shields.io/badge/TypeScript-strict-3178c6?style=flat-square&logo=typescript&logoColor=white)
8
9
  ![license](https://img.shields.io/badge/license-MIT-dc3522?style=flat-square)
@@ -13,6 +14,8 @@ stacking — and the exact same engine behind every adapter.
13
14
 
14
15
  ## 🚀 [Live demo → bottom-sheet-demo.vercel.app](https://bottom-sheet-demo.vercel.app)
15
16
 
17
+ 📚 [API reference (typedoc) → surdeddd.github.io/BottomSheet](https://surdeddd.github.io/BottomSheet/)
18
+
16
19
  <p align="center">
17
20
  <picture>
18
21
  <source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/sheet-dark.png" />
@@ -226,6 +229,8 @@ type SnapPoint =
226
229
  | `initial` | first allowed | Snap id to start at |
227
230
  | `mode` | `"bottom"` | `bottom`, `top`, `left`, `right` |
228
231
  | `animation` | `"spring"` | `spring`, `tween`, `ios-spring`, `material-bounce`, `linear`, `snappy` |
232
+ | `settleAnimation` | off | `"waapi"` — settle runs as a compositor-driven Web Animation (pre-sampled spring keyframes); falls back to rAF automatically |
233
+ | `features` | all defaults | `EngineFeature[]` — override/extend the composable feature set (see Slim core below) |
229
234
  | `spring` | snappy | `{ stiffness, damping, mass }` |
230
235
  | `flickVelocity` | `0.65 px/ms` | Mobile flick threshold |
231
236
  | `dragThreshold` | `18 px` | Below this, drag snaps back |
@@ -388,6 +393,52 @@ Three deliberate choices keep things 60 fps even on mid-range Android:
388
393
  propagate via CSS variables (`--bs-progress`, `--bs-size`) and direct
389
394
  imperative subscriptions — no React re-renders on every frame.
390
395
 
396
+ ## Slim core & composable features
397
+
398
+ The default `BottomSheetEngine` ships every optional behavior preinstalled.
399
+ If you only need the essentials, import the slim core (~17.5 KB gzip vs
400
+ ~23 KB) and register just the features you use:
401
+
402
+ ```ts
403
+ import { BottomSheetCore } from '@surdeddd/bottom-sheet/core';
404
+ import { routeFeature, contentSwipeFeature } from '@surdeddd/bottom-sheet/features';
405
+
406
+ const engine = new BottomSheetCore({
407
+ element, handle, snapPoints,
408
+ closeOnBack: true,
409
+ features: [routeFeature(), contentSwipeFeature()],
410
+ });
411
+ ```
412
+
413
+ Optional features: `routeFeature()` (`closeOnBack` / `routedTo` /
414
+ `closeOnRouteChange`), `visualViewportFeature()` (soft-keyboard clamp),
415
+ `contentSwipeFeature()`, `persistFeature()`, `autoCollapseFeature()`.
416
+ Everything else (gestures, snap math, resize self-heal, a11y slider, focus
417
+ trap, scroll lock, scrim, stacking) is core. Setting an option whose feature
418
+ is missing dev-warns once and is ignored in production. Custom features
419
+ implement `{ name, install(ctx) }` — the same seam the built-ins use.
420
+
421
+ ### Debug overlay
422
+
423
+ ```ts
424
+ import { attachDebugOverlay } from '@surdeddd/bottom-sheet/debug';
425
+
426
+ const detach = attachDebugOverlay(engine);
427
+ ```
428
+
429
+ A fixed dev panel showing the active snap, live size/progress, drag/animate
430
+ flags and the resolved snap list — driven purely by public engine events,
431
+ shipped as its own entry so it costs nothing in app bundles.
432
+
433
+ ### Qwik SSR
434
+
435
+ The package declares a `qwik` field pointing at
436
+ `dist/qwik-lib/index.qwik.mjs`. Qwik apps pick the adapter up automatically
437
+ as a vendor root: the consumer optimizer segments it into QRL chunks and
438
+ `renderToString` emits a resumable (`q:container="paused"`) sheet. No extra
439
+ configuration — `import { BottomSheet } from '@surdeddd/bottom-sheet/qwik'`
440
+ keeps working for CSR, and Qwik City SSR now works out of the box.
441
+
391
442
  ## Theming
392
443
 
393
444
  All visuals are driven by CSS custom properties. Override anywhere:
@@ -103,6 +103,7 @@ type EngineOptions = {
103
103
  scrimTapToClose?: boolean;
104
104
  scrimPreset?: ScrimPreset;
105
105
  animation?: "spring" | "tween" | "ios-spring" | "material-bounce" | "linear" | "snappy";
106
+ settleAnimation?: "waapi";
106
107
  spring?: {
107
108
  stiffness?: number;
108
109
  damping?: number;
@@ -127,15 +128,64 @@ type EngineOptions = {
127
128
  linkedSheets?: BottomSheetEngineLike[];
128
129
  viewTransitions?: boolean;
129
130
  stackEffect?: boolean;
131
+ features?: EngineFeature[];
130
132
  };
131
133
 
132
- type BottomSheetEngineLike = BottomSheetEngine;
134
+ type BottomSheetEngineLike = BottomSheetCore;
135
+ type EngineFeatureStage = "attach" | "post";
136
+ type EngineFeatureOptions = {
137
+ routedTo?: string;
138
+ closeOnBack: boolean;
139
+ closeOnRouteChange: boolean;
140
+ persistKey?: string;
141
+ autoCollapseAfter?: number;
142
+ };
143
+ type EngineFeatureContext = {
144
+ element: HTMLElement;
145
+ scrollContainer?: HTMLElement;
146
+ sheetId: string;
147
+ options: EngineFeatureOptions;
148
+ isDestroyed: () => boolean;
149
+ isDragging: () => boolean;
150
+ isAnimating: () => boolean;
151
+ isTopSheet: () => boolean;
152
+ isVerticalAxis: () => boolean;
153
+ getSize: () => number;
154
+ getActiveId: () => string;
155
+ getAllowedIds: () => string[];
156
+ allowedIdsBySize: () => string[];
157
+ getMaxAxisSize: () => number;
158
+ resolveSnap: (id: string) => {
159
+ id: string;
160
+ size: number;
161
+ } | null;
162
+ resolveActiveSnap: () => {
163
+ id: string;
164
+ size: number;
165
+ } | null;
166
+ setSize: (size: number) => void;
167
+ setMaxAxisSize: (size: number) => void;
168
+ applySize: (size: number) => void;
169
+ recomputeSnaps: () => void;
170
+ newCycle: () => void;
171
+ cancelInFlight: () => void;
172
+ resyncAfterResize: () => void;
173
+ snapTo: (id: string) => void;
174
+ close: (reason?: CloseReason) => Promise<void>;
175
+ on: <K extends keyof SheetEventMap>(event: K, fn: (payload: SheetEventMap[K]) => void) => () => void;
176
+ addTeardown: (fn: (() => void) | null | undefined) => void;
177
+ };
178
+ type EngineFeature = {
179
+ name: string;
180
+ stage?: EngineFeatureStage;
181
+ install: (ctx: EngineFeatureContext) => (() => void) | void;
182
+ };
133
183
  type TeardownScope = {
134
184
  add: (fn: (() => void) | null | undefined) => void;
135
185
  };
136
186
  type Plugin = {
137
187
  name: string;
138
- install: (engine: BottomSheetEngine, scope: TeardownScope) => void | (() => void);
188
+ install: (engine: BottomSheetCore, scope: TeardownScope) => void | (() => void);
139
189
  };
140
190
  type EngineState = {
141
191
  size: number;
@@ -200,7 +250,7 @@ type ScrimStagesOptions = {
200
250
  };
201
251
 
202
252
  type Listener<K extends keyof SheetEventMap> = (payload: SheetEventMap[K]) => void;
203
- declare class BottomSheetEngine {
253
+ declare class BottomSheetCore {
204
254
  private id;
205
255
  private element;
206
256
  private handle;
@@ -252,11 +302,16 @@ declare class BottomSheetEngine {
252
302
  private stackEffectPrimed;
253
303
  private fitDeps;
254
304
  private transformTemplate;
305
+ private featureList;
306
+ private featureCtx;
255
307
  constructor(opts: EngineOptions);
308
+ private buildFeatureContext;
309
+ private runFeatureStage;
310
+ private warnOrphanFeatureOptions;
256
311
  get state(): EngineState;
257
312
  on<K extends keyof SheetEventMap>(event: K, fn: Listener<K>): () => void;
258
313
  use(plugin: Plugin): this;
259
- setLinkedSheets(sheets: BottomSheetEngine[]): void;
314
+ setLinkedSheets(sheets: BottomSheetCore[]): void;
260
315
  getAllowedIds(): string[];
261
316
  getResolvedSnaps(): readonly {
262
317
  id: string;
@@ -330,4 +385,4 @@ declare class BottomSheetEngine {
330
385
  private handleClose;
331
386
  }
332
387
 
333
- export { type AnchorOptions as A, BottomSheetEngine as B, type CloseReason as C, 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 SheetEventMap as d, type SnapPoint 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 };
388
+ export { type AnchorOptions as A, BottomSheetCore as B, type CloseReason as C, type EngineState as E, type Plugin as P, type ScrimStagesOptions as S, type TeardownScope as T, type EngineOptions as a, type SnapPointDef as b, type SheetMode as c, type SheetEventMap as d, type SnapPoint 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, type EngineFeature as l, type EngineFeatureContext as m, type EngineFeatureOptions as n, type EngineFeatureStage as o, SCRIM_PRESETS as p, type ScrimOverlayOptions as q, type ScrimPreset as r, type ScrimPresetConfig as s, type ScrimStageDef as t, type ScrimUpdate as u, type SnapId as v, runAnchorTransition as w };
@@ -103,6 +103,7 @@ type EngineOptions = {
103
103
  scrimTapToClose?: boolean;
104
104
  scrimPreset?: ScrimPreset;
105
105
  animation?: "spring" | "tween" | "ios-spring" | "material-bounce" | "linear" | "snappy";
106
+ settleAnimation?: "waapi";
106
107
  spring?: {
107
108
  stiffness?: number;
108
109
  damping?: number;
@@ -127,15 +128,64 @@ type EngineOptions = {
127
128
  linkedSheets?: BottomSheetEngineLike[];
128
129
  viewTransitions?: boolean;
129
130
  stackEffect?: boolean;
131
+ features?: EngineFeature[];
130
132
  };
131
133
 
132
- type BottomSheetEngineLike = BottomSheetEngine;
134
+ type BottomSheetEngineLike = BottomSheetCore;
135
+ type EngineFeatureStage = "attach" | "post";
136
+ type EngineFeatureOptions = {
137
+ routedTo?: string;
138
+ closeOnBack: boolean;
139
+ closeOnRouteChange: boolean;
140
+ persistKey?: string;
141
+ autoCollapseAfter?: number;
142
+ };
143
+ type EngineFeatureContext = {
144
+ element: HTMLElement;
145
+ scrollContainer?: HTMLElement;
146
+ sheetId: string;
147
+ options: EngineFeatureOptions;
148
+ isDestroyed: () => boolean;
149
+ isDragging: () => boolean;
150
+ isAnimating: () => boolean;
151
+ isTopSheet: () => boolean;
152
+ isVerticalAxis: () => boolean;
153
+ getSize: () => number;
154
+ getActiveId: () => string;
155
+ getAllowedIds: () => string[];
156
+ allowedIdsBySize: () => string[];
157
+ getMaxAxisSize: () => number;
158
+ resolveSnap: (id: string) => {
159
+ id: string;
160
+ size: number;
161
+ } | null;
162
+ resolveActiveSnap: () => {
163
+ id: string;
164
+ size: number;
165
+ } | null;
166
+ setSize: (size: number) => void;
167
+ setMaxAxisSize: (size: number) => void;
168
+ applySize: (size: number) => void;
169
+ recomputeSnaps: () => void;
170
+ newCycle: () => void;
171
+ cancelInFlight: () => void;
172
+ resyncAfterResize: () => void;
173
+ snapTo: (id: string) => void;
174
+ close: (reason?: CloseReason) => Promise<void>;
175
+ on: <K extends keyof SheetEventMap>(event: K, fn: (payload: SheetEventMap[K]) => void) => () => void;
176
+ addTeardown: (fn: (() => void) | null | undefined) => void;
177
+ };
178
+ type EngineFeature = {
179
+ name: string;
180
+ stage?: EngineFeatureStage;
181
+ install: (ctx: EngineFeatureContext) => (() => void) | void;
182
+ };
133
183
  type TeardownScope = {
134
184
  add: (fn: (() => void) | null | undefined) => void;
135
185
  };
136
186
  type Plugin = {
137
187
  name: string;
138
- install: (engine: BottomSheetEngine, scope: TeardownScope) => void | (() => void);
188
+ install: (engine: BottomSheetCore, scope: TeardownScope) => void | (() => void);
139
189
  };
140
190
  type EngineState = {
141
191
  size: number;
@@ -200,7 +250,7 @@ type ScrimStagesOptions = {
200
250
  };
201
251
 
202
252
  type Listener<K extends keyof SheetEventMap> = (payload: SheetEventMap[K]) => void;
203
- declare class BottomSheetEngine {
253
+ declare class BottomSheetCore {
204
254
  private id;
205
255
  private element;
206
256
  private handle;
@@ -252,11 +302,16 @@ declare class BottomSheetEngine {
252
302
  private stackEffectPrimed;
253
303
  private fitDeps;
254
304
  private transformTemplate;
305
+ private featureList;
306
+ private featureCtx;
255
307
  constructor(opts: EngineOptions);
308
+ private buildFeatureContext;
309
+ private runFeatureStage;
310
+ private warnOrphanFeatureOptions;
256
311
  get state(): EngineState;
257
312
  on<K extends keyof SheetEventMap>(event: K, fn: Listener<K>): () => void;
258
313
  use(plugin: Plugin): this;
259
- setLinkedSheets(sheets: BottomSheetEngine[]): void;
314
+ setLinkedSheets(sheets: BottomSheetCore[]): void;
260
315
  getAllowedIds(): string[];
261
316
  getResolvedSnaps(): readonly {
262
317
  id: string;
@@ -330,4 +385,4 @@ declare class BottomSheetEngine {
330
385
  private handleClose;
331
386
  }
332
387
 
333
- export { type AnchorOptions as A, BottomSheetEngine as B, type CloseReason as C, 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 SheetEventMap as d, type SnapPoint 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 };
388
+ export { type AnchorOptions as A, BottomSheetCore as B, type CloseReason as C, type EngineState as E, type Plugin as P, type ScrimStagesOptions as S, type TeardownScope as T, type EngineOptions as a, type SnapPointDef as b, type SheetMode as c, type SheetEventMap as d, type SnapPoint 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, type EngineFeature as l, type EngineFeatureContext as m, type EngineFeatureOptions as n, type EngineFeatureStage as o, SCRIM_PRESETS as p, type ScrimOverlayOptions as q, type ScrimPreset as r, type ScrimPresetConfig as s, type ScrimStageDef as t, type ScrimUpdate as u, type SnapId as v, runAnchorTransition as w };
@@ -0,0 +1,7 @@
1
+ import { B as BottomSheetCore, a as EngineOptions } from './BottomSheetCore-CsIjyq7C.cjs';
2
+
3
+ declare class BottomSheetEngine extends BottomSheetCore {
4
+ constructor(opts: EngineOptions);
5
+ }
6
+
7
+ export { BottomSheetEngine as B };
@@ -0,0 +1,7 @@
1
+ import { B as BottomSheetCore, a as EngineOptions } from './BottomSheetCore-D16lsa6g.js';
2
+
3
+ declare class BottomSheetEngine extends BottomSheetCore {
4
+ constructor(opts: EngineOptions);
5
+ }
6
+
7
+ export { BottomSheetEngine as B };