@celar-ui/svelte 0.0.14 → 0.0.15
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/dist/index.d.ts
CHANGED
|
@@ -24,3 +24,4 @@ export { default as Slider } from './inputs/Slider.svelte';
|
|
|
24
24
|
export { default as AppBar } from './navigation/AppBar.svelte';
|
|
25
25
|
export { default as NavigationBar } from './navigation/NavigationBar.svelte';
|
|
26
26
|
export { default as NavigationBarButton } from './navigation/NavigationBarButton.svelte';
|
|
27
|
+
export { default as NavigationDrawer } from './navigation/NavigationDrawer.svelte';
|
package/dist/index.js
CHANGED
|
@@ -25,3 +25,4 @@ export { default as Slider } from './inputs/Slider.svelte';
|
|
|
25
25
|
export { default as AppBar } from './navigation/AppBar.svelte';
|
|
26
26
|
export { default as NavigationBar } from './navigation/NavigationBar.svelte';
|
|
27
27
|
export { default as NavigationBarButton } from './navigation/NavigationBarButton.svelte';
|
|
28
|
+
export { default as NavigationDrawer } from './navigation/NavigationDrawer.svelte';
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { fade, fly } from 'svelte/transition';
|
|
3
|
+
import { Dialog as BitDialog, type DialogRootProps } from 'bits-ui';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import IconButton from '../buttons/IconButton.svelte';
|
|
6
|
+
|
|
7
|
+
export interface NavigationDrawerProps extends DialogRootProps {
|
|
8
|
+
header?: Snippet;
|
|
9
|
+
footer?: Snippet;
|
|
10
|
+
close?: Snippet;
|
|
11
|
+
position?: 'left' | 'right';
|
|
12
|
+
width?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
open = $bindable(false),
|
|
17
|
+
header,
|
|
18
|
+
footer,
|
|
19
|
+
close,
|
|
20
|
+
children,
|
|
21
|
+
position = 'left',
|
|
22
|
+
width = '280px',
|
|
23
|
+
...rest
|
|
24
|
+
}: NavigationDrawerProps = $props();
|
|
25
|
+
|
|
26
|
+
let duration = 200;
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<BitDialog.Root {...rest} bind:open>
|
|
30
|
+
<BitDialog.Portal>
|
|
31
|
+
<BitDialog.Overlay forceMount>
|
|
32
|
+
{#snippet child({ props, open })}
|
|
33
|
+
{#if open}
|
|
34
|
+
<div {...props} data-navigation-drawer-backdrop transition:fade={{ duration }}></div>
|
|
35
|
+
{/if}
|
|
36
|
+
{/snippet}
|
|
37
|
+
</BitDialog.Overlay>
|
|
38
|
+
<BitDialog.Content forceMount data-position={position}>
|
|
39
|
+
{#snippet child({ props, open })}
|
|
40
|
+
{#if open}
|
|
41
|
+
<aside
|
|
42
|
+
{...props}
|
|
43
|
+
data-navigation-drawer
|
|
44
|
+
style:width
|
|
45
|
+
transition:fly={{
|
|
46
|
+
duration,
|
|
47
|
+
x: position === 'left' ? -280 : 280,
|
|
48
|
+
opacity: 0
|
|
49
|
+
}}
|
|
50
|
+
aria-label="Navigation drawer"
|
|
51
|
+
>
|
|
52
|
+
{#if header}
|
|
53
|
+
<div data-navigation-drawer-header>
|
|
54
|
+
{@render header()}
|
|
55
|
+
{#if close}
|
|
56
|
+
<BitDialog.Close>
|
|
57
|
+
{#snippet child({ props })}
|
|
58
|
+
<IconButton {...props} data-navigation-drawer-close>
|
|
59
|
+
{@render close()}
|
|
60
|
+
</IconButton>
|
|
61
|
+
{/snippet}
|
|
62
|
+
</BitDialog.Close>
|
|
63
|
+
{/if}
|
|
64
|
+
</div>
|
|
65
|
+
{/if}
|
|
66
|
+
|
|
67
|
+
<div data-navigation-drawer-content>
|
|
68
|
+
{@render children?.()}
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
{#if footer}
|
|
72
|
+
<div data-navigation-drawer-footer>
|
|
73
|
+
{@render footer()}
|
|
74
|
+
</div>
|
|
75
|
+
{/if}
|
|
76
|
+
</aside>
|
|
77
|
+
{/if}
|
|
78
|
+
{/snippet}
|
|
79
|
+
</BitDialog.Content>
|
|
80
|
+
</BitDialog.Portal>
|
|
81
|
+
</BitDialog.Root>
|
|
82
|
+
|
|
83
|
+
<style>:global([data-navigation-drawer-backdrop]) {
|
|
84
|
+
position: fixed;
|
|
85
|
+
top: 0;
|
|
86
|
+
left: 0;
|
|
87
|
+
width: 100%;
|
|
88
|
+
height: 100%;
|
|
89
|
+
-webkit-backdrop-filter: blur(var(--blur-length));
|
|
90
|
+
backdrop-filter: blur(var(--blur-length));
|
|
91
|
+
background-color: var(--color-border--strong);
|
|
92
|
+
z-index: 100;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
:global([data-navigation-drawer]) {
|
|
96
|
+
box-sizing: border-box;
|
|
97
|
+
display: flex;
|
|
98
|
+
position: fixed;
|
|
99
|
+
top: 0;
|
|
100
|
+
z-index: 100;
|
|
101
|
+
flex-direction: column;
|
|
102
|
+
background-color: var(--color-bg);
|
|
103
|
+
height: 100vh;
|
|
104
|
+
overflow-y: auto;
|
|
105
|
+
box-shadow: 0 4px 1rem var(--color-shadow);
|
|
106
|
+
max-width: 85%;
|
|
107
|
+
}
|
|
108
|
+
:global([data-navigation-drawer])[data-position=left] {
|
|
109
|
+
left: 0;
|
|
110
|
+
border-top-right-radius: var(--radius);
|
|
111
|
+
border-bottom-right-radius: var(--radius);
|
|
112
|
+
}
|
|
113
|
+
:global([data-navigation-drawer])[data-position=right] {
|
|
114
|
+
right: 0;
|
|
115
|
+
border-top-left-radius: var(--radius);
|
|
116
|
+
border-bottom-left-radius: var(--radius);
|
|
117
|
+
}
|
|
118
|
+
:global([data-navigation-drawer]) [data-navigation-drawer-header] {
|
|
119
|
+
display: flex;
|
|
120
|
+
justify-content: space-between;
|
|
121
|
+
align-items: center;
|
|
122
|
+
border-bottom: 1px solid var(--color-border);
|
|
123
|
+
padding: var(--gap);
|
|
124
|
+
flex-shrink: 0;
|
|
125
|
+
}
|
|
126
|
+
:global([data-navigation-drawer]) [data-navigation-drawer-header] [data-navigation-drawer-close] {
|
|
127
|
+
margin-left: auto;
|
|
128
|
+
}
|
|
129
|
+
:global([data-navigation-drawer]) [data-navigation-drawer-content] {
|
|
130
|
+
flex: 1;
|
|
131
|
+
overflow-y: auto;
|
|
132
|
+
padding: var(--gap--half);
|
|
133
|
+
}
|
|
134
|
+
:global([data-navigation-drawer]) [data-navigation-drawer-footer] {
|
|
135
|
+
border-top: 1px solid var(--color-border);
|
|
136
|
+
padding: var(--gap);
|
|
137
|
+
flex-shrink: 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* Scrollbar styling */
|
|
141
|
+
:global([data-navigation-drawer]) {
|
|
142
|
+
scrollbar-width: thin;
|
|
143
|
+
scrollbar-color: var(--color-border) transparent;
|
|
144
|
+
}
|
|
145
|
+
:global([data-navigation-drawer])::-webkit-scrollbar {
|
|
146
|
+
width: 6px;
|
|
147
|
+
}
|
|
148
|
+
:global([data-navigation-drawer])::-webkit-scrollbar-track {
|
|
149
|
+
background: transparent;
|
|
150
|
+
}
|
|
151
|
+
:global([data-navigation-drawer])::-webkit-scrollbar-thumb {
|
|
152
|
+
border-radius: 3px;
|
|
153
|
+
background-color: var(--color-border);
|
|
154
|
+
}
|
|
155
|
+
:global([data-navigation-drawer])::-webkit-scrollbar-thumb:hover {
|
|
156
|
+
background-color: var(--color-primary--light);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* Focus management */
|
|
160
|
+
:global([data-navigation-drawer]:focus-visible) {
|
|
161
|
+
outline: 2px solid var(--color-primary);
|
|
162
|
+
outline-offset: -2px;
|
|
163
|
+
}</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type DialogRootProps } from 'bits-ui';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
export interface NavigationDrawerProps extends DialogRootProps {
|
|
4
|
+
header?: Snippet;
|
|
5
|
+
footer?: Snippet;
|
|
6
|
+
close?: Snippet;
|
|
7
|
+
position?: 'left' | 'right';
|
|
8
|
+
width?: string;
|
|
9
|
+
}
|
|
10
|
+
declare const NavigationDrawer: import("svelte").Component<NavigationDrawerProps, {}, "open">;
|
|
11
|
+
type NavigationDrawer = ReturnType<typeof NavigationDrawer>;
|
|
12
|
+
export default NavigationDrawer;
|
|
@@ -38,19 +38,26 @@
|
|
|
38
38
|
{/snippet}
|
|
39
39
|
</BitDialog.Trigger>
|
|
40
40
|
<BitDialog.Portal>
|
|
41
|
-
<BitDialog.Overlay forceMount>
|
|
41
|
+
<BitDialog.Overlay forceMount data-celar-dialog-overlay>
|
|
42
42
|
{#snippet child({ props, open })}
|
|
43
43
|
{#if open}
|
|
44
44
|
<div {...props} transition:fade={{ duration }}></div>
|
|
45
45
|
{/if}
|
|
46
46
|
{/snippet}
|
|
47
47
|
</BitDialog.Overlay>
|
|
48
|
-
<BitDialog.Content
|
|
48
|
+
<BitDialog.Content
|
|
49
|
+
forceMount
|
|
50
|
+
data-xs={xs}
|
|
51
|
+
data-sm={sm}
|
|
52
|
+
data-md={md}
|
|
53
|
+
data-fluid={fluid}
|
|
54
|
+
data-celar-dialog-content
|
|
55
|
+
>
|
|
49
56
|
{#snippet child({ props, open })}
|
|
50
57
|
{#if open}
|
|
51
58
|
<div {...props} transition:fly={{ duration, y: 50 }}>
|
|
52
59
|
<div data-dialog-header>
|
|
53
|
-
<BitDialog.Title children={title} />
|
|
60
|
+
<BitDialog.Title children={title} data-celar-dialog-title />
|
|
54
61
|
<BitDialog.Close>
|
|
55
62
|
{#snippet child({ props })}
|
|
56
63
|
<IconButton {...props}>
|
|
@@ -69,5 +76,3 @@
|
|
|
69
76
|
</BitDialog.Content>
|
|
70
77
|
</BitDialog.Portal>
|
|
71
78
|
</BitDialog.Root>
|
|
72
|
-
|
|
73
|
-
|
|
@@ -5,7 +5,7 @@ $d-max-h: calc(100dvh - $gap--x2);
|
|
|
5
5
|
$header-h: 48px;
|
|
6
6
|
$body-max-h: calc($d-max-h - $header-h);
|
|
7
7
|
|
|
8
|
-
[data-dialog-overlay] {
|
|
8
|
+
[data-celar-dialog-overlay] {
|
|
9
9
|
position: fixed;
|
|
10
10
|
top: 0;
|
|
11
11
|
left: 0;
|
|
@@ -16,7 +16,7 @@ $body-max-h: calc($d-max-h - $header-h);
|
|
|
16
16
|
z-index: 100;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
[data-dialog-content] {
|
|
19
|
+
[data-celar-dialog-content] {
|
|
20
20
|
box-sizing: border-box;
|
|
21
21
|
position: fixed;
|
|
22
22
|
top: calc(50dvh - $gap);
|
|
@@ -55,7 +55,7 @@ $body-max-h: calc($d-max-h - $header-h);
|
|
|
55
55
|
overflow: hidden;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
[data-dialog-title] {
|
|
58
|
+
[data-celar-dialog-title] {
|
|
59
59
|
overflow: hidden;
|
|
60
60
|
text-overflow: ellipsis;
|
|
61
61
|
white-space: nowrap;
|
|
@@ -66,4 +66,4 @@ $body-max-h: calc($d-max-h - $header-h);
|
|
|
66
66
|
max-height: $body-max-h;
|
|
67
67
|
overflow-y: auto;
|
|
68
68
|
padding: var(--gap);
|
|
69
|
-
}
|
|
69
|
+
}
|