@abhivarde/svelte-drawer 0.0.24 → 0.0.25

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 CHANGED
@@ -398,6 +398,61 @@ Optional pre-styled header and footer components for quick setup.
398
398
 
399
399
  **Note:** These components are **optional**. You can still build custom headers and footers using plain HTML/Svelte markup without importing these components.
400
400
 
401
+ ### Persistent State
402
+
403
+ Automatically save and restore drawer state across page reloads.
404
+ ```svelte
405
+ <script>
406
+ import { Drawer, DrawerOverlay, DrawerContent } from '@abhivarde/svelte-drawer';
407
+
408
+ let open = $state(false);
409
+ </script>
410
+
411
+ <Drawer
412
+ bind:open
413
+ persistState={true}
414
+ persistKey="main-drawer"
415
+ >
416
+ <DrawerOverlay />
417
+ <DrawerContent class="...">
418
+ <h2>This drawer remembers if it was open!</h2>
419
+ <p>Reload the page and it will restore its state.</p>
420
+ </DrawerContent>
421
+ </Drawer>
422
+ ```
423
+
424
+ **With snap points:**
425
+ ```svelte
426
+ <Drawer
427
+ bind:open
428
+ snapPoints={[0.25, 0.5, 0.9]}
429
+ bind:activeSnapPoint
430
+ persistState={true}
431
+ persistKey="snap-drawer"
432
+ persistSnapPoint={true}
433
+ >
434
+ <DrawerOverlay />
435
+ <DrawerContent class="...">
436
+ <h2>Position is saved too!</h2>
437
+ <p>The snap point will be restored on reload.</p>
438
+ </DrawerContent>
439
+ </Drawer>
440
+ ```
441
+
442
+ **Clear saved state programmatically:**
443
+ ```svelte
444
+ <script>
445
+ import { clearDrawerState } from '@abhivarde/svelte-drawer';
446
+
447
+ function resetDrawer() {
448
+ clearDrawerState('main-drawer');
449
+ // Drawer will reset to default state on next load
450
+ }
451
+ </script>
452
+
453
+ <button onclick={resetDrawer}>Reset Drawer State</button>
454
+ ```
455
+
401
456
  ## Variants
402
457
 
403
458
  Available variants for `DrawerVariants` component:
@@ -431,6 +486,9 @@ Main wrapper component that manages drawer state and animations.
431
486
  - `onSnapPointChange` (function, optional) - Callback fired when snap changes
432
487
  - `portal` (boolean, optional, default: false) - Render drawer in a portal
433
488
  - `portalContainer` (HTMLElement | string, optional) - Custom portal container element or selector
489
+ - `persistState` (boolean, optional, default: false) - Enable persistent state
490
+ - `persistKey` (string, optional, default: "default") - Unique identifier for this drawer
491
+ - `persistSnapPoint` (boolean, optional, default: false) - Whether to persist snap point position
434
492
 
435
493
  ### DrawerOverlay
436
494
 
@@ -3,6 +3,7 @@
3
3
  import { expoOut } from "svelte/easing";
4
4
  import { setContext, onMount } from "svelte";
5
5
  import DrawerPortal from "./DrawerPortal.svelte";
6
+ import { saveDrawerState, loadDrawerState } from "../utils/storage"; // NEW
6
7
 
7
8
  let {
8
9
  open = $bindable(false),
@@ -14,6 +15,9 @@
14
15
  onSnapPointChange = undefined,
15
16
  portal = false,
16
17
  portalContainer = undefined,
18
+ persistState = false,
19
+ persistKey = "default",
20
+ persistSnapPoint = false,
17
21
  children,
18
22
  } = $props();
19
23
 
@@ -30,6 +34,43 @@
30
34
  let previouslyFocusedElement: HTMLElement | null = null;
31
35
  let visible = false;
32
36
  let previousSnapPoint: number | undefined = undefined;
37
+ let stateLoaded = false;
38
+
39
+ onMount(() => {
40
+ if (persistState && !stateLoaded) {
41
+ const savedState = loadDrawerState(persistKey);
42
+
43
+ if (savedState) {
44
+ open = savedState.open;
45
+
46
+ if (
47
+ persistSnapPoint &&
48
+ savedState.snapPoint !== undefined &&
49
+ snapPoints
50
+ ) {
51
+ activeSnapPoint = savedState.snapPoint;
52
+ }
53
+ }
54
+
55
+ stateLoaded = true;
56
+ }
57
+
58
+ window.addEventListener("keydown", handleKeydown);
59
+ return () => {
60
+ window.removeEventListener("keydown", handleKeydown);
61
+ document.body.style.overflow = "";
62
+ };
63
+ });
64
+
65
+ $effect(() => {
66
+ if (persistState && stateLoaded) {
67
+ saveDrawerState(
68
+ persistKey,
69
+ open,
70
+ persistSnapPoint ? activeSnapPoint : undefined
71
+ );
72
+ }
73
+ });
33
74
 
34
75
  $effect(() => {
35
76
  if (
@@ -108,14 +149,6 @@
108
149
  }
109
150
  }
110
151
 
111
- onMount(() => {
112
- window.addEventListener("keydown", handleKeydown);
113
- return () => {
114
- window.removeEventListener("keydown", handleKeydown);
115
- document.body.style.overflow = "";
116
- };
117
- });
118
-
119
152
  setContext("drawer", {
120
153
  get open() {
121
154
  return open;
@@ -8,6 +8,9 @@ declare const Drawer: import("svelte").Component<{
8
8
  onSnapPointChange?: any;
9
9
  portal?: boolean;
10
10
  portalContainer?: any;
11
+ persistState?: boolean;
12
+ persistKey?: string;
13
+ persistSnapPoint?: boolean;
11
14
  children: any;
12
15
  }, {}, "open" | "activeSnapPoint">;
13
16
  type Drawer = ReturnType<typeof Drawer>;
package/dist/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export { default as DrawerHandle } from "./components/DrawerHandle.svelte";
6
6
  export { default as DrawerPortal } from "./components/DrawerPortal.svelte";
7
7
  export { default as DrawerHeader } from "./components/DrawerHeader.svelte";
8
8
  export { default as DrawerFooter } from "./components/DrawerFooter.svelte";
9
+ export { saveDrawerState, loadDrawerState, clearDrawerState, } from "./utils/storage";
9
10
  export type { DrawerProps, DrawerContentProps, DrawerOverlayProps, DrawerHandleProps, DrawerVariant, DrawerVariantsProps, DrawerPortalProps, DrawerHeaderProps, DrawerFooterProps, } from "./types";
package/dist/index.js CHANGED
@@ -6,3 +6,4 @@ export { default as DrawerHandle } from "./components/DrawerHandle.svelte";
6
6
  export { default as DrawerPortal } from "./components/DrawerPortal.svelte";
7
7
  export { default as DrawerHeader } from "./components/DrawerHeader.svelte";
8
8
  export { default as DrawerFooter } from "./components/DrawerFooter.svelte";
9
+ export { saveDrawerState, loadDrawerState, clearDrawerState, } from "./utils/storage";
package/dist/types.d.ts CHANGED
@@ -8,6 +8,9 @@ export interface DrawerProps {
8
8
  onSnapPointChange?: (snapPoint: number) => void;
9
9
  portal?: boolean;
10
10
  portalContainer?: HTMLElement | string;
11
+ persistState?: boolean;
12
+ persistKey?: string;
13
+ persistSnapPoint?: boolean;
11
14
  }
12
15
  export interface DrawerContentProps {
13
16
  class?: string;
@@ -0,0 +1,8 @@
1
+ interface DrawerState {
2
+ open: boolean;
3
+ snapPoint?: number;
4
+ }
5
+ export declare function saveDrawerState(key: string, open: boolean, snapPoint?: number): void;
6
+ export declare function loadDrawerState(key: string): DrawerState | null;
7
+ export declare function clearDrawerState(key: string): void;
8
+ export {};
@@ -0,0 +1,39 @@
1
+ const STORAGE_PREFIX = "svelte-drawer-";
2
+ export function saveDrawerState(key, open, snapPoint) {
3
+ if (typeof window === "undefined")
4
+ return;
5
+ try {
6
+ const state = { open };
7
+ if (snapPoint !== undefined) {
8
+ state.snapPoint = snapPoint;
9
+ }
10
+ localStorage.setItem(`${STORAGE_PREFIX}${key}`, JSON.stringify(state));
11
+ }
12
+ catch (error) {
13
+ console.warn("Failed to save drawer state:", error);
14
+ }
15
+ }
16
+ export function loadDrawerState(key) {
17
+ if (typeof window === "undefined")
18
+ return null;
19
+ try {
20
+ const stored = localStorage.getItem(`${STORAGE_PREFIX}${key}`);
21
+ if (!stored)
22
+ return null;
23
+ return JSON.parse(stored);
24
+ }
25
+ catch (error) {
26
+ console.warn("Failed to load drawer state:", error);
27
+ return null;
28
+ }
29
+ }
30
+ export function clearDrawerState(key) {
31
+ if (typeof window === "undefined")
32
+ return;
33
+ try {
34
+ localStorage.removeItem(`${STORAGE_PREFIX}${key}`);
35
+ }
36
+ catch (error) {
37
+ console.warn("Failed to clear drawer state:", error);
38
+ }
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abhivarde/svelte-drawer",
3
- "version": "0.0.24",
3
+ "version": "0.0.25",
4
4
  "description": "A drawer component for Svelte 5, inspired by Vaul",
5
5
  "author": "Abhi Varde",
6
6
  "license": "MIT",