@ims360/svelte-ivory 0.1.13 → 0.1.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.
Files changed (25) hide show
  1. package/dist/components/inputs/FullscreenDropzone.svelte +4 -6
  2. package/dist/components/inputs/FullscreenDropzone.svelte.d.ts.map +1 -1
  3. package/dist/components/layout/dialog/Dialog.svelte +2 -2
  4. package/dist/components/layout/drawer/Drawer.svelte +35 -37
  5. package/dist/components/layout/drawer/Drawer.svelte.d.ts.map +1 -1
  6. package/dist/components/layout/hiddenBackground/HiddenBackground.svelte +7 -45
  7. package/dist/components/layout/hiddenBackground/HiddenBackground.svelte.d.ts +2 -8
  8. package/dist/components/layout/hiddenBackground/HiddenBackground.svelte.d.ts.map +1 -1
  9. package/dist/components/layout/modal/Modal.svelte +56 -64
  10. package/dist/components/layout/modal/Modal.svelte.d.ts.map +1 -1
  11. package/dist/components/layout/popover/Popover.svelte +5 -15
  12. package/dist/components/layout/popover/Popover.svelte.d.ts +0 -2
  13. package/dist/components/layout/popover/Popover.svelte.d.ts.map +1 -1
  14. package/dist/components/table/VirtualList.svelte +20 -23
  15. package/dist/theme.svelte.d.ts +3 -0
  16. package/dist/theme.svelte.d.ts.map +1 -1
  17. package/package.json +1 -1
  18. package/src/lib/components/inputs/FullscreenDropzone.svelte +4 -6
  19. package/src/lib/components/layout/dialog/Dialog.svelte +2 -2
  20. package/src/lib/components/layout/drawer/Drawer.svelte +35 -37
  21. package/src/lib/components/layout/hiddenBackground/HiddenBackground.svelte +7 -45
  22. package/src/lib/components/layout/modal/Modal.svelte +56 -64
  23. package/src/lib/components/layout/popover/Popover.svelte +5 -15
  24. package/src/lib/components/table/VirtualList.svelte +20 -23
  25. package/src/lib/theme.svelte.ts +3 -0
@@ -2,7 +2,7 @@
2
2
  import { FileUp } from '@lucide/svelte';
3
3
  import type { Snippet } from 'svelte';
4
4
  import { scale } from 'svelte/transition';
5
- import { HiddenBackground, Portal } from '../layout';
5
+ import { HiddenBackground } from '../layout';
6
6
 
7
7
  export interface FullscreenDropzoneProps {
8
8
  ondrop: (files: File[]) => void;
@@ -64,11 +64,9 @@
64
64
  />
65
65
 
66
66
  {#if open}
67
- <Portal>
68
- <HiddenBackground class="flex items-center justify-center">
69
- {@render children()}
70
- </HiddenBackground>
71
- </Portal>
67
+ <HiddenBackground class="flex items-center justify-center">
68
+ {@render children()}
69
+ </HiddenBackground>
72
70
  {/if}
73
71
 
74
72
  {#snippet defaultChildren()}
@@ -1 +1 @@
1
- {"version":3,"file":"FullscreenDropzone.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputs/FullscreenDropzone.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,WAAW,uBAAuB;IACpC,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAoEL,QAAA,MAAM,kBAAkB,6DAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"FullscreenDropzone.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputs/FullscreenDropzone.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,WAAW,uBAAuB;IACpC,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAkEL,QAAA,MAAM,kBAAkB,6DAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -63,8 +63,8 @@
63
63
  onclose={close}
64
64
  class={twMerge(
65
65
  clsx(
66
- 'h-full max-h-none w-screen max-w-full bg-transparent backdrop:bg-black/20',
67
- theme.current.hiddenBackground?.class,
66
+ 'h-full max-h-none w-screen max-w-full bg-transparent backdrop:bg-transparent',
67
+ theme.current.dialog?.class,
68
68
  clazz
69
69
  )
70
70
  )}
@@ -5,7 +5,7 @@
5
5
  import type { Snippet } from 'svelte';
6
6
  import { fly } from 'svelte/transition';
7
7
  import { twMerge } from 'tailwind-merge';
8
- import { HiddenBackground, Portal } from '..';
8
+ import { HiddenBackground } from '..';
9
9
  import Heading from '../Heading.svelte';
10
10
 
11
11
  export type DrawerPlacement = 'left' | 'right';
@@ -52,42 +52,40 @@
52
52
  </script>
53
53
 
54
54
  {#if currentlyOpen}
55
- <Portal>
56
- <HiddenBackground
57
- onclose={() => {
58
- if (closeOnOutsideClick) close();
59
- }}
55
+ <HiddenBackground
56
+ onclose={() => {
57
+ if (closeOnOutsideClick) close();
58
+ }}
59
+ >
60
+ <div
61
+ class={twMerge(
62
+ clsx([
63
+ 'bg-surface-50-950 absolute top-0 flex h-full flex-col gap-4 p-4',
64
+ placement === 'left' && 'left-0',
65
+ placement === 'right' && 'right-0',
66
+ clazz
67
+ ])
68
+ )}
69
+ onclick={(e) => e.stopPropagation()}
70
+ in:inTransition|global
71
+ out:outTransition|global
72
+ {...rest}
60
73
  >
61
- <div
62
- class={twMerge(
63
- clsx([
64
- 'bg-surface-50-950 absolute top-0 flex h-full flex-col gap-4 p-4',
65
- placement === 'left' && 'left-0',
66
- placement === 'right' && 'right-0',
67
- clazz
68
- ])
69
- )}
70
- onclick={(e) => e.stopPropagation()}
71
- in:inTransition|global
72
- out:outTransition|global
73
- {...rest}
74
- >
75
- <div class="flex flex-row items-center justify-between gap-8">
76
- {#if title}
77
- <Heading class="flex grow flex-row items-center gap-4">
78
- {#if typeof title === 'function'}
79
- {@render title()}
80
- {:else}
81
- {title}
82
- {/if}
83
- </Heading>
84
- {/if}
85
- <button class="group ml-auto flex justify-end" type="button" onclick={close}>
86
- <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
87
- </button>
88
- </div>
89
- {@render children()}
74
+ <div class="flex flex-row items-center justify-between gap-8">
75
+ {#if title}
76
+ <Heading class="flex grow flex-row items-center gap-4">
77
+ {#if typeof title === 'function'}
78
+ {@render title()}
79
+ {:else}
80
+ {title}
81
+ {/if}
82
+ </Heading>
83
+ {/if}
84
+ <button class="group ml-auto flex justify-end" type="button" onclick={close}>
85
+ <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
86
+ </button>
90
87
  </div>
91
- </HiddenBackground>
92
- </Portal>
88
+ {@render children()}
89
+ </div>
90
+ </HiddenBackground>
93
91
  {/if}
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/drawer/Drawer.svelte.ts"],"names":[],"mappings":"AAGI,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAMtC,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAuEN,QAAA,MAAM,MAAM;;;;;MAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Drawer.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/drawer/Drawer.svelte.ts"],"names":[],"mappings":"AAGI,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAMtC,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAqEN,QAAA,MAAM,MAAM;;;;;MAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
@@ -1,51 +1,13 @@
1
- <script lang="ts" module>
2
- import type { IvoryComponent, TransitionProps } from '../../../types';
3
- import clsx from 'clsx';
4
- import type { ClassValue } from 'svelte/elements';
5
- import { fade } from 'svelte/transition';
6
- import { twMerge } from 'tailwind-merge';
7
- import { focusTrap, shortcut } from '../../../utils/actions/index';
8
-
9
- let globalClass = $state<ClassValue>();
10
-
11
- export function setClasses(value: ClassValue) {
12
- globalClass = value;
13
- }
14
-
15
- export interface HiddenBackgroundProps extends IvoryComponent<HTMLDivElement>, TransitionProps {
16
- /** Gets called when the dialog is clicked */
17
- onclose?: () => void;
18
- }
19
- </script>
20
-
21
1
  <script lang="ts">
2
+ import { theme } from '../../../theme.svelte';
3
+ import type { DialogProps } from '../dialog';
4
+ import Dialog from '../dialog/Dialog.svelte';
5
+
22
6
  let {
23
7
  class: clazz,
24
- onclose,
25
- children,
26
- inTransition = (e) => fade(e, { duration: 200 }),
27
- outTransition = (e) => fade(e, { duration: 100 }),
8
+
28
9
  ...rest
29
- }: HiddenBackgroundProps = $props();
10
+ }: DialogProps = $props();
30
11
  </script>
31
12
 
32
- <div
33
- class={twMerge(
34
- clsx(
35
- 'bg-surface-950-50/40 pointer-events-auto absolute top-0 left-0 m-0 h-full w-full p-0',
36
- globalClass,
37
- clazz
38
- )
39
- )}
40
- use:focusTrap={true}
41
- {@attach shortcut({
42
- code: 'Escape',
43
- callback: onclose ?? (() => {})
44
- })}
45
- onclick={onclose}
46
- in:inTransition
47
- out:outTransition
48
- {...rest}
49
- >
50
- {@render children?.()}
51
- </div>
13
+ <Dialog {...rest} class={['bg-surface-950-50/40', theme.current.hiddenBackground?.class, clazz]} />
@@ -1,11 +1,5 @@
1
- import type { IvoryComponent, TransitionProps } from '../../../types';
2
- import type { ClassValue } from 'svelte/elements';
3
- export declare function setClasses(value: ClassValue): void;
4
- export interface HiddenBackgroundProps extends IvoryComponent<HTMLDivElement>, TransitionProps {
5
- /** Gets called when the dialog is clicked */
6
- onclose?: () => void;
7
- }
8
- declare const HiddenBackground: import("svelte").Component<HiddenBackgroundProps, {}, "">;
1
+ import type { DialogProps } from '../dialog';
2
+ declare const HiddenBackground: import("svelte").Component<DialogProps, {}, "">;
9
3
  type HiddenBackground = ReturnType<typeof HiddenBackground>;
10
4
  export default HiddenBackground;
11
5
  //# sourceMappingURL=HiddenBackground.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"HiddenBackground.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/hiddenBackground/HiddenBackground.svelte.ts"],"names":[],"mappings":"AAGI,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,QAE3C;AAED,MAAM,WAAW,qBAAsB,SAAQ,cAAc,CAAC,cAAc,CAAC,EAAE,eAAe;IAC1F,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AA8BL,QAAA,MAAM,gBAAgB,2DAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"HiddenBackground.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/hiddenBackground/HiddenBackground.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAmB7C,QAAA,MAAM,gBAAgB,iDAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -7,7 +7,7 @@
7
7
  import type { ClassValue, MouseEventHandler } from 'svelte/elements';
8
8
  import { fade } from 'svelte/transition';
9
9
  import { twMerge } from 'tailwind-merge';
10
- import { Heading, HiddenBackground, Portal } from '..';
10
+ import { Heading, HiddenBackground } from '..';
11
11
 
12
12
  /** Props for the modal, expose if you overwrite the defaults in a custom component */
13
13
  export type ModalProps = TransitionProps & {
@@ -83,73 +83,65 @@
83
83
  A modal, comes with a title, close button and different variants per default.
84
84
  -->
85
85
  {#if currentlyOpen}
86
- <Portal>
87
- <HiddenBackground
88
- onclose={() => {
89
- if (closeOnOutsideClick) close();
90
- }}
91
- class="flex h-full w-full flex-col items-center justify-start p-8 lg:p-12 xl:p-16"
92
- >
93
- {#if modal}
94
- <div {...rest} {onclick}>
95
- {@render modal()}
86
+ <HiddenBackground
87
+ onclose={() => {
88
+ if (closeOnOutsideClick) close();
89
+ }}
90
+ class="flex h-full w-full flex-col items-center justify-start p-8 lg:p-12 xl:p-16"
91
+ >
92
+ {#if modal}
93
+ <div {...rest} {onclick}>
94
+ {@render modal()}
95
+ </div>
96
+ {:else}
97
+ <div
98
+ class={twMerge(
99
+ clsx([
100
+ 'bg-surface-50-950 relative flex max-h-full max-w-full flex-col overflow-hidden rounded',
101
+ theme.current.modal?.class,
102
+ clazz
103
+ ])
104
+ )}
105
+ {...rest}
106
+ {onclick}
107
+ in:inTransition|global
108
+ out:outTransition|global
109
+ >
110
+ <div
111
+ class={[
112
+ 'flex flex-row items-center justify-between gap-4 px-4 py-3',
113
+ !variant && 'pb-0',
114
+ variant === 'success' && 'preset-tonal-success',
115
+ variant === 'warning' && 'preset-tonal-warning',
116
+ variant === 'error' && 'preset-tonal-error',
117
+ variant === 'info' && 'preset-tonal-primary'
118
+ ]}
119
+ >
120
+ {#if title}
121
+ <Heading class="flex grow flex-row items-center gap-4">
122
+ {#if typeof title === 'function'}
123
+ {@render title()}
124
+ {:else}
125
+ {title}
126
+ {/if}
127
+ </Heading>
128
+ {/if}
129
+ <button class="group ml-auto flex justify-end" type="button" onclick={close}>
130
+ <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
131
+ </button>
96
132
  </div>
97
- {:else}
98
133
  <div
99
134
  class={twMerge(
100
- clsx([
101
- 'bg-surface-50-950 relative flex max-h-full max-w-full flex-col overflow-hidden rounded',
102
- theme.current.modal?.class,
103
- clazz
104
- ])
135
+ clsx(
136
+ 'flex grow flex-col gap-4 overflow-hidden bg-inherit p-4 pt-3',
137
+ theme.current.modal?.innerClass,
138
+ innerClass
139
+ )
105
140
  )}
106
- {...rest}
107
- {onclick}
108
- in:inTransition|global
109
- out:outTransition|global
110
141
  >
111
- <div
112
- class={[
113
- 'flex flex-row items-center justify-between gap-4 px-4 py-3',
114
- !variant && 'pb-0',
115
- variant === 'success' && 'preset-tonal-success',
116
- variant === 'warning' && 'preset-tonal-warning',
117
- variant === 'error' && 'preset-tonal-error',
118
- variant === 'info' && 'preset-tonal-primary'
119
- ]}
120
- >
121
- {#if title}
122
- <Heading class="flex grow flex-row items-center gap-4">
123
- {#if typeof title === 'function'}
124
- {@render title()}
125
- {:else}
126
- {title}
127
- {/if}
128
- </Heading>
129
- {/if}
130
- <button
131
- class="group ml-auto flex justify-end"
132
- type="button"
133
- onclick={close}
134
- >
135
- <X
136
- class="h-full w-auto transition-[stroke-width] group-hover:stroke-3"
137
- />
138
- </button>
139
- </div>
140
- <div
141
- class={twMerge(
142
- clsx(
143
- 'flex grow flex-col gap-4 overflow-hidden bg-inherit p-4 pt-3',
144
- theme.current.modal?.innerClass,
145
- innerClass
146
- )
147
- )}
148
- >
149
- {@render children?.()}
150
- </div>
142
+ {@render children?.()}
151
143
  </div>
152
- {/if}
153
- </HiddenBackground>
154
- </Portal>
144
+ </div>
145
+ {/if}
146
+ </HiddenBackground>
155
147
  {/if}
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/modal/Modal.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKrE,sFAAsF;AACtF,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG;IACvC,iEAAiE;IACjE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;SAIK;IACL,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,0DAA0D;IAC1D,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpE,UAAU,KAAM,SAAQ,UAAU;IAC9B,sGAAsG;IACtG,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAsGL,oFAAoF;AACpF,QAAA,MAAM,KAAK;;;;;MAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Modal.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/modal/Modal.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKrE,sFAAsF;AACtF,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG;IACvC,iEAAiE;IACjE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;SAIK;IACL,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,0DAA0D;IAC1D,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpE,UAAU,KAAM,SAAQ,UAAU;IAC9B,sGAAsG;IACtG,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAoGL,oFAAoF;AACpF,QAAA,MAAM,KAAK;;;;;MAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
@@ -13,7 +13,7 @@
13
13
  import clsx from 'clsx';
14
14
  import { twMerge } from 'tailwind-merge';
15
15
  import { clickOutside } from '../../../utils/actions/clickOutside';
16
- import Portal from '../portal/Portal.svelte';
16
+ import { Dialog } from '../dialog';
17
17
 
18
18
  /** Possible placements for the popover */
19
19
  export type PopoverPlacement = ComputePositionConfig['placement'];
@@ -31,8 +31,6 @@
31
31
  * Callback that is called when the user clicks outside the popover or the target element.
32
32
  */
33
33
  onClickOutside?: (e: MouseEvent) => void;
34
- /** If set to `true`, the nested component will not be unmounted when the popover is closed */
35
- keepMounted?: boolean;
36
34
  /**
37
35
  * Whether to place the popover automatically
38
36
  *
@@ -49,7 +47,6 @@
49
47
  target,
50
48
  placement = 'bottom-start',
51
49
  onClickOutside = close,
52
- keepMounted = false,
53
50
  children,
54
51
  autoplacement,
55
52
  ...rest
@@ -101,17 +98,10 @@
101
98
  @component
102
99
  A popover, positions itself relative to a target element.
103
100
  -->
104
- {#if currentlyOpen || keepMounted}
105
- <Portal>
101
+ {#if currentlyOpen}
102
+ <Dialog>
106
103
  <div
107
- class={twMerge(
108
- clsx(
109
- 'absolute',
110
- theme.current.popover?.class,
111
- !keepMounted && clazz,
112
- keepMounted && !currentlyOpen ? 'hidden' : clazz
113
- )
114
- )}
104
+ class={twMerge(clsx('absolute', theme.current.popover?.class, clazz))}
115
105
  style={style + ' ' + externalStyle}
116
106
  bind:this={popover}
117
107
  use:clickOutside={{ callback: onClickOutside, target }}
@@ -119,5 +109,5 @@
119
109
  >
120
110
  {@render children?.()}
121
111
  </div>
122
- </Portal>
112
+ </Dialog>
123
113
  {/if}
@@ -15,8 +15,6 @@ export interface PopoverProps extends IvoryComponent<HTMLDivElement> {
15
15
  * Callback that is called when the user clicks outside the popover or the target element.
16
16
  */
17
17
  onClickOutside?: (e: MouseEvent) => void;
18
- /** If set to `true`, the nested component will not be unmounted when the popover is closed */
19
- keepMounted?: boolean;
20
18
  /**
21
19
  * Whether to place the popover automatically
22
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/popover/Popover.svelte.ts"],"names":[],"mappings":"AAKI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAMH,KAAK,qBAAqB,EAC7B,MAAM,kBAAkB,CAAC;AAM1B,0CAA0C;AAC1C,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;AAElE,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,cAAc,CAAC;IAChE,6DAA6D;IAC7D,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC,8FAA8F;IAC9F,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AA6EL,gEAAgE;AAChE,QAAA,MAAM,OAAO;;;;;MAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"Popover.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/popover/Popover.svelte.ts"],"names":[],"mappings":"AAKI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAMH,KAAK,qBAAqB,EAC7B,MAAM,kBAAkB,CAAC;AAM1B,0CAA0C;AAC1C,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;AAElE,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,cAAc,CAAC;IAChE,6DAA6D;IAC7D,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAqEL,gEAAgE;AAChE,QAAA,MAAM,OAAO;;;;;MAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -38,7 +38,16 @@
38
38
  let viewport_height = $state(0);
39
39
 
40
40
  export function scrollTo(top?: number, left?: number) {
41
- onscroll(top, left);
41
+ if (!viewport) return;
42
+ if (top !== undefined) {
43
+ scroll_top = top;
44
+ viewport.scrollTop = top;
45
+ b_scrollTop = top;
46
+ }
47
+ if (left !== undefined) {
48
+ scroll_left = left;
49
+ viewport.scrollLeft = left;
50
+ }
42
51
  }
43
52
 
44
53
  const start = $derived(Math.max(0, Math.floor(scroll_top / rowHeight) - overscan));
@@ -56,26 +65,16 @@
56
65
  const top = $derived(start * rowHeight);
57
66
  const bottom = $derived((data.length - end) * rowHeight);
58
67
 
59
- async function onscroll(top?: number, left?: number, retry = true) {
68
+ async function onscroll() {
60
69
  if (!viewport) {
61
70
  viewportReactivity++;
62
71
  await tick();
63
- if (retry) await onscroll(top, left, false);
72
+ onscroll();
64
73
  return;
65
74
  }
66
- if (typeof top !== 'undefined') {
67
- scroll_top = top;
68
- viewport.scrollTop = top;
69
- } else {
70
- scroll_top = viewport.scrollTop;
71
- b_scrollTop = scroll_top;
72
- }
73
- if (typeof left !== 'undefined') {
74
- scroll_left = left;
75
- viewport.scrollLeft = left;
76
- } else {
77
- scroll_left = viewport.scrollLeft;
78
- }
75
+ scroll_top = viewport.scrollTop;
76
+ scroll_left = viewport.scrollLeft;
77
+ b_scrollTop = scroll_top;
79
78
  }
80
79
 
81
80
  // update the scrolltop when the prop value changes
@@ -88,7 +87,8 @@
88
87
  }
89
88
  });
90
89
 
91
- onMount(() => {
90
+ onMount(async () => {
91
+ await tick();
92
92
  onscroll();
93
93
  });
94
94
  </script>
@@ -114,23 +114,20 @@
114
114
  class="flex min-w-full! grow overflow-auto [scrollbar-gutter:stable]"
115
115
  bind:this={viewport}
116
116
  bind:offsetHeight={viewport_height}
117
- onscroll={() => onscroll()}
117
+ {onscroll}
118
118
  >
119
119
  <div
120
120
  class="flex h-fit shrink-0 flex-col"
121
121
  style="padding-top: {top}px; padding-bottom: {bottom}px; min-width: max(100%, {header_width}px) !important;"
122
122
  >
123
123
  {#each visible as row, i (row.data.id)}
124
- <virtual-list-row
125
- class={finalRowClass}
126
- style="height: {rowHeight}px !important;"
127
- >
124
+ <div class={finalRowClass} style="height: {rowHeight}px !important;">
128
125
  {@render children({
129
126
  row: row.data,
130
127
  domIndex: i,
131
128
  index: row.index
132
129
  })}
133
- </virtual-list-row>
130
+ </div>
134
131
  {/each}
135
132
  </div>
136
133
  </div>
@@ -6,6 +6,9 @@ export interface Theme {
6
6
  hiddenBackground?: {
7
7
  class?: ClassValue;
8
8
  };
9
+ dialog?: {
10
+ class?: ClassValue;
11
+ };
9
12
  tabs?: {
10
13
  tab?: {
11
14
  class?: (active: boolean) => ClassValue;
@@ -1 +1 @@
1
- {"version":3,"file":"theme.svelte.d.ts","sourceRoot":"","sources":["../src/lib/theme.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,KAAK;IAClB,OAAO,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,gBAAgB,CAAC,EAAE;QACf,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,IAAI,CAAC,EAAE;QACH,GAAG,CAAC,EAAE;YACF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,UAAU,CAAC;SAC3C,CAAC;KACL,CAAC;IACF,KAAK,CAAC,EAAE;QACJ,MAAM,CAAC,EAAE;YACL,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;KACL,CAAC;IACF,KAAK,CAAC,EAAE;QACJ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,UAAU,CAAC,EAAE,UAAU,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;CACL;AAkBD,eAAO,MAAM,KAAK;uBAZS,KAAK;aAGF,KAAK;CASD,CAAC"}
1
+ {"version":3,"file":"theme.svelte.d.ts","sourceRoot":"","sources":["../src/lib/theme.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,KAAK;IAClB,OAAO,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,gBAAgB,CAAC,EAAE;QACf,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,MAAM,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,IAAI,CAAC,EAAE;QACH,GAAG,CAAC,EAAE;YACF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,UAAU,CAAC;SAC3C,CAAC;KACL,CAAC;IACF,KAAK,CAAC,EAAE;QACJ,MAAM,CAAC,EAAE;YACL,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;KACL,CAAC;IACF,KAAK,CAAC,EAAE;QACJ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,UAAU,CAAC,EAAE,UAAU,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;CACL;AAkBD,eAAO,MAAM,KAAK;uBAZS,KAAK;aAGF,KAAK;CASD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ims360/svelte-ivory",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "keywords": [
5
5
  "svelte"
6
6
  ],
@@ -2,7 +2,7 @@
2
2
  import { FileUp } from '@lucide/svelte';
3
3
  import type { Snippet } from 'svelte';
4
4
  import { scale } from 'svelte/transition';
5
- import { HiddenBackground, Portal } from '../layout';
5
+ import { HiddenBackground } from '../layout';
6
6
 
7
7
  export interface FullscreenDropzoneProps {
8
8
  ondrop: (files: File[]) => void;
@@ -64,11 +64,9 @@
64
64
  />
65
65
 
66
66
  {#if open}
67
- <Portal>
68
- <HiddenBackground class="flex items-center justify-center">
69
- {@render children()}
70
- </HiddenBackground>
71
- </Portal>
67
+ <HiddenBackground class="flex items-center justify-center">
68
+ {@render children()}
69
+ </HiddenBackground>
72
70
  {/if}
73
71
 
74
72
  {#snippet defaultChildren()}
@@ -63,8 +63,8 @@
63
63
  onclose={close}
64
64
  class={twMerge(
65
65
  clsx(
66
- 'h-full max-h-none w-screen max-w-full bg-transparent backdrop:bg-black/20',
67
- theme.current.hiddenBackground?.class,
66
+ 'h-full max-h-none w-screen max-w-full bg-transparent backdrop:bg-transparent',
67
+ theme.current.dialog?.class,
68
68
  clazz
69
69
  )
70
70
  )}
@@ -5,7 +5,7 @@
5
5
  import type { Snippet } from 'svelte';
6
6
  import { fly } from 'svelte/transition';
7
7
  import { twMerge } from 'tailwind-merge';
8
- import { HiddenBackground, Portal } from '..';
8
+ import { HiddenBackground } from '..';
9
9
  import Heading from '../Heading.svelte';
10
10
 
11
11
  export type DrawerPlacement = 'left' | 'right';
@@ -52,42 +52,40 @@
52
52
  </script>
53
53
 
54
54
  {#if currentlyOpen}
55
- <Portal>
56
- <HiddenBackground
57
- onclose={() => {
58
- if (closeOnOutsideClick) close();
59
- }}
55
+ <HiddenBackground
56
+ onclose={() => {
57
+ if (closeOnOutsideClick) close();
58
+ }}
59
+ >
60
+ <div
61
+ class={twMerge(
62
+ clsx([
63
+ 'bg-surface-50-950 absolute top-0 flex h-full flex-col gap-4 p-4',
64
+ placement === 'left' && 'left-0',
65
+ placement === 'right' && 'right-0',
66
+ clazz
67
+ ])
68
+ )}
69
+ onclick={(e) => e.stopPropagation()}
70
+ in:inTransition|global
71
+ out:outTransition|global
72
+ {...rest}
60
73
  >
61
- <div
62
- class={twMerge(
63
- clsx([
64
- 'bg-surface-50-950 absolute top-0 flex h-full flex-col gap-4 p-4',
65
- placement === 'left' && 'left-0',
66
- placement === 'right' && 'right-0',
67
- clazz
68
- ])
69
- )}
70
- onclick={(e) => e.stopPropagation()}
71
- in:inTransition|global
72
- out:outTransition|global
73
- {...rest}
74
- >
75
- <div class="flex flex-row items-center justify-between gap-8">
76
- {#if title}
77
- <Heading class="flex grow flex-row items-center gap-4">
78
- {#if typeof title === 'function'}
79
- {@render title()}
80
- {:else}
81
- {title}
82
- {/if}
83
- </Heading>
84
- {/if}
85
- <button class="group ml-auto flex justify-end" type="button" onclick={close}>
86
- <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
87
- </button>
88
- </div>
89
- {@render children()}
74
+ <div class="flex flex-row items-center justify-between gap-8">
75
+ {#if title}
76
+ <Heading class="flex grow flex-row items-center gap-4">
77
+ {#if typeof title === 'function'}
78
+ {@render title()}
79
+ {:else}
80
+ {title}
81
+ {/if}
82
+ </Heading>
83
+ {/if}
84
+ <button class="group ml-auto flex justify-end" type="button" onclick={close}>
85
+ <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
86
+ </button>
90
87
  </div>
91
- </HiddenBackground>
92
- </Portal>
88
+ {@render children()}
89
+ </div>
90
+ </HiddenBackground>
93
91
  {/if}
@@ -1,51 +1,13 @@
1
- <script lang="ts" module>
2
- import type { IvoryComponent, TransitionProps } from '$lib/types';
3
- import clsx from 'clsx';
4
- import type { ClassValue } from 'svelte/elements';
5
- import { fade } from 'svelte/transition';
6
- import { twMerge } from 'tailwind-merge';
7
- import { focusTrap, shortcut } from '../../../utils/actions/index';
8
-
9
- let globalClass = $state<ClassValue>();
10
-
11
- export function setClasses(value: ClassValue) {
12
- globalClass = value;
13
- }
14
-
15
- export interface HiddenBackgroundProps extends IvoryComponent<HTMLDivElement>, TransitionProps {
16
- /** Gets called when the dialog is clicked */
17
- onclose?: () => void;
18
- }
19
- </script>
20
-
21
1
  <script lang="ts">
2
+ import { theme } from '$lib/theme.svelte';
3
+ import type { DialogProps } from '../dialog';
4
+ import Dialog from '../dialog/Dialog.svelte';
5
+
22
6
  let {
23
7
  class: clazz,
24
- onclose,
25
- children,
26
- inTransition = (e) => fade(e, { duration: 200 }),
27
- outTransition = (e) => fade(e, { duration: 100 }),
8
+
28
9
  ...rest
29
- }: HiddenBackgroundProps = $props();
10
+ }: DialogProps = $props();
30
11
  </script>
31
12
 
32
- <div
33
- class={twMerge(
34
- clsx(
35
- 'bg-surface-950-50/40 pointer-events-auto absolute top-0 left-0 m-0 h-full w-full p-0',
36
- globalClass,
37
- clazz
38
- )
39
- )}
40
- use:focusTrap={true}
41
- {@attach shortcut({
42
- code: 'Escape',
43
- callback: onclose ?? (() => {})
44
- })}
45
- onclick={onclose}
46
- in:inTransition
47
- out:outTransition
48
- {...rest}
49
- >
50
- {@render children?.()}
51
- </div>
13
+ <Dialog {...rest} class={['bg-surface-950-50/40', theme.current.hiddenBackground?.class, clazz]} />
@@ -7,7 +7,7 @@
7
7
  import type { ClassValue, MouseEventHandler } from 'svelte/elements';
8
8
  import { fade } from 'svelte/transition';
9
9
  import { twMerge } from 'tailwind-merge';
10
- import { Heading, HiddenBackground, Portal } from '..';
10
+ import { Heading, HiddenBackground } from '..';
11
11
 
12
12
  /** Props for the modal, expose if you overwrite the defaults in a custom component */
13
13
  export type ModalProps = TransitionProps & {
@@ -83,73 +83,65 @@
83
83
  A modal, comes with a title, close button and different variants per default.
84
84
  -->
85
85
  {#if currentlyOpen}
86
- <Portal>
87
- <HiddenBackground
88
- onclose={() => {
89
- if (closeOnOutsideClick) close();
90
- }}
91
- class="flex h-full w-full flex-col items-center justify-start p-8 lg:p-12 xl:p-16"
92
- >
93
- {#if modal}
94
- <div {...rest} {onclick}>
95
- {@render modal()}
86
+ <HiddenBackground
87
+ onclose={() => {
88
+ if (closeOnOutsideClick) close();
89
+ }}
90
+ class="flex h-full w-full flex-col items-center justify-start p-8 lg:p-12 xl:p-16"
91
+ >
92
+ {#if modal}
93
+ <div {...rest} {onclick}>
94
+ {@render modal()}
95
+ </div>
96
+ {:else}
97
+ <div
98
+ class={twMerge(
99
+ clsx([
100
+ 'bg-surface-50-950 relative flex max-h-full max-w-full flex-col overflow-hidden rounded',
101
+ theme.current.modal?.class,
102
+ clazz
103
+ ])
104
+ )}
105
+ {...rest}
106
+ {onclick}
107
+ in:inTransition|global
108
+ out:outTransition|global
109
+ >
110
+ <div
111
+ class={[
112
+ 'flex flex-row items-center justify-between gap-4 px-4 py-3',
113
+ !variant && 'pb-0',
114
+ variant === 'success' && 'preset-tonal-success',
115
+ variant === 'warning' && 'preset-tonal-warning',
116
+ variant === 'error' && 'preset-tonal-error',
117
+ variant === 'info' && 'preset-tonal-primary'
118
+ ]}
119
+ >
120
+ {#if title}
121
+ <Heading class="flex grow flex-row items-center gap-4">
122
+ {#if typeof title === 'function'}
123
+ {@render title()}
124
+ {:else}
125
+ {title}
126
+ {/if}
127
+ </Heading>
128
+ {/if}
129
+ <button class="group ml-auto flex justify-end" type="button" onclick={close}>
130
+ <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
131
+ </button>
96
132
  </div>
97
- {:else}
98
133
  <div
99
134
  class={twMerge(
100
- clsx([
101
- 'bg-surface-50-950 relative flex max-h-full max-w-full flex-col overflow-hidden rounded',
102
- theme.current.modal?.class,
103
- clazz
104
- ])
135
+ clsx(
136
+ 'flex grow flex-col gap-4 overflow-hidden bg-inherit p-4 pt-3',
137
+ theme.current.modal?.innerClass,
138
+ innerClass
139
+ )
105
140
  )}
106
- {...rest}
107
- {onclick}
108
- in:inTransition|global
109
- out:outTransition|global
110
141
  >
111
- <div
112
- class={[
113
- 'flex flex-row items-center justify-between gap-4 px-4 py-3',
114
- !variant && 'pb-0',
115
- variant === 'success' && 'preset-tonal-success',
116
- variant === 'warning' && 'preset-tonal-warning',
117
- variant === 'error' && 'preset-tonal-error',
118
- variant === 'info' && 'preset-tonal-primary'
119
- ]}
120
- >
121
- {#if title}
122
- <Heading class="flex grow flex-row items-center gap-4">
123
- {#if typeof title === 'function'}
124
- {@render title()}
125
- {:else}
126
- {title}
127
- {/if}
128
- </Heading>
129
- {/if}
130
- <button
131
- class="group ml-auto flex justify-end"
132
- type="button"
133
- onclick={close}
134
- >
135
- <X
136
- class="h-full w-auto transition-[stroke-width] group-hover:stroke-3"
137
- />
138
- </button>
139
- </div>
140
- <div
141
- class={twMerge(
142
- clsx(
143
- 'flex grow flex-col gap-4 overflow-hidden bg-inherit p-4 pt-3',
144
- theme.current.modal?.innerClass,
145
- innerClass
146
- )
147
- )}
148
- >
149
- {@render children?.()}
150
- </div>
142
+ {@render children?.()}
151
143
  </div>
152
- {/if}
153
- </HiddenBackground>
154
- </Portal>
144
+ </div>
145
+ {/if}
146
+ </HiddenBackground>
155
147
  {/if}
@@ -13,7 +13,7 @@
13
13
  import clsx from 'clsx';
14
14
  import { twMerge } from 'tailwind-merge';
15
15
  import { clickOutside } from '../../../utils/actions/clickOutside';
16
- import Portal from '../portal/Portal.svelte';
16
+ import { Dialog } from '../dialog';
17
17
 
18
18
  /** Possible placements for the popover */
19
19
  export type PopoverPlacement = ComputePositionConfig['placement'];
@@ -31,8 +31,6 @@
31
31
  * Callback that is called when the user clicks outside the popover or the target element.
32
32
  */
33
33
  onClickOutside?: (e: MouseEvent) => void;
34
- /** If set to `true`, the nested component will not be unmounted when the popover is closed */
35
- keepMounted?: boolean;
36
34
  /**
37
35
  * Whether to place the popover automatically
38
36
  *
@@ -49,7 +47,6 @@
49
47
  target,
50
48
  placement = 'bottom-start',
51
49
  onClickOutside = close,
52
- keepMounted = false,
53
50
  children,
54
51
  autoplacement,
55
52
  ...rest
@@ -101,17 +98,10 @@
101
98
  @component
102
99
  A popover, positions itself relative to a target element.
103
100
  -->
104
- {#if currentlyOpen || keepMounted}
105
- <Portal>
101
+ {#if currentlyOpen}
102
+ <Dialog>
106
103
  <div
107
- class={twMerge(
108
- clsx(
109
- 'absolute',
110
- theme.current.popover?.class,
111
- !keepMounted && clazz,
112
- keepMounted && !currentlyOpen ? 'hidden' : clazz
113
- )
114
- )}
104
+ class={twMerge(clsx('absolute', theme.current.popover?.class, clazz))}
115
105
  style={style + ' ' + externalStyle}
116
106
  bind:this={popover}
117
107
  use:clickOutside={{ callback: onClickOutside, target }}
@@ -119,5 +109,5 @@
119
109
  >
120
110
  {@render children?.()}
121
111
  </div>
122
- </Portal>
112
+ </Dialog>
123
113
  {/if}
@@ -38,7 +38,16 @@
38
38
  let viewport_height = $state(0);
39
39
 
40
40
  export function scrollTo(top?: number, left?: number) {
41
- onscroll(top, left);
41
+ if (!viewport) return;
42
+ if (top !== undefined) {
43
+ scroll_top = top;
44
+ viewport.scrollTop = top;
45
+ b_scrollTop = top;
46
+ }
47
+ if (left !== undefined) {
48
+ scroll_left = left;
49
+ viewport.scrollLeft = left;
50
+ }
42
51
  }
43
52
 
44
53
  const start = $derived(Math.max(0, Math.floor(scroll_top / rowHeight) - overscan));
@@ -56,26 +65,16 @@
56
65
  const top = $derived(start * rowHeight);
57
66
  const bottom = $derived((data.length - end) * rowHeight);
58
67
 
59
- async function onscroll(top?: number, left?: number, retry = true) {
68
+ async function onscroll() {
60
69
  if (!viewport) {
61
70
  viewportReactivity++;
62
71
  await tick();
63
- if (retry) await onscroll(top, left, false);
72
+ onscroll();
64
73
  return;
65
74
  }
66
- if (typeof top !== 'undefined') {
67
- scroll_top = top;
68
- viewport.scrollTop = top;
69
- } else {
70
- scroll_top = viewport.scrollTop;
71
- b_scrollTop = scroll_top;
72
- }
73
- if (typeof left !== 'undefined') {
74
- scroll_left = left;
75
- viewport.scrollLeft = left;
76
- } else {
77
- scroll_left = viewport.scrollLeft;
78
- }
75
+ scroll_top = viewport.scrollTop;
76
+ scroll_left = viewport.scrollLeft;
77
+ b_scrollTop = scroll_top;
79
78
  }
80
79
 
81
80
  // update the scrolltop when the prop value changes
@@ -88,7 +87,8 @@
88
87
  }
89
88
  });
90
89
 
91
- onMount(() => {
90
+ onMount(async () => {
91
+ await tick();
92
92
  onscroll();
93
93
  });
94
94
  </script>
@@ -114,23 +114,20 @@
114
114
  class="flex min-w-full! grow overflow-auto [scrollbar-gutter:stable]"
115
115
  bind:this={viewport}
116
116
  bind:offsetHeight={viewport_height}
117
- onscroll={() => onscroll()}
117
+ {onscroll}
118
118
  >
119
119
  <div
120
120
  class="flex h-fit shrink-0 flex-col"
121
121
  style="padding-top: {top}px; padding-bottom: {bottom}px; min-width: max(100%, {header_width}px) !important;"
122
122
  >
123
123
  {#each visible as row, i (row.data.id)}
124
- <virtual-list-row
125
- class={finalRowClass}
126
- style="height: {rowHeight}px !important;"
127
- >
124
+ <div class={finalRowClass} style="height: {rowHeight}px !important;">
128
125
  {@render children({
129
126
  row: row.data,
130
127
  domIndex: i,
131
128
  index: row.index
132
129
  })}
133
- </virtual-list-row>
130
+ </div>
134
131
  {/each}
135
132
  </div>
136
133
  </div>
@@ -7,6 +7,9 @@ export interface Theme {
7
7
  hiddenBackground?: {
8
8
  class?: ClassValue;
9
9
  };
10
+ dialog?: {
11
+ class?: ClassValue;
12
+ };
10
13
  tabs?: {
11
14
  tab?: {
12
15
  class?: (active: boolean) => ClassValue;