@abhivarde/svelte-drawer 0.0.21 → 0.0.23
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 +126 -0
- package/dist/components/DrawerFooter.svelte +23 -0
- package/dist/components/DrawerFooter.svelte.d.ts +9 -0
- package/dist/components/DrawerHeader.svelte +67 -0
- package/dist/components/DrawerHeader.svelte.d.ts +12 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/types.d.ts +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@ A drawer component for Svelte 5, inspired by [Vaul](https://github.com/emilkowal
|
|
|
13
13
|
- ✅ Prebuilt variants (**default, sheet, dialog, minimal, sidebar**)
|
|
14
14
|
- ✅ **Drag handle component** with auto-adaptive orientation
|
|
15
15
|
- ✅ **Snap points** for iOS-like multi-height drawers
|
|
16
|
+
- ✅ **Portal rendering** to escape z-index conflicts
|
|
17
|
+
- ✅ **Optional header & footer** components for quick setup
|
|
16
18
|
- ✅ Nested drawer support
|
|
17
19
|
- ✅ Scrollable content areas
|
|
18
20
|
- ✅ Keyboard shortcuts (**Escape to close**, Tab navigation)
|
|
@@ -268,6 +270,98 @@ Render the drawer in a portal to avoid z-index conflicts in complex layouts.
|
|
|
268
270
|
- Modals inside scrollable containers
|
|
269
271
|
- Preventing overflow: hidden conflicts
|
|
270
272
|
|
|
273
|
+
### Header & Footer Components
|
|
274
|
+
|
|
275
|
+
Optional pre-styled header and footer components for quick setup.
|
|
276
|
+
|
|
277
|
+
#### DrawerHeader
|
|
278
|
+
```svelte
|
|
279
|
+
<script>
|
|
280
|
+
import { Drawer, DrawerOverlay, DrawerContent, DrawerHeader, DrawerHandle } from '@abhivarde/svelte-drawer';
|
|
281
|
+
|
|
282
|
+
let open = $state(false);
|
|
283
|
+
</script>
|
|
284
|
+
|
|
285
|
+
<!-- With title and description -->
|
|
286
|
+
<Drawer bind:open>
|
|
287
|
+
<DrawerOverlay class="fixed inset-0 bg-black/40" />
|
|
288
|
+
<DrawerContent class="fixed bottom-0 left-0 right-0 bg-white rounded-t-lg">
|
|
289
|
+
<DrawerHeader
|
|
290
|
+
title="Drawer Title"
|
|
291
|
+
description="Optional description text"
|
|
292
|
+
showCloseButton={true}
|
|
293
|
+
/>
|
|
294
|
+
<div class="p-4">
|
|
295
|
+
<p>Drawer content here</p>
|
|
296
|
+
</div>
|
|
297
|
+
</DrawerContent>
|
|
298
|
+
</Drawer>
|
|
299
|
+
|
|
300
|
+
<!-- Custom header content -->
|
|
301
|
+
<Drawer bind:open>
|
|
302
|
+
<DrawerOverlay />
|
|
303
|
+
<DrawerContent class="fixed bottom-0 left-0 right-0 bg-white rounded-t-lg">
|
|
304
|
+
<DrawerHeader>
|
|
305
|
+
<div class="flex items-center gap-3">
|
|
306
|
+
<img src="/icon.png" alt="Icon" class="w-8 h-8" />
|
|
307
|
+
<div>
|
|
308
|
+
<h2 class="font-semibold">Custom Header</h2>
|
|
309
|
+
<p class="text-sm text-gray-600">Your custom content</p>
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
</DrawerHeader>
|
|
313
|
+
<div class="p-4">
|
|
314
|
+
<p>Drawer content</p>
|
|
315
|
+
</div>
|
|
316
|
+
</DrawerContent>
|
|
317
|
+
</Drawer>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
#### DrawerFooter
|
|
321
|
+
```svelte
|
|
322
|
+
<script>
|
|
323
|
+
import { Drawer, DrawerOverlay, DrawerContent, DrawerFooter } from '@abhivarde/svelte-drawer';
|
|
324
|
+
|
|
325
|
+
let open = $state(false);
|
|
326
|
+
</script>
|
|
327
|
+
|
|
328
|
+
<!-- Simple footer with custom content -->
|
|
329
|
+
<Drawer bind:open>
|
|
330
|
+
<DrawerOverlay class="fixed inset-0 bg-black/40" />
|
|
331
|
+
<DrawerContent class="fixed bottom-0 left-0 right-0 bg-white rounded-t-lg flex flex-col">
|
|
332
|
+
<div class="p-4 flex-1">
|
|
333
|
+
<h2>Drawer Content</h2>
|
|
334
|
+
</div>
|
|
335
|
+
<DrawerFooter>
|
|
336
|
+
<button onclick={() => open = false} class="px-4 py-2 bg-gray-200 rounded">
|
|
337
|
+
Cancel
|
|
338
|
+
</button>
|
|
339
|
+
<button class="px-4 py-2 bg-black text-white rounded">
|
|
340
|
+
Confirm
|
|
341
|
+
</button>
|
|
342
|
+
</DrawerFooter>
|
|
343
|
+
</DrawerContent>
|
|
344
|
+
</Drawer>
|
|
345
|
+
|
|
346
|
+
<!-- Custom footer with links -->
|
|
347
|
+
<Drawer bind:open>
|
|
348
|
+
<DrawerOverlay />
|
|
349
|
+
<DrawerContent class="fixed bottom-0 left-0 right-0 bg-white rounded-t-lg flex flex-col">
|
|
350
|
+
<div class="p-4 flex-1">
|
|
351
|
+
<h2>Content</h2>
|
|
352
|
+
</div>
|
|
353
|
+
<DrawerFooter class="bg-gray-50">
|
|
354
|
+
<div class="flex justify-between w-full">
|
|
355
|
+
<a href="/privacy" class="text-sm text-gray-600 hover:text-gray-900">Privacy</a>
|
|
356
|
+
<a href="/terms" class="text-sm text-gray-600 hover:text-gray-900">Terms</a>
|
|
357
|
+
</div>
|
|
358
|
+
</DrawerFooter>
|
|
359
|
+
</DrawerContent>
|
|
360
|
+
</Drawer>
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Note:** These components are **optional**. You can still build custom headers and footers using plain HTML/Svelte markup without importing these components.
|
|
364
|
+
|
|
271
365
|
## Variants
|
|
272
366
|
|
|
273
367
|
Available variants for `DrawerVariants` component:
|
|
@@ -357,6 +451,38 @@ Pre-styled drawer content with built-in variants.
|
|
|
357
451
|
- `class` (string, optional) - Additional CSS classes for styling
|
|
358
452
|
- `trapFocus` (boolean, optional, default: true) - Whether to trap focus inside drawer
|
|
359
453
|
|
|
454
|
+
### DrawerHeader
|
|
455
|
+
|
|
456
|
+
Optional pre-styled header component.
|
|
457
|
+
|
|
458
|
+
**Props:**
|
|
459
|
+
|
|
460
|
+
- `title` (string, optional) - Header title text
|
|
461
|
+
- `description` (string, optional) - Description text below title
|
|
462
|
+
- `showCloseButton` (boolean, optional, default: true) - Show close button
|
|
463
|
+
- `onClose` (function, optional) - Custom close handler
|
|
464
|
+
- `class` (string, optional) - CSS classes for styling
|
|
465
|
+
|
|
466
|
+
**Features:**
|
|
467
|
+
|
|
468
|
+
- Automatic close button with drawer context
|
|
469
|
+
- Customizable via children render
|
|
470
|
+
- Border and padding included
|
|
471
|
+
|
|
472
|
+
### DrawerFooter
|
|
473
|
+
|
|
474
|
+
Optional pre-styled footer component.
|
|
475
|
+
|
|
476
|
+
**Props:**
|
|
477
|
+
|
|
478
|
+
- `class` (string, optional) - CSS classes for styling
|
|
479
|
+
|
|
480
|
+
**Features:**
|
|
481
|
+
|
|
482
|
+
- Automatic border and spacing
|
|
483
|
+
- Flexible content via children
|
|
484
|
+
- Works with mt-auto for bottom positioning
|
|
485
|
+
|
|
360
486
|
## Demo
|
|
361
487
|
|
|
362
488
|
Visit [drawer.abhivarde.in](https://drawer.abhivarde.in) to see live examples.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let {
|
|
3
|
+
class: className = "",
|
|
4
|
+
children,
|
|
5
|
+
actions,
|
|
6
|
+
...restProps
|
|
7
|
+
}: {
|
|
8
|
+
class?: string;
|
|
9
|
+
children?: any;
|
|
10
|
+
actions?: any;
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
} = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div class="border-t border-gray-200 p-4 mt-auto {className}" {...restProps}>
|
|
16
|
+
{#if children}
|
|
17
|
+
{@render children()}
|
|
18
|
+
{:else if actions}
|
|
19
|
+
<div class="flex justify-end gap-3">
|
|
20
|
+
{@render actions()}
|
|
21
|
+
</div>
|
|
22
|
+
{/if}
|
|
23
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
class?: string;
|
|
3
|
+
children?: any;
|
|
4
|
+
actions?: any;
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
};
|
|
7
|
+
declare const DrawerFooter: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type DrawerFooter = ReturnType<typeof DrawerFooter>;
|
|
9
|
+
export default DrawerFooter;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getContext } from "svelte";
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
title,
|
|
6
|
+
description,
|
|
7
|
+
showCloseButton = true,
|
|
8
|
+
onClose,
|
|
9
|
+
class: className = "",
|
|
10
|
+
children,
|
|
11
|
+
...restProps
|
|
12
|
+
}: {
|
|
13
|
+
title?: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
showCloseButton?: boolean;
|
|
16
|
+
onClose?: () => void;
|
|
17
|
+
class?: string;
|
|
18
|
+
children?: any;
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
} = $props();
|
|
21
|
+
|
|
22
|
+
const drawer = getContext<any>("drawer");
|
|
23
|
+
|
|
24
|
+
function handleClose() {
|
|
25
|
+
if (onClose) onClose();
|
|
26
|
+
else drawer?.closeDrawer();
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div class="border-b border-gray-200 p-4 {className}" {...restProps}>
|
|
31
|
+
<div class="flex items-start justify-between gap-4">
|
|
32
|
+
{#if children}
|
|
33
|
+
{@render children()}
|
|
34
|
+
{:else}
|
|
35
|
+
<div class="flex-1">
|
|
36
|
+
{#if title}
|
|
37
|
+
<h2 class="text-lg font-semibold text-gray-900">{title}</h2>
|
|
38
|
+
{/if}
|
|
39
|
+
{#if description}
|
|
40
|
+
<p class="text-sm text-gray-600 mt-1">{description}</p>
|
|
41
|
+
{/if}
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
{#if showCloseButton}
|
|
45
|
+
<button
|
|
46
|
+
onclick={handleClose}
|
|
47
|
+
class="p-2 rounded-md hover:bg-gray-100 transition-colors"
|
|
48
|
+
aria-label="Close drawer"
|
|
49
|
+
>
|
|
50
|
+
<svg
|
|
51
|
+
class="w-5 h-5 text-gray-500"
|
|
52
|
+
fill="none"
|
|
53
|
+
stroke="currentColor"
|
|
54
|
+
viewBox="0 0 24 24"
|
|
55
|
+
>
|
|
56
|
+
<path
|
|
57
|
+
stroke-linecap="round"
|
|
58
|
+
stroke-linejoin="round"
|
|
59
|
+
stroke-width="2"
|
|
60
|
+
d="M6 18L18 6M6 6l12 12"
|
|
61
|
+
/>
|
|
62
|
+
</svg>
|
|
63
|
+
</button>
|
|
64
|
+
{/if}
|
|
65
|
+
{/if}
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
title?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
showCloseButton?: boolean;
|
|
5
|
+
onClose?: () => void;
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: any;
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
};
|
|
10
|
+
declare const DrawerHeader: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type DrawerHeader = ReturnType<typeof DrawerHeader>;
|
|
12
|
+
export default DrawerHeader;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,6 @@ export { default as DrawerOverlay } from "./components/DrawerOverlay.svelte";
|
|
|
4
4
|
export { default as DrawerVariants } from "./components/DrawerVariants.svelte";
|
|
5
5
|
export { default as DrawerHandle } from "./components/DrawerHandle.svelte";
|
|
6
6
|
export { default as DrawerPortal } from "./components/DrawerPortal.svelte";
|
|
7
|
-
export
|
|
7
|
+
export { default as DrawerHeader } from "./components/DrawerHeader.svelte";
|
|
8
|
+
export { default as DrawerFooter } from "./components/DrawerFooter.svelte";
|
|
9
|
+
export type { DrawerProps, DrawerContentProps, DrawerOverlayProps, DrawerHandleProps, DrawerVariant, DrawerVariantsProps, DrawerPortalProps, DrawerHeaderProps, DrawerFooterProps, } from "./types";
|
package/dist/index.js
CHANGED
|
@@ -4,3 +4,5 @@ export { default as DrawerOverlay } from "./components/DrawerOverlay.svelte";
|
|
|
4
4
|
export { default as DrawerVariants } from "./components/DrawerVariants.svelte";
|
|
5
5
|
export { default as DrawerHandle } from "./components/DrawerHandle.svelte";
|
|
6
6
|
export { default as DrawerPortal } from "./components/DrawerPortal.svelte";
|
|
7
|
+
export { default as DrawerHeader } from "./components/DrawerHeader.svelte";
|
|
8
|
+
export { default as DrawerFooter } from "./components/DrawerFooter.svelte";
|
package/dist/types.d.ts
CHANGED
|
@@ -22,6 +22,16 @@ export interface DrawerHandleProps {
|
|
|
22
22
|
export interface DrawerPortalProps {
|
|
23
23
|
container?: HTMLElement | string;
|
|
24
24
|
}
|
|
25
|
+
export interface DrawerHeaderProps {
|
|
26
|
+
title?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
showCloseButton?: boolean;
|
|
29
|
+
onClose?: () => void;
|
|
30
|
+
class?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface DrawerFooterProps {
|
|
33
|
+
class?: string;
|
|
34
|
+
}
|
|
25
35
|
export type DrawerVariant = "default" | "sheet" | "dialog" | "minimal" | "sidebar";
|
|
26
36
|
export interface DrawerVariantsProps {
|
|
27
37
|
variant?: DrawerVariant;
|