compote-ui 0.80.0 → 0.81.1

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 (33) hide show
  1. package/dist/components/data-table-v9/column-filter-kind.d.ts +10 -1
  2. package/dist/components/data-table-v9/column-filter-kind.js +7 -0
  3. package/dist/components/data-table-v9/data-table-head.svelte +230 -230
  4. package/dist/components/data-table-v9/data-table.svelte +154 -154
  5. package/dist/components/data-table-v9/filter-editors/boolean-filter-editor.svelte +45 -45
  6. package/dist/components/data-table-v9/filter-editors/column-filter-editor.svelte +39 -33
  7. package/dist/components/data-table-v9/filter-editors/column-filter-editor.svelte.d.ts +7 -2
  8. package/dist/components/data-table-v9/filter-editors/date-range-filter-editor.svelte +52 -52
  9. package/dist/components/data-table-v9/filter-editors/range-filter-editor.svelte +51 -51
  10. package/dist/components/data-table-v9/filter-editors/select-filter-editor.svelte +59 -59
  11. package/dist/components/data-table-v9/filter-editors/text-filter-editor.svelte +20 -20
  12. package/dist/components/data-table-v9/header/column-header-filter.svelte +66 -66
  13. package/dist/components/data-table-v9/index.d.ts +9 -1
  14. package/dist/components/data-table-v9/index.js +7 -0
  15. package/dist/components/data-table-v9/toolbar/data-table-column-filter.svelte +203 -203
  16. package/dist/components/data-table-v9/toolbar/data-table-toolbar.svelte +4 -1
  17. package/dist/components/data-table-v9/types.d.ts +3 -1
  18. package/dist/components/data-table-v9/virtual/data-table-virtualized.svelte +82 -82
  19. package/dist/components/data-table-v9/virtual/index.d.ts +2 -2
  20. package/dist/components/data-table-v9/virtual/index.js +1 -1
  21. package/dist/components/dialog/alert-dialog.svelte +73 -73
  22. package/dist/components/dialog/dialog-root.svelte +45 -45
  23. package/dist/components/drawer/drawer-content.svelte +213 -213
  24. package/dist/components/popover/popover-content.svelte +97 -97
  25. package/dist/components/popover/popover-description.svelte +19 -19
  26. package/dist/components/popover/popover-root.svelte +27 -27
  27. package/dist/components/popover/popover-title.svelte +19 -19
  28. package/dist/icons/PhFunnelFill.svelte +19 -19
  29. package/package.json +1 -1
  30. package/skills/component-usage/references/overlays-and-floating-ui.md +278 -278
  31. package/skills/data-table/SKILL.md +362 -314
  32. package/skills/data-table/references/column-options.md +175 -175
  33. package/skills/data-table/references/table-state-and-reactivity.md +65 -65
@@ -1,73 +1,73 @@
1
- <script lang="ts">
2
- import { PhX } from '../../icons';
3
- import { Dialog } from '@ark-ui/svelte/dialog';
4
- import { Portal } from '@ark-ui/svelte/portal';
5
- import { releaseFocusOnExitProps } from '../../utils/release-focus-on-exit';
6
- import type { AlertDialogProps } from './dialog.types';
7
-
8
- let {
9
- open = $bindable(),
10
- title,
11
- description,
12
- confirmLabel = 'Confirm',
13
- cancelLabel = 'Cancel',
14
- onConfirm,
15
- onCancel,
16
- variant = 'default',
17
- lazyMount = true,
18
- unmountOnExit = true,
19
- ...restProps
20
- }: AlertDialogProps = $props();
21
-
22
- const confirmClass = $derived(
23
- variant === 'destructive'
24
- ? 'inline-flex h-9 items-center justify-center rounded-md bg-red-600 px-4 text-sm font-medium text-ink-inverse shadow-sm transition-colors hover:bg-red-700 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring'
25
- : 'inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-ink-inverse shadow-sm transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring'
26
- );
27
- </script>
28
-
29
- <Dialog.Root role="alertdialog" bind:open {lazyMount} {unmountOnExit} {...restProps}>
30
- <Portal>
31
- <Dialog.Backdrop
32
- class="fixed inset-0 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0"
33
- style="z-index: calc(50 + var(--layer-index, 0))"
34
- />
35
- <Dialog.Positioner
36
- class="fixed inset-0 flex items-center justify-center"
37
- style="z-index: calc(50 + var(--layer-index, 0))"
38
- >
39
- <Dialog.Content
40
- class="relative w-full max-w-md rounded-lg border bg-surface-1 p-6 shadow-xl data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95"
41
- {...releaseFocusOnExitProps}
42
- >
43
- <Dialog.Title class="text-lg leading-none font-semibold tracking-tight">
44
- {title}
45
- </Dialog.Title>
46
- {#if description}
47
- <Dialog.Description class="mt-2 text-sm text-ink-dim">
48
- {#each Array.isArray(description) ? description : [description] as line, i (i)}
49
- <span class="block">{line}</span>
50
- {/each}
51
- </Dialog.Description>
52
- {/if}
53
- <div class="mt-6 flex justify-end gap-3">
54
- <Dialog.CloseTrigger
55
- class="inline-flex h-9 items-center justify-center rounded-md border bg-surface-1 px-4 text-sm font-medium shadow-sm transition-colors hover:bg-surface-2 hover:text-ink focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none"
56
- onclick={onCancel}
57
- >
58
- {cancelLabel}
59
- </Dialog.CloseTrigger>
60
- <button type="button" class={confirmClass} onclick={onConfirm}>
61
- {confirmLabel}
62
- </button>
63
- </div>
64
- <Dialog.CloseTrigger
65
- class="absolute top-3 right-3 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none"
66
- >
67
- <PhX class="h-4 w-4" />
68
- <span class="sr-only">Close</span>
69
- </Dialog.CloseTrigger>
70
- </Dialog.Content>
71
- </Dialog.Positioner>
72
- </Portal>
73
- </Dialog.Root>
1
+ <script lang="ts">
2
+ import { PhX } from '../../icons';
3
+ import { Dialog } from '@ark-ui/svelte/dialog';
4
+ import { Portal } from '@ark-ui/svelte/portal';
5
+ import { releaseFocusOnExitProps } from '../../utils/release-focus-on-exit';
6
+ import type { AlertDialogProps } from './dialog.types';
7
+
8
+ let {
9
+ open = $bindable(),
10
+ title,
11
+ description,
12
+ confirmLabel = 'Confirm',
13
+ cancelLabel = 'Cancel',
14
+ onConfirm,
15
+ onCancel,
16
+ variant = 'default',
17
+ lazyMount = true,
18
+ unmountOnExit = true,
19
+ ...restProps
20
+ }: AlertDialogProps = $props();
21
+
22
+ const confirmClass = $derived(
23
+ variant === 'destructive'
24
+ ? 'inline-flex h-9 items-center justify-center rounded-md bg-red-600 px-4 text-sm font-medium text-ink-inverse shadow-sm transition-colors hover:bg-red-700 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring'
25
+ : 'inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-ink-inverse shadow-sm transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring'
26
+ );
27
+ </script>
28
+
29
+ <Dialog.Root role="alertdialog" bind:open {lazyMount} {unmountOnExit} {...restProps}>
30
+ <Portal>
31
+ <Dialog.Backdrop
32
+ class="fixed inset-0 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0"
33
+ style="z-index: calc(50 + var(--layer-index, 0))"
34
+ />
35
+ <Dialog.Positioner
36
+ class="fixed inset-0 flex items-center justify-center"
37
+ style="z-index: calc(50 + var(--layer-index, 0))"
38
+ >
39
+ <Dialog.Content
40
+ class="relative w-full max-w-md rounded-lg border bg-surface-1 p-6 shadow-xl data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95"
41
+ {...releaseFocusOnExitProps}
42
+ >
43
+ <Dialog.Title class="text-lg leading-none font-semibold tracking-tight">
44
+ {title}
45
+ </Dialog.Title>
46
+ {#if description}
47
+ <Dialog.Description class="mt-2 text-sm text-ink-dim">
48
+ {#each Array.isArray(description) ? description : [description] as line, i (i)}
49
+ <span class="block">{line}</span>
50
+ {/each}
51
+ </Dialog.Description>
52
+ {/if}
53
+ <div class="mt-6 flex justify-end gap-3">
54
+ <Dialog.CloseTrigger
55
+ class="inline-flex h-9 items-center justify-center rounded-md border bg-surface-1 px-4 text-sm font-medium shadow-sm transition-colors hover:bg-surface-2 hover:text-ink focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none"
56
+ onclick={onCancel}
57
+ >
58
+ {cancelLabel}
59
+ </Dialog.CloseTrigger>
60
+ <button type="button" class={confirmClass} onclick={onConfirm}>
61
+ {confirmLabel}
62
+ </button>
63
+ </div>
64
+ <Dialog.CloseTrigger
65
+ class="absolute top-3 right-3 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none"
66
+ >
67
+ <PhX class="h-4 w-4" />
68
+ <span class="sr-only">Close</span>
69
+ </Dialog.CloseTrigger>
70
+ </Dialog.Content>
71
+ </Dialog.Positioner>
72
+ </Portal>
73
+ </Dialog.Root>
@@ -1,45 +1,45 @@
1
- <script lang="ts">
2
- import { Dialog } from '@ark-ui/svelte/dialog';
3
- import { Portal } from '@ark-ui/svelte/portal';
4
- import { releaseFocusOnExitProps } from '../../utils/release-focus-on-exit';
5
- import { cn } from 'tailwind-variants';
6
- import type { DialogProps } from './dialog.types';
7
-
8
- let {
9
- open = $bindable(),
10
- children,
11
- contentClass,
12
- lazyMount = true,
13
- unmountOnExit = true,
14
- onOpenChange,
15
- ...restProps
16
- }: DialogProps = $props();
17
-
18
- function handleOpenChange(details: { open: boolean }) {
19
- open = details.open;
20
- onOpenChange?.(details);
21
- }
22
- </script>
23
-
24
- <Dialog.Root {open} {lazyMount} {unmountOnExit} onOpenChange={handleOpenChange} {...restProps}>
25
- <Portal>
26
- <Dialog.Backdrop
27
- class="fixed inset-0 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0"
28
- style="z-index: calc(50 + var(--layer-index, 0))"
29
- />
30
- <Dialog.Positioner
31
- class="fixed inset-0 flex items-center justify-center p-4"
32
- style="z-index: calc(50 + var(--layer-index, 0))"
33
- >
34
- <Dialog.Content
35
- class={cn(
36
- 'relative w-full max-w-2xl rounded-lg border bg-surface-1 p-6 shadow-xl data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
37
- contentClass
38
- )}
39
- {...releaseFocusOnExitProps}
40
- >
41
- {@render children()}
42
- </Dialog.Content>
43
- </Dialog.Positioner>
44
- </Portal>
45
- </Dialog.Root>
1
+ <script lang="ts">
2
+ import { Dialog } from '@ark-ui/svelte/dialog';
3
+ import { Portal } from '@ark-ui/svelte/portal';
4
+ import { releaseFocusOnExitProps } from '../../utils/release-focus-on-exit';
5
+ import { cn } from 'tailwind-variants';
6
+ import type { DialogProps } from './dialog.types';
7
+
8
+ let {
9
+ open = $bindable(),
10
+ children,
11
+ contentClass,
12
+ lazyMount = true,
13
+ unmountOnExit = true,
14
+ onOpenChange,
15
+ ...restProps
16
+ }: DialogProps = $props();
17
+
18
+ function handleOpenChange(details: { open: boolean }) {
19
+ open = details.open;
20
+ onOpenChange?.(details);
21
+ }
22
+ </script>
23
+
24
+ <Dialog.Root {open} {lazyMount} {unmountOnExit} onOpenChange={handleOpenChange} {...restProps}>
25
+ <Portal>
26
+ <Dialog.Backdrop
27
+ class="fixed inset-0 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0"
28
+ style="z-index: calc(50 + var(--layer-index, 0))"
29
+ />
30
+ <Dialog.Positioner
31
+ class="fixed inset-0 flex items-center justify-center p-4"
32
+ style="z-index: calc(50 + var(--layer-index, 0))"
33
+ >
34
+ <Dialog.Content
35
+ class={cn(
36
+ 'relative w-full max-w-2xl rounded-lg border bg-surface-1 p-6 shadow-xl data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
37
+ contentClass
38
+ )}
39
+ {...releaseFocusOnExitProps}
40
+ >
41
+ {@render children()}
42
+ </Dialog.Content>
43
+ </Dialog.Positioner>
44
+ </Portal>
45
+ </Dialog.Root>
@@ -1,213 +1,213 @@
1
- <script lang="ts">
2
- import { Drawer } from '@ark-ui/svelte/drawer';
3
- import type { DrawerContentBaseProps } from '@ark-ui/svelte/drawer';
4
- import type { ClassValue } from 'svelte/elements';
5
- import { cn } from 'tailwind-variants';
6
- import { releaseFocusOnExitProps } from '../../utils/release-focus-on-exit';
7
-
8
- interface Props extends DrawerContentBaseProps {
9
- class?: ClassValue;
10
- backdropClass?: ClassValue;
11
- positionerClass?: ClassValue;
12
- maxWidth?: string;
13
- maxHeight?: string;
14
- }
15
-
16
- let {
17
- class: className,
18
- backdropClass,
19
- positionerClass,
20
- maxWidth,
21
- maxHeight,
22
- children,
23
- draggable = false,
24
- ...rest
25
- }: Props = $props();
26
- </script>
27
-
28
- <Drawer.Backdrop
29
- class={cn(
30
- 'fixed inset-0 z-50 bg-black/50',
31
- 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0',
32
- 'data-[state=open]:animate-in data-[state=open]:fade-in-0',
33
- backdropClass
34
- )}
35
- />
36
- <Drawer.Positioner
37
- class={cn(
38
- 'fixed inset-0 z-50 flex items-end justify-center',
39
- 'data-[swipe-direction=left]:items-stretch data-[swipe-direction=left]:justify-start',
40
- 'data-[swipe-direction=right]:items-stretch data-[swipe-direction=right]:justify-end',
41
- 'data-[swipe-direction=up]:items-start',
42
- positionerClass
43
- )}
44
- >
45
- <Drawer.Content
46
- {...rest}
47
- {draggable}
48
- style={[
49
- maxWidth && `--drawer-max-width:${maxWidth}`,
50
- maxHeight && `--drawer-max-height:${maxHeight}`
51
- ]
52
- .filter(Boolean)
53
- .join(';')}
54
- class={cn(
55
- 'pointer-events-auto relative flex h-full w-full flex-col bg-surface-1 shadow-xl outline-none',
56
- className
57
- )}
58
- {...releaseFocusOnExitProps}
59
- >
60
- {@render children?.()}
61
- </Drawer.Content>
62
- </Drawer.Positioner>
63
-
64
- <style>
65
- /* Side drawers: grabber becomes an absolutely-positioned vertical strip on the open edge */
66
- :global(
67
- [data-scope='drawer'][data-part='content'][data-swipe-direction='left']
68
- [data-scope='drawer'][data-part='grabber'],
69
- [data-scope='drawer'][data-part='content'][data-swipe-direction='right']
70
- [data-scope='drawer'][data-part='grabber']
71
- ) {
72
- position: absolute;
73
- top: 0;
74
- bottom: 0;
75
- width: auto;
76
- height: 100%;
77
- padding: 0 0.75rem;
78
- }
79
-
80
- :global(
81
- [data-scope='drawer'][data-part='content'][data-swipe-direction='left']
82
- [data-scope='drawer'][data-part='grabber']
83
- ) {
84
- right: 0;
85
- }
86
-
87
- :global(
88
- [data-scope='drawer'][data-part='content'][data-swipe-direction='right']
89
- [data-scope='drawer'][data-part='grabber']
90
- ) {
91
- left: 0;
92
- }
93
-
94
- :global(
95
- [data-scope='drawer'][data-part='content'][data-swipe-direction='left']
96
- [data-scope='drawer'][data-part='grabber-indicator'],
97
- [data-scope='drawer'][data-part='content'][data-swipe-direction='right']
98
- [data-scope='drawer'][data-part='grabber-indicator']
99
- ) {
100
- width: 4px;
101
- height: 2.5rem;
102
- }
103
-
104
- /* Bottom/top drawers: cap height, overridable via --drawer-max-height */
105
- :global(
106
- [data-scope='drawer'][data-part='content']:not([data-swipe-direction]),
107
- [data-scope='drawer'][data-part='content'][data-swipe-direction='down'],
108
- [data-scope='drawer'][data-part='content'][data-swipe-direction='up']
109
- ) {
110
- max-height: var(--drawer-max-height, 96svh);
111
- }
112
-
113
- /* Side drawers: constrain width, remove height cap — overridable via --drawer-max-width */
114
- :global(
115
- [data-scope='drawer'][data-part='content'][data-swipe-direction='left'],
116
- [data-scope='drawer'][data-part='content'][data-swipe-direction='right']
117
- ) {
118
- max-width: var(--drawer-max-width, 25rem);
119
- max-height: none;
120
- }
121
-
122
- /* Bleed pseudo-element so background extends past rounded corners on the open edge */
123
- :global([data-scope='drawer'][data-part='content'])::after {
124
- content: '';
125
- position: absolute;
126
- left: 0;
127
- right: 0;
128
- top: 100%;
129
- height: 50px;
130
- background: inherit;
131
- pointer-events: none;
132
- }
133
-
134
- :global([data-scope='drawer'][data-part='content'][data-swipe-direction='up'])::after {
135
- top: auto;
136
- bottom: 100%;
137
- }
138
-
139
- :global([data-scope='drawer'][data-part='content'][data-swipe-direction='left'])::after {
140
- top: 0;
141
- bottom: 0;
142
- left: auto;
143
- right: 100%;
144
- width: 50px;
145
- height: auto;
146
- }
147
-
148
- :global([data-scope='drawer'][data-part='content'][data-swipe-direction='right'])::after {
149
- top: 0;
150
- bottom: 0;
151
- right: auto;
152
- left: 100%;
153
- width: 50px;
154
- height: auto;
155
- }
156
-
157
- :global([data-scope='drawer'][data-part='content'][data-state='open']) {
158
- animation-name: enter;
159
- animation-duration: 500ms;
160
- animation-fill-mode: both;
161
- }
162
- :global([data-scope='drawer'][data-part='content'][data-state='closed']) {
163
- animation-name: exit;
164
- animation-duration: 300ms;
165
- animation-fill-mode: both;
166
- }
167
-
168
- :global(
169
- [data-scope='drawer'][data-part='content']:not([data-swipe-direction])[data-state='open'],
170
- [data-scope='drawer'][data-part='content'][data-swipe-direction='down'][data-state='open']
171
- ) {
172
- --tw-enter-translate-y: 100%;
173
- }
174
- :global(
175
- [data-scope='drawer'][data-part='content']:not([data-swipe-direction])[data-state='closed'],
176
- [data-scope='drawer'][data-part='content'][data-swipe-direction='down'][data-state='closed']
177
- ) {
178
- --tw-exit-translate-y: 100%;
179
- }
180
-
181
- :global(
182
- [data-scope='drawer'][data-part='content'][data-swipe-direction='up'][data-state='open']
183
- ) {
184
- --tw-enter-translate-y: -100%;
185
- }
186
- :global(
187
- [data-scope='drawer'][data-part='content'][data-swipe-direction='up'][data-state='closed']
188
- ) {
189
- --tw-exit-translate-y: -100%;
190
- }
191
-
192
- :global(
193
- [data-scope='drawer'][data-part='content'][data-swipe-direction='left'][data-state='open']
194
- ) {
195
- --tw-enter-translate-x: -100%;
196
- }
197
- :global(
198
- [data-scope='drawer'][data-part='content'][data-swipe-direction='left'][data-state='closed']
199
- ) {
200
- --tw-exit-translate-x: -100%;
201
- }
202
-
203
- :global(
204
- [data-scope='drawer'][data-part='content'][data-swipe-direction='right'][data-state='open']
205
- ) {
206
- --tw-enter-translate-x: 100%;
207
- }
208
- :global(
209
- [data-scope='drawer'][data-part='content'][data-swipe-direction='right'][data-state='closed']
210
- ) {
211
- --tw-exit-translate-x: 100%;
212
- }
213
- </style>
1
+ <script lang="ts">
2
+ import { Drawer } from '@ark-ui/svelte/drawer';
3
+ import type { DrawerContentBaseProps } from '@ark-ui/svelte/drawer';
4
+ import type { ClassValue } from 'svelte/elements';
5
+ import { cn } from 'tailwind-variants';
6
+ import { releaseFocusOnExitProps } from '../../utils/release-focus-on-exit';
7
+
8
+ interface Props extends DrawerContentBaseProps {
9
+ class?: ClassValue;
10
+ backdropClass?: ClassValue;
11
+ positionerClass?: ClassValue;
12
+ maxWidth?: string;
13
+ maxHeight?: string;
14
+ }
15
+
16
+ let {
17
+ class: className,
18
+ backdropClass,
19
+ positionerClass,
20
+ maxWidth,
21
+ maxHeight,
22
+ children,
23
+ draggable = false,
24
+ ...rest
25
+ }: Props = $props();
26
+ </script>
27
+
28
+ <Drawer.Backdrop
29
+ class={cn(
30
+ 'fixed inset-0 z-50 bg-black/50',
31
+ 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0',
32
+ 'data-[state=open]:animate-in data-[state=open]:fade-in-0',
33
+ backdropClass
34
+ )}
35
+ />
36
+ <Drawer.Positioner
37
+ class={cn(
38
+ 'fixed inset-0 z-50 flex items-end justify-center',
39
+ 'data-[swipe-direction=left]:items-stretch data-[swipe-direction=left]:justify-start',
40
+ 'data-[swipe-direction=right]:items-stretch data-[swipe-direction=right]:justify-end',
41
+ 'data-[swipe-direction=up]:items-start',
42
+ positionerClass
43
+ )}
44
+ >
45
+ <Drawer.Content
46
+ {...rest}
47
+ {draggable}
48
+ style={[
49
+ maxWidth && `--drawer-max-width:${maxWidth}`,
50
+ maxHeight && `--drawer-max-height:${maxHeight}`
51
+ ]
52
+ .filter(Boolean)
53
+ .join(';')}
54
+ class={cn(
55
+ 'pointer-events-auto relative flex h-full w-full flex-col bg-surface-1 shadow-xl outline-none',
56
+ className
57
+ )}
58
+ {...releaseFocusOnExitProps}
59
+ >
60
+ {@render children?.()}
61
+ </Drawer.Content>
62
+ </Drawer.Positioner>
63
+
64
+ <style>
65
+ /* Side drawers: grabber becomes an absolutely-positioned vertical strip on the open edge */
66
+ :global(
67
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='left']
68
+ [data-scope='drawer'][data-part='grabber'],
69
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='right']
70
+ [data-scope='drawer'][data-part='grabber']
71
+ ) {
72
+ position: absolute;
73
+ top: 0;
74
+ bottom: 0;
75
+ width: auto;
76
+ height: 100%;
77
+ padding: 0 0.75rem;
78
+ }
79
+
80
+ :global(
81
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='left']
82
+ [data-scope='drawer'][data-part='grabber']
83
+ ) {
84
+ right: 0;
85
+ }
86
+
87
+ :global(
88
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='right']
89
+ [data-scope='drawer'][data-part='grabber']
90
+ ) {
91
+ left: 0;
92
+ }
93
+
94
+ :global(
95
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='left']
96
+ [data-scope='drawer'][data-part='grabber-indicator'],
97
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='right']
98
+ [data-scope='drawer'][data-part='grabber-indicator']
99
+ ) {
100
+ width: 4px;
101
+ height: 2.5rem;
102
+ }
103
+
104
+ /* Bottom/top drawers: cap height, overridable via --drawer-max-height */
105
+ :global(
106
+ [data-scope='drawer'][data-part='content']:not([data-swipe-direction]),
107
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='down'],
108
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='up']
109
+ ) {
110
+ max-height: var(--drawer-max-height, 96svh);
111
+ }
112
+
113
+ /* Side drawers: constrain width, remove height cap — overridable via --drawer-max-width */
114
+ :global(
115
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='left'],
116
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='right']
117
+ ) {
118
+ max-width: var(--drawer-max-width, 25rem);
119
+ max-height: none;
120
+ }
121
+
122
+ /* Bleed pseudo-element so background extends past rounded corners on the open edge */
123
+ :global([data-scope='drawer'][data-part='content'])::after {
124
+ content: '';
125
+ position: absolute;
126
+ left: 0;
127
+ right: 0;
128
+ top: 100%;
129
+ height: 50px;
130
+ background: inherit;
131
+ pointer-events: none;
132
+ }
133
+
134
+ :global([data-scope='drawer'][data-part='content'][data-swipe-direction='up'])::after {
135
+ top: auto;
136
+ bottom: 100%;
137
+ }
138
+
139
+ :global([data-scope='drawer'][data-part='content'][data-swipe-direction='left'])::after {
140
+ top: 0;
141
+ bottom: 0;
142
+ left: auto;
143
+ right: 100%;
144
+ width: 50px;
145
+ height: auto;
146
+ }
147
+
148
+ :global([data-scope='drawer'][data-part='content'][data-swipe-direction='right'])::after {
149
+ top: 0;
150
+ bottom: 0;
151
+ right: auto;
152
+ left: 100%;
153
+ width: 50px;
154
+ height: auto;
155
+ }
156
+
157
+ :global([data-scope='drawer'][data-part='content'][data-state='open']) {
158
+ animation-name: enter;
159
+ animation-duration: 500ms;
160
+ animation-fill-mode: both;
161
+ }
162
+ :global([data-scope='drawer'][data-part='content'][data-state='closed']) {
163
+ animation-name: exit;
164
+ animation-duration: 300ms;
165
+ animation-fill-mode: both;
166
+ }
167
+
168
+ :global(
169
+ [data-scope='drawer'][data-part='content']:not([data-swipe-direction])[data-state='open'],
170
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='down'][data-state='open']
171
+ ) {
172
+ --tw-enter-translate-y: 100%;
173
+ }
174
+ :global(
175
+ [data-scope='drawer'][data-part='content']:not([data-swipe-direction])[data-state='closed'],
176
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='down'][data-state='closed']
177
+ ) {
178
+ --tw-exit-translate-y: 100%;
179
+ }
180
+
181
+ :global(
182
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='up'][data-state='open']
183
+ ) {
184
+ --tw-enter-translate-y: -100%;
185
+ }
186
+ :global(
187
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='up'][data-state='closed']
188
+ ) {
189
+ --tw-exit-translate-y: -100%;
190
+ }
191
+
192
+ :global(
193
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='left'][data-state='open']
194
+ ) {
195
+ --tw-enter-translate-x: -100%;
196
+ }
197
+ :global(
198
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='left'][data-state='closed']
199
+ ) {
200
+ --tw-exit-translate-x: -100%;
201
+ }
202
+
203
+ :global(
204
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='right'][data-state='open']
205
+ ) {
206
+ --tw-enter-translate-x: 100%;
207
+ }
208
+ :global(
209
+ [data-scope='drawer'][data-part='content'][data-swipe-direction='right'][data-state='closed']
210
+ ) {
211
+ --tw-exit-translate-x: 100%;
212
+ }
213
+ </style>