@surdeddd/bottom-sheet 0.2.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 (49) hide show
  1. package/README.md +51 -21
  2. package/dist/{BottomSheetEngine-CIT9Htti.d.cts → BottomSheetEngine-CAymrH-P.d.cts} +67 -1
  3. package/dist/{BottomSheetEngine-Df9MwBbm.d.ts → BottomSheetEngine-DcqcuudN.d.ts} +67 -1
  4. package/dist/element.cjs +699 -116
  5. package/dist/element.d.cts +7 -2
  6. package/dist/element.d.ts +7 -2
  7. package/dist/element.iife.global.js +2 -2
  8. package/dist/element.js +699 -116
  9. package/dist/index.cjs +715 -145
  10. package/dist/index.d.cts +17 -3
  11. package/dist/index.d.ts +17 -3
  12. package/dist/index.js +713 -146
  13. package/dist/integrations/formik.d.cts +1 -1
  14. package/dist/integrations/formik.d.ts +1 -1
  15. package/dist/integrations/react-hook-form.d.cts +1 -1
  16. package/dist/integrations/react-hook-form.d.ts +1 -1
  17. package/dist/overlay.cjs +168 -35
  18. package/dist/overlay.d.cts +13 -0
  19. package/dist/overlay.d.ts +13 -0
  20. package/dist/overlay.js +168 -35
  21. package/dist/preact.d.cts +1 -1
  22. package/dist/preact.d.ts +1 -1
  23. package/dist/qwik.cjs +619 -119
  24. package/dist/qwik.d.cts +2 -2
  25. package/dist/qwik.d.ts +2 -2
  26. package/dist/qwik.js +620 -120
  27. package/dist/react.cjs +821 -191
  28. package/dist/react.d.cts +20 -3
  29. package/dist/react.d.ts +20 -3
  30. package/dist/react.js +821 -191
  31. package/dist/solid.cjs +656 -161
  32. package/dist/solid.d.cts +263 -4
  33. package/dist/solid.d.ts +263 -4
  34. package/dist/solid.js +657 -162
  35. package/dist/solid.source.jsx +3215 -0
  36. package/dist/styles.css +10 -10
  37. package/dist/svelte-core.cjs +3149 -0
  38. package/dist/svelte-core.js +3147 -0
  39. package/dist/svelte-src/BottomSheet.svelte +210 -0
  40. package/dist/svelte-src/index.js +2 -0
  41. package/dist/svelte.cjs +618 -124
  42. package/dist/svelte.d.cts +100 -0
  43. package/dist/svelte.d.ts +7 -3
  44. package/dist/svelte.js +619 -125
  45. package/dist/vue.cjs +612 -119
  46. package/dist/vue.d.cts +78 -0
  47. package/dist/vue.d.ts +6 -2
  48. package/dist/vue.js +612 -119
  49. package/package.json +103 -43
@@ -0,0 +1,210 @@
1
+ <script lang="ts" generics="TId extends string = string">
2
+ import { onMount, onDestroy, untrack, type Snippet } from "svelte";
3
+ import { BottomSheetEngine } from "@surdeddd/bottom-sheet";
4
+ import type {
5
+ EngineState,
6
+ SnapPointDef,
7
+ SheetMode,
8
+ ScrimUpdate,
9
+ ScrimOverlayOptions,
10
+ EngineOptions,
11
+ } from "@surdeddd/bottom-sheet";
12
+
13
+ type Props = {
14
+ snapPoints: SnapPointDef<TId>[];
15
+ allowed?: TId[];
16
+ initial?: TId;
17
+ mode?: SheetMode;
18
+ animation?: "spring" | "tween";
19
+ spring?: { stiffness?: number; damping?: number; mass?: number };
20
+ focusTrap?: boolean;
21
+ closeOnEscape?: boolean;
22
+ closeOnBack?: boolean;
23
+ lockBodyScroll?: boolean;
24
+ rubberBand?: boolean;
25
+ backdropRange?: [number, number];
26
+ backdrop?: boolean;
27
+ closeOnBackdrop?: boolean;
28
+ ariaLabel?: string;
29
+ header?: Snippet<[EngineState & { activeId: TId }]>;
30
+ leftButton?: Snippet;
31
+ rightButton?: Snippet;
32
+ screen?: Snippet;
33
+ children?: Snippet;
34
+ onsnap?: (id: TId) => void;
35
+ onopen?: (id: TId) => void;
36
+ onclose?: () => void;
37
+ onchange?: (state: EngineState & { activeId: TId }) => void;
38
+ };
39
+
40
+ let {
41
+ snapPoints,
42
+ allowed,
43
+ initial,
44
+ mode = "bottom",
45
+ animation = "spring",
46
+ spring,
47
+ focusTrap = false,
48
+ closeOnEscape = true,
49
+ closeOnBack = false,
50
+ lockBodyScroll = true,
51
+ rubberBand = true,
52
+ backdropRange,
53
+ backdrop = true,
54
+ closeOnBackdrop = true,
55
+ ariaLabel = "Bottom sheet",
56
+ header,
57
+ leftButton,
58
+ rightButton,
59
+ screen,
60
+ children,
61
+ onsnap,
62
+ onopen,
63
+ onclose,
64
+ onchange,
65
+ }: Props = $props();
66
+
67
+ let sheetEl: HTMLElement | undefined = $state();
68
+ let handleEl: HTMLElement | undefined = $state();
69
+ let contentEl: HTMLElement | undefined = $state();
70
+ let backdropEl: HTMLElement | undefined = $state();
71
+ let screenEl: HTMLElement | undefined = $state();
72
+
73
+ let viewState: EngineState & { activeId: TId } = $state({
74
+ size: 0,
75
+ activeId: untrack(
76
+ () => (initial ?? snapPoints[0]?.id ?? "default") as TId,
77
+ ),
78
+ isDragging: false,
79
+ isAnimating: false,
80
+ progress: 0,
81
+ });
82
+
83
+ let engine: BottomSheetEngine | null = null;
84
+
85
+ onMount(() => {
86
+ if (!sheetEl) return;
87
+ engine = new BottomSheetEngine({
88
+ element: sheetEl,
89
+ handle: handleEl,
90
+ scrollContainer: contentEl,
91
+ backdrop: backdropEl,
92
+ scrim: screenEl,
93
+ mode,
94
+ snapPoints,
95
+ allowed,
96
+ initial,
97
+ animation,
98
+ spring,
99
+ focusTrap,
100
+ closeOnEscape,
101
+ closeOnBack,
102
+ lockBodyScroll,
103
+ rubberBand,
104
+ backdropRange,
105
+ });
106
+ const sync = () => {
107
+ if (!engine) return;
108
+ viewState = { ...engine.state } as EngineState & { activeId: TId };
109
+ onchange?.(viewState);
110
+ };
111
+ sync();
112
+ engine.on("snap", payload => {
113
+ sync();
114
+ onsnap?.(payload.id as TId);
115
+ });
116
+ engine.on("open", payload => onopen?.(payload.id as TId));
117
+ engine.on("close", () => onclose?.());
118
+ engine.on("dragstart", sync);
119
+ engine.on("dragend", sync);
120
+ });
121
+
122
+ onDestroy(() => {
123
+ engine?.destroy();
124
+ engine = null;
125
+ });
126
+
127
+ export const snapTo = (id: TId) =>
128
+ engine?.snapTo(id) ?? Promise.resolve();
129
+ export const open = (id?: TId) =>
130
+ engine?.open(id) ?? Promise.resolve();
131
+ export const close = () => engine?.close() ?? Promise.resolve();
132
+ export const setAllowed = (ids: TId[], snap?: TId) =>
133
+ engine?.setAllowed(ids as unknown as string[], snap);
134
+ export const setSnapPoints = (
135
+ points: EngineOptions["snapPoints"],
136
+ nextAllowed?: string[],
137
+ ) => engine?.setSnapPoints(points, nextAllowed);
138
+ export const setScrim = (opts: ScrimUpdate) => engine?.setScrim(opts);
139
+ export const setScrimOverlay = (opts: ScrimOverlayOptions): (() => void) =>
140
+ engine?.setScrimOverlay(opts) ?? (() => {});
141
+ export const getState = (): EngineState & { activeId: TId } =>
142
+ (engine?.state ?? viewState) as EngineState & { activeId: TId };
143
+ export const getEngine = (): BottomSheetEngine | null => engine;
144
+
145
+ let allowedIds = $derived(
146
+ allowed && allowed.length > 0
147
+ ? allowed
148
+ : snapPoints.map(s => s.id),
149
+ );
150
+ let activeIdx = $derived(allowedIds.indexOf(viewState.activeId));
151
+ let isVerticalAxis = $derived(mode === "bottom" || mode === "top");
152
+ </script>
153
+
154
+ <div class="bs-root">
155
+ {#if backdrop}
156
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
157
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
158
+ <div
159
+ class="bs-backdrop"
160
+ bind:this={backdropEl}
161
+ aria-hidden="true"
162
+ onclick={closeOnBackdrop ? () => engine?.close() : undefined}
163
+ ></div>
164
+ {/if}
165
+ <div class="bs-screen" bind:this={screenEl}>
166
+ {#if screen}{@render screen()}{/if}
167
+ </div>
168
+ <!-- svelte-ignore a11y_no_noninteractive_element_to_interactive_role -->
169
+ <section
170
+ class="bs-sheet"
171
+ bind:this={sheetEl}
172
+ data-mode={mode}
173
+ data-active={viewState.activeId}
174
+ role="dialog"
175
+ aria-modal={focusTrap ? "true" : undefined}
176
+ aria-label={ariaLabel}
177
+ >
178
+ {#if leftButton}
179
+ <div class="bs-button-slot" data-side="left">
180
+ {@render leftButton()}
181
+ </div>
182
+ {/if}
183
+ {#if rightButton}
184
+ <div class="bs-button-slot" data-side="right">
185
+ {@render rightButton()}
186
+ </div>
187
+ {/if}
188
+ <div
189
+ class="bs-handle"
190
+ bind:this={handleEl}
191
+ role="slider"
192
+ tabindex="0"
193
+ aria-label="Resize sheet"
194
+ aria-orientation={isVerticalAxis ? "vertical" : "horizontal"}
195
+ aria-valuemin={0}
196
+ aria-valuemax={Math.max(0, allowedIds.length - 1)}
197
+ aria-valuenow={Math.max(0, activeIdx)}
198
+ aria-valuetext={viewState.activeId}
199
+ >
200
+ {#if header}{@render header(viewState)}{/if}
201
+ </div>
202
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
203
+ <div class="bs-content" bind:this={contentEl} tabindex="0" role="region" aria-label="Sheet content">
204
+ {#if children}{@render children()}{/if}
205
+ </div>
206
+ <span class="bs-sr-only" role="status" aria-live="polite">
207
+ {viewState.activeId}
208
+ </span>
209
+ </section>
210
+ </div>
@@ -0,0 +1,2 @@
1
+ export { default as BottomSheet } from "./BottomSheet.svelte";
2
+ export { createBottomSheet } from "../svelte-core.js";