@ims360/svelte-ivory 0.4.12 → 0.4.14

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.
@@ -18,7 +18,7 @@
18
18
  <svelte:element
19
19
  this={rest.onclick ? 'button' : 'div'}
20
20
  class={merge(
21
- 'group relative flex h-5 w-9 flex-row items-center rounded-full p-0.5 transition-colors duration-100',
21
+ 'group relative flex h-5 w-9 flex-row items-center rounded-full p-0.5 transition-colors ',
22
22
  value ? 'bg-primary-500' : 'bg-surface-300-700',
23
23
  clazz
24
24
  )}
@@ -65,7 +65,7 @@
65
65
  'group flex h-full grow flex-col overflow-hidden rounded border-2',
66
66
  hasIssues
67
67
  ? 'bg-error-500/20 border-error-500'
68
- : 'focus-within:border-primary-500 focus-within:hover:border-primary-500 border-surface-300-700/25 hover:border-surface-300-700/50 transition-[border-color] duration-300',
68
+ : 'focus-within:border-primary-500 focus-within:hover:border-primary-500 border-surface-300-700/25 hover:border-surface-300-700/50 transition-[border-color]',
69
69
  theme.current.input?.class?.(hasValue, hasIssues)
70
70
  )}
71
71
  >
@@ -61,6 +61,33 @@
61
61
  </dialog>
62
62
 
63
63
  <style>
64
+ dialog {
65
+ transition:
66
+ display var(--tw-duration, var(--default-transition-duration)) allow-discrete,
67
+ overlay var(--tw-duration, var(--default-transition-duration)) allow-discrete;
68
+ }
69
+
70
+ /* Dialog backdrop fade-in animation */
71
+ dialog::backdrop {
72
+ opacity: 0;
73
+ transition:
74
+ display var(--tw-duration, var(--default-transition-duration)) allow-discrete,
75
+ overlay var(--tw-duration, var(--default-transition-duration)) allow-discrete,
76
+ opacity var(--tw-duration, var(--default-transition-duration))
77
+ cubic-bezier(0.16, 1, 0.3, 1);
78
+ }
79
+
80
+ dialog[open]::backdrop {
81
+ opacity: 1;
82
+ }
83
+
84
+ /* Starting style for entry animation */
85
+ @starting-style {
86
+ dialog[open]::backdrop {
87
+ opacity: 0;
88
+ }
89
+ }
90
+
64
91
  dialog:not([open]):not(:popover-open) {
65
92
  display: none !important;
66
93
  }
@@ -1,15 +1,13 @@
1
1
  <script lang="ts" module>
2
- import type { TransitionProps } from '../../../types';
3
2
  import { merge } from '../../../utils/functions';
4
3
  import { X } from '@lucide/svelte';
5
4
  import type { Snippet } from 'svelte';
6
- import { fly } from 'svelte/transition';
7
5
  import Heading from '../Heading.svelte';
8
6
  import { Dialog } from '../dialog';
9
7
 
10
8
  export type DrawerPlacement = 'left' | 'right';
11
9
 
12
- export type DrawerProps = TransitionProps & {
10
+ export type DrawerProps = {
13
11
  class?: string;
14
12
  title?: string | Snippet;
15
13
  children: Snippet;
@@ -27,10 +25,6 @@
27
25
  title,
28
26
  placement = 'right',
29
27
  closeOnOutsideClick = true,
30
- inTransition = (e) =>
31
- fly(e, { x: placement === 'right' ? '100%' : '-100%', duration: 200 }),
32
- outTransition = (e) =>
33
- fly(e, { x: placement === 'right' ? '100%' : '-100%', duration: 200 }),
34
28
  inner,
35
29
  ...rest
36
30
  }: DrawerProps = $props();
@@ -56,33 +50,55 @@
56
50
  }}
57
51
  class={['flex flex-row justify-start overflow-visible', placement === 'right' && 'justify-end']}
58
52
  >
59
- {#if dialog?.isOpen()}
60
- <div
61
- class={merge('bg-surface-50-950 flex h-full flex-col gap-4 p-4', clazz)}
62
- onclick={(e) => e.stopPropagation()}
63
- in:inTransition
64
- out:outTransition
65
- {...rest}
66
- >
67
- {#if inner}
68
- {@render inner()}
69
- {:else}
70
- <div class="flex flex-row items-center justify-between gap-8">
71
- {#if title}
72
- <Heading class="flex grow flex-row items-center gap-4">
73
- {#if typeof title === 'function'}
74
- {@render title()}
75
- {:else}
76
- {title}
77
- {/if}
78
- </Heading>
79
- {/if}
80
- <button class="group ml-auto flex justify-end" type="button" onclick={close}>
81
- <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
82
- </button>
83
- </div>
84
- {@render children()}
85
- {/if}
86
- </div>
87
- {/if}
53
+ <div
54
+ data-placement={placement}
55
+ class={merge(
56
+ 'drawer bg-surface-50-950 flex h-full flex-col gap-4 p-4 transition-transform ease-in-out',
57
+ clazz
58
+ )}
59
+ onclick={(e) => e.stopPropagation()}
60
+ {...rest}
61
+ >
62
+ {#if inner}
63
+ {@render inner()}
64
+ {:else}
65
+ <div class="flex flex-row items-center justify-between gap-8">
66
+ {#if title}
67
+ <Heading class="flex grow flex-row items-center gap-4">
68
+ {#if typeof title === 'function'}
69
+ {@render title()}
70
+ {:else}
71
+ {title}
72
+ {/if}
73
+ </Heading>
74
+ {/if}
75
+ <button class="group ml-auto flex justify-end" type="button" onclick={close}>
76
+ <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
77
+ </button>
78
+ </div>
79
+ {@render children()}
80
+ {/if}
81
+ </div>
88
82
  </Dialog>
83
+
84
+ <style>
85
+ .drawer[data-placement='right'] {
86
+ transform: translateX(100%);
87
+ }
88
+ .drawer[data-placement='left'] {
89
+ transform: translateX(-100%);
90
+ }
91
+
92
+ :global(dialog[open]) .drawer {
93
+ transform: translateX(0);
94
+ }
95
+
96
+ @starting-style {
97
+ :global(dialog[open]) .drawer[data-placement='right'] {
98
+ transform: translateX(100%);
99
+ }
100
+ :global(dialog[open]) .drawer[data-placement='left'] {
101
+ transform: translateX(-100%);
102
+ }
103
+ }
104
+ </style>
@@ -1,7 +1,6 @@
1
- import type { TransitionProps } from '../../../types';
2
1
  import type { Snippet } from 'svelte';
3
2
  export type DrawerPlacement = 'left' | 'right';
4
- export type DrawerProps = TransitionProps & {
3
+ export type DrawerProps = {
5
4
  class?: string;
6
5
  title?: string | Snippet;
7
6
  children: Snippet;
@@ -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;AAKtC,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;IAC9B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AA+DN,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":"AAKI,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG;IACtB,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;IAC9B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AA8DN,QAAA,MAAM,MAAM;;;;;MAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
@@ -1,17 +1,15 @@
1
1
  <script lang="ts" module>
2
2
  import type { Variant } from '../../..';
3
3
  import { theme } from '../../../theme.svelte';
4
- import type { TransitionProps } from '../../../types';
5
4
  import { merge } from '../../../utils/functions';
6
5
  import { X } from '@lucide/svelte';
7
6
  import { type Snippet } from 'svelte';
8
7
  import type { ClassValue, MouseEventHandler } from 'svelte/elements';
9
- import { scale } from 'svelte/transition';
10
8
  import { Heading } from '..';
11
9
  import { Dialog } from '../dialog';
12
10
 
13
11
  /** Props for the modal, expose if you overwrite the defaults in a custom component */
14
- export type ModalProps = TransitionProps & {
12
+ export type ModalProps = {
15
13
  /** Class of the modal itself, does not apply to the inner div */
16
14
  class?: ClassValue;
17
15
  /** Class of the div wrapping the children */
@@ -34,32 +32,24 @@
34
32
  <script lang="ts">
35
33
  interface Props extends ModalProps {
36
34
  /** If you don't want the title and close button to be included you can overwrite the default modal */
37
- modal?: Snippet;
35
+ inner?: Snippet;
38
36
  }
39
37
 
40
38
  let {
41
39
  class: clazz = 'flex flex-col',
42
40
  title,
43
41
  children,
44
- modal,
42
+ inner,
45
43
  closeOnOutsideClick = true,
46
44
  variant,
47
45
  innerClass,
48
- inTransition = (e) =>
49
- scale(e, {
50
- duration: 200,
51
- start: 0.8
52
- }),
53
- outTransition = () => ({}),
54
46
  ...rest
55
47
  }: Props = $props();
56
48
 
57
49
  let dialog = $state<Dialog>();
58
50
 
59
51
  export const close = () => dialog?.close();
60
-
61
52
  export const open = () => dialog?.open();
62
-
63
53
  export const isOpen = () => dialog?.isOpen();
64
54
 
65
55
  export const toggle = () => {
@@ -82,61 +72,76 @@
82
72
  onclose={() => {
83
73
  if (closeOnOutsideClick) close();
84
74
  }}
85
- class={merge('flex h-full w-full flex-col items-center justify-center p-8 lg:p-12 xl:p-16')}
75
+ class="flex h-full w-full flex-col items-center justify-center p-2 sm:p-4 md:p-8 lg:p-12 xl:p-16"
86
76
  >
87
- {#if dialog?.isOpen()}
88
- {#if modal}
89
- <div {...rest} {onclick}>
90
- {@render modal()}
77
+ {#if inner}
78
+ <div {...rest} {onclick} class={merge('modal-content transition-all ease-in-out', clazz)}>
79
+ {@render inner()}
80
+ </div>
81
+ {:else}
82
+ <div
83
+ class={merge(
84
+ 'modal-content bg-surface-50-950 flex max-h-full max-w-full flex-col overflow-hidden rounded transition-all ease-in-out',
85
+ theme.current.modal?.class,
86
+ clazz
87
+ )}
88
+ {...rest}
89
+ {onclick}
90
+ >
91
+ <div
92
+ class={[
93
+ 'flex flex-row items-center justify-between gap-4 px-4 py-3',
94
+ !variant && 'pb-0',
95
+ variant === 'primary' && 'preset-tonal-primary',
96
+ variant === 'secondary' && 'preset-tonal-secondary',
97
+ variant === 'tertiary' && 'preset-tonal-tertiary',
98
+ variant === 'success' && 'preset-tonal-success',
99
+ variant === 'warning' && 'preset-tonal-warning',
100
+ variant === 'error' && 'preset-tonal-error',
101
+ variant === 'surface' && 'preset-tonal-surface'
102
+ ]}
103
+ >
104
+ {#if title}
105
+ <Heading class="flex grow flex-row items-center gap-4">
106
+ {#if typeof title === 'function'}
107
+ {@render title()}
108
+ {:else}
109
+ {title}
110
+ {/if}
111
+ </Heading>
112
+ {/if}
113
+ <button class="group ml-auto flex justify-end" type="button" onclick={close}>
114
+ <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
115
+ </button>
91
116
  </div>
92
- {:else}
93
117
  <div
94
118
  class={merge(
95
- 'bg-surface-50-950 flex max-h-full max-w-full flex-col overflow-hidden rounded',
96
- theme.current.modal?.class,
97
- clazz
119
+ 'flex grow flex-col gap-4 overflow-hidden bg-inherit p-4 pt-3',
120
+ theme.current.modal?.innerClass,
121
+ innerClass
98
122
  )}
99
- {...rest}
100
- {onclick}
101
- in:inTransition
102
- out:outTransition
103
123
  >
104
- <div
105
- class={[
106
- 'flex flex-row items-center justify-between gap-4 px-4 py-3',
107
- !variant && 'pb-0',
108
- variant === 'primary' && 'preset-tonal-primary',
109
- variant === 'secondary' && 'preset-tonal-secondary',
110
- variant === 'tertiary' && 'preset-tonal-tertiary',
111
- variant === 'success' && 'preset-tonal-success',
112
- variant === 'warning' && 'preset-tonal-warning',
113
- variant === 'error' && 'preset-tonal-error',
114
- variant === 'surface' && 'preset-tonal-surface'
115
- ]}
116
- >
117
- {#if title}
118
- <Heading class="flex grow flex-row items-center gap-4">
119
- {#if typeof title === 'function'}
120
- {@render title()}
121
- {:else}
122
- {title}
123
- {/if}
124
- </Heading>
125
- {/if}
126
- <button class="group ml-auto flex justify-end" type="button" onclick={close}>
127
- <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
128
- </button>
129
- </div>
130
- <div
131
- class={merge(
132
- 'flex grow flex-col gap-4 overflow-hidden bg-inherit p-4 pt-3',
133
- theme.current.modal?.innerClass,
134
- innerClass
135
- )}
136
- >
137
- {@render children?.()}
138
- </div>
124
+ {@render children?.()}
139
125
  </div>
140
- {/if}
126
+ </div>
141
127
  {/if}
142
128
  </Dialog>
129
+
130
+ <style>
131
+ .modal-content {
132
+ opacity: 0;
133
+ transform: scale(0.97);
134
+ }
135
+
136
+ :global(dialog[open]) .modal-content {
137
+ opacity: 1;
138
+ transform: scale(1);
139
+ }
140
+
141
+ @starting-style {
142
+ :global(dialog[open]) .modal-content {
143
+ opacity: 0;
144
+ transform: scale(0.97);
145
+ }
146
+ }
147
+ </style>
@@ -1,9 +1,8 @@
1
1
  import type { Variant } from '../../..';
2
- import type { TransitionProps } from '../../../types';
3
2
  import { type Snippet } from 'svelte';
4
3
  import type { ClassValue, MouseEventHandler } from 'svelte/elements';
5
4
  /** Props for the modal, expose if you overwrite the defaults in a custom component */
6
- export type ModalProps = TransitionProps & {
5
+ export type ModalProps = {
7
6
  /** Class of the modal itself, does not apply to the inner div */
8
7
  class?: ClassValue;
9
8
  /** Class of the div wrapping the children */
@@ -23,7 +22,7 @@ export type ModalProps = TransitionProps & {
23
22
  };
24
23
  interface Props extends ModalProps {
25
24
  /** If you don't want the title and close button to be included you can overwrite the default modal */
26
- modal?: Snippet;
25
+ inner?: Snippet;
27
26
  }
28
27
  /** A modal, comes with a title, close button and different variants per default. */
29
28
  declare const Modal: import("svelte").Component<Props, {
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/modal/Modal.svelte.ts"],"names":[],"mappings":"AAGI,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,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,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;CAC/C,CAAC;AAEF,UAAU,KAAM,SAAQ,UAAU;IAC9B,sGAAsG;IACtG,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AA+FL,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":"AAGI,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAIpC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAIrE,sFAAsF;AACtF,MAAM,MAAM,UAAU,GAAG;IACrB,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,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;CAC/C,CAAC;AAEF,UAAU,KAAM,SAAQ,UAAU;IAC9B,sGAAsG;IACtG,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAuFL,oFAAoF;AACpF,QAAA,MAAM,KAAK;;;;;MAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
@@ -1,9 +1,7 @@
1
1
  <script lang="ts" module>
2
2
  import { theme } from '../../../theme.svelte';
3
3
  import type { IvoryComponent } from '../../../types';
4
- import { pseudoRandomId } from '../../../utils/functions';
5
- import clsx from 'clsx';
6
- import { twMerge } from 'tailwind-merge';
4
+ import { merge, pseudoRandomId } from '../../../utils/functions';
7
5
 
8
6
  /** Possible placements for the popover */
9
7
  export type PopoverPlacement =
@@ -177,7 +175,7 @@
177
175
  bind:this={popoverEl}
178
176
  style="{style} {externalStyle}"
179
177
  {popover}
180
- class={twMerge(clsx('bg-transparent', theme.current.popover?.class, clazz))}
178
+ class={merge('bg-transparent not-open:hidden!', theme.current.popover?.class, clazz)}
181
179
  {...rest}
182
180
  >
183
181
  {@render children?.()}
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/popover/Popover.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjD,0CAA0C;AAC1C,MAAM,MAAM,gBAAgB,GACtB,KAAK,GACL,WAAW,GACX,SAAS,GACT,OAAO,GACP,aAAa,GACb,WAAW,GACX,QAAQ,GACR,cAAc,GACd,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,UAAU,CAAC;AAEjB,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,cAAc,CAAC;IAChE,6DAA6D;IAC7D,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAmJL,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":"AAII,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,0CAA0C;AAC1C,MAAM,MAAM,gBAAgB,GACtB,KAAK,GACL,WAAW,GACX,SAAS,GACT,OAAO,GACP,aAAa,GACb,WAAW,GACX,QAAQ,GACR,cAAc,GACd,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,UAAU,CAAC;AAEjB,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,cAAc,CAAC;IAChE,6DAA6D;IAC7D,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAmJL,QAAA,MAAM,OAAO;;;;;MAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -34,6 +34,9 @@ export interface Theme {
34
34
  class?: ClassValue;
35
35
  };
36
36
  };
37
+ drawer?: {
38
+ class?: ClassValue;
39
+ };
37
40
  popover?: {
38
41
  class?: ClassValue;
39
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"theme.svelte.d.ts","sourceRoot":"","sources":["../src/lib/theme.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,KAAK;IAClB,QAAQ,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,UAAU,CAAC;KAC9D,CAAC;IACF,OAAO,CAAC,EAAE;QACN,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,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,MAAM,CAAC,EAAE;YACL,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;QACF,IAAI,CAAC,EAAE;YACH,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;QACF,GAAG,CAAC,EAAE;YACF,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;QACxB,MAAM,CAAC,EAAE;YACL,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;KACL,CAAC;IACF,OAAO,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,KAAK,CAAC,EAAE;QACJ,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,UAAU,CAAC;QACzD,KAAK,CAAC,EAAE;YACJ,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,UAAU,CAAC;SAC5D,CAAC;QACF,MAAM,CAAC,EAAE;YACL,KAAK,CAAC,EAAE;gBACJ,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,CAAC;gBAC3C,KAAK,CAAC,EAAE,UAAU,CAAC;aACtB,CAAC;YACF,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;KACL,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,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,KAAK;IAClB,QAAQ,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,UAAU,CAAC;KAC9D,CAAC;IACF,OAAO,CAAC,EAAE;QACN,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,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,MAAM,CAAC,EAAE;YACL,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;QACF,IAAI,CAAC,EAAE;YACH,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;QACF,GAAG,CAAC,EAAE;YACF,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;QACxB,MAAM,CAAC,EAAE;YACL,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;KACL,CAAC;IACF,MAAM,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,OAAO,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,KAAK,CAAC,EAAE;QACJ,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,UAAU,CAAC;QACzD,KAAK,CAAC,EAAE;YACJ,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,UAAU,CAAC;SAC5D,CAAC;QACF,MAAM,CAAC,EAAE;YACL,KAAK,CAAC,EAAE;gBACJ,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,CAAC;gBAC3C,KAAK,CAAC,EAAE,UAAU,CAAC;aACtB,CAAC;YACF,KAAK,CAAC,EAAE,UAAU,CAAC;SACtB,CAAC;KACL,CAAC;CACL;AAkBD,eAAO,MAAM,KAAK;uBAZS,KAAK;aAGF,KAAK;CASD,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,9 +1,4 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
- import type { TransitionConfig } from 'svelte/transition';
3
2
  export interface IvoryComponent<RootElement extends EventTarget> extends HTMLAttributes<RootElement> {
4
3
  }
5
- export interface TransitionProps {
6
- inTransition?: (node: Element) => TransitionConfig;
7
- outTransition?: (node: Element) => TransitionConfig;
8
- }
9
4
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,MAAM,WAAW,cAAc,CAC3B,WAAW,SAAS,WAAW,CACjC,SAAQ,cAAc,CAAC,WAAW,CAAC;CAAG;AAExC,MAAM,WAAW,eAAe;IAC5B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,gBAAgB,CAAC;IACnD,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,gBAAgB,CAAC;CACvD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,MAAM,WAAW,cAAc,CAC3B,WAAW,SAAS,WAAW,CACjC,SAAQ,cAAc,CAAC,WAAW,CAAC;CAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ims360/svelte-ivory",
3
- "version": "0.4.12",
3
+ "version": "0.4.14",
4
4
  "keywords": [
5
5
  "svelte"
6
6
  ],
@@ -18,7 +18,7 @@
18
18
  <svelte:element
19
19
  this={rest.onclick ? 'button' : 'div'}
20
20
  class={merge(
21
- 'group relative flex h-5 w-9 flex-row items-center rounded-full p-0.5 transition-colors duration-100',
21
+ 'group relative flex h-5 w-9 flex-row items-center rounded-full p-0.5 transition-colors ',
22
22
  value ? 'bg-primary-500' : 'bg-surface-300-700',
23
23
  clazz
24
24
  )}
@@ -65,7 +65,7 @@
65
65
  'group flex h-full grow flex-col overflow-hidden rounded border-2',
66
66
  hasIssues
67
67
  ? 'bg-error-500/20 border-error-500'
68
- : 'focus-within:border-primary-500 focus-within:hover:border-primary-500 border-surface-300-700/25 hover:border-surface-300-700/50 transition-[border-color] duration-300',
68
+ : 'focus-within:border-primary-500 focus-within:hover:border-primary-500 border-surface-300-700/25 hover:border-surface-300-700/50 transition-[border-color]',
69
69
  theme.current.input?.class?.(hasValue, hasIssues)
70
70
  )}
71
71
  >
@@ -61,6 +61,33 @@
61
61
  </dialog>
62
62
 
63
63
  <style>
64
+ dialog {
65
+ transition:
66
+ display var(--tw-duration, var(--default-transition-duration)) allow-discrete,
67
+ overlay var(--tw-duration, var(--default-transition-duration)) allow-discrete;
68
+ }
69
+
70
+ /* Dialog backdrop fade-in animation */
71
+ dialog::backdrop {
72
+ opacity: 0;
73
+ transition:
74
+ display var(--tw-duration, var(--default-transition-duration)) allow-discrete,
75
+ overlay var(--tw-duration, var(--default-transition-duration)) allow-discrete,
76
+ opacity var(--tw-duration, var(--default-transition-duration))
77
+ cubic-bezier(0.16, 1, 0.3, 1);
78
+ }
79
+
80
+ dialog[open]::backdrop {
81
+ opacity: 1;
82
+ }
83
+
84
+ /* Starting style for entry animation */
85
+ @starting-style {
86
+ dialog[open]::backdrop {
87
+ opacity: 0;
88
+ }
89
+ }
90
+
64
91
  dialog:not([open]):not(:popover-open) {
65
92
  display: none !important;
66
93
  }
@@ -1,15 +1,13 @@
1
1
  <script lang="ts" module>
2
- import type { TransitionProps } from '$lib/types';
3
2
  import { merge } from '$lib/utils/functions';
4
3
  import { X } from '@lucide/svelte';
5
4
  import type { Snippet } from 'svelte';
6
- import { fly } from 'svelte/transition';
7
5
  import Heading from '../Heading.svelte';
8
6
  import { Dialog } from '../dialog';
9
7
 
10
8
  export type DrawerPlacement = 'left' | 'right';
11
9
 
12
- export type DrawerProps = TransitionProps & {
10
+ export type DrawerProps = {
13
11
  class?: string;
14
12
  title?: string | Snippet;
15
13
  children: Snippet;
@@ -27,10 +25,6 @@
27
25
  title,
28
26
  placement = 'right',
29
27
  closeOnOutsideClick = true,
30
- inTransition = (e) =>
31
- fly(e, { x: placement === 'right' ? '100%' : '-100%', duration: 200 }),
32
- outTransition = (e) =>
33
- fly(e, { x: placement === 'right' ? '100%' : '-100%', duration: 200 }),
34
28
  inner,
35
29
  ...rest
36
30
  }: DrawerProps = $props();
@@ -56,33 +50,55 @@
56
50
  }}
57
51
  class={['flex flex-row justify-start overflow-visible', placement === 'right' && 'justify-end']}
58
52
  >
59
- {#if dialog?.isOpen()}
60
- <div
61
- class={merge('bg-surface-50-950 flex h-full flex-col gap-4 p-4', clazz)}
62
- onclick={(e) => e.stopPropagation()}
63
- in:inTransition
64
- out:outTransition
65
- {...rest}
66
- >
67
- {#if inner}
68
- {@render inner()}
69
- {:else}
70
- <div class="flex flex-row items-center justify-between gap-8">
71
- {#if title}
72
- <Heading class="flex grow flex-row items-center gap-4">
73
- {#if typeof title === 'function'}
74
- {@render title()}
75
- {:else}
76
- {title}
77
- {/if}
78
- </Heading>
79
- {/if}
80
- <button class="group ml-auto flex justify-end" type="button" onclick={close}>
81
- <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
82
- </button>
83
- </div>
84
- {@render children()}
85
- {/if}
86
- </div>
87
- {/if}
53
+ <div
54
+ data-placement={placement}
55
+ class={merge(
56
+ 'drawer bg-surface-50-950 flex h-full flex-col gap-4 p-4 transition-transform ease-in-out',
57
+ clazz
58
+ )}
59
+ onclick={(e) => e.stopPropagation()}
60
+ {...rest}
61
+ >
62
+ {#if inner}
63
+ {@render inner()}
64
+ {:else}
65
+ <div class="flex flex-row items-center justify-between gap-8">
66
+ {#if title}
67
+ <Heading class="flex grow flex-row items-center gap-4">
68
+ {#if typeof title === 'function'}
69
+ {@render title()}
70
+ {:else}
71
+ {title}
72
+ {/if}
73
+ </Heading>
74
+ {/if}
75
+ <button class="group ml-auto flex justify-end" type="button" onclick={close}>
76
+ <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
77
+ </button>
78
+ </div>
79
+ {@render children()}
80
+ {/if}
81
+ </div>
88
82
  </Dialog>
83
+
84
+ <style>
85
+ .drawer[data-placement='right'] {
86
+ transform: translateX(100%);
87
+ }
88
+ .drawer[data-placement='left'] {
89
+ transform: translateX(-100%);
90
+ }
91
+
92
+ :global(dialog[open]) .drawer {
93
+ transform: translateX(0);
94
+ }
95
+
96
+ @starting-style {
97
+ :global(dialog[open]) .drawer[data-placement='right'] {
98
+ transform: translateX(100%);
99
+ }
100
+ :global(dialog[open]) .drawer[data-placement='left'] {
101
+ transform: translateX(-100%);
102
+ }
103
+ }
104
+ </style>
@@ -1,17 +1,15 @@
1
1
  <script lang="ts" module>
2
2
  import type { Variant } from '$lib';
3
3
  import { theme } from '$lib/theme.svelte';
4
- import type { TransitionProps } from '$lib/types';
5
4
  import { merge } from '$lib/utils/functions';
6
5
  import { X } from '@lucide/svelte';
7
6
  import { type Snippet } from 'svelte';
8
7
  import type { ClassValue, MouseEventHandler } from 'svelte/elements';
9
- import { scale } from 'svelte/transition';
10
8
  import { Heading } from '..';
11
9
  import { Dialog } from '../dialog';
12
10
 
13
11
  /** Props for the modal, expose if you overwrite the defaults in a custom component */
14
- export type ModalProps = TransitionProps & {
12
+ export type ModalProps = {
15
13
  /** Class of the modal itself, does not apply to the inner div */
16
14
  class?: ClassValue;
17
15
  /** Class of the div wrapping the children */
@@ -34,32 +32,24 @@
34
32
  <script lang="ts">
35
33
  interface Props extends ModalProps {
36
34
  /** If you don't want the title and close button to be included you can overwrite the default modal */
37
- modal?: Snippet;
35
+ inner?: Snippet;
38
36
  }
39
37
 
40
38
  let {
41
39
  class: clazz = 'flex flex-col',
42
40
  title,
43
41
  children,
44
- modal,
42
+ inner,
45
43
  closeOnOutsideClick = true,
46
44
  variant,
47
45
  innerClass,
48
- inTransition = (e) =>
49
- scale(e, {
50
- duration: 200,
51
- start: 0.8
52
- }),
53
- outTransition = () => ({}),
54
46
  ...rest
55
47
  }: Props = $props();
56
48
 
57
49
  let dialog = $state<Dialog>();
58
50
 
59
51
  export const close = () => dialog?.close();
60
-
61
52
  export const open = () => dialog?.open();
62
-
63
53
  export const isOpen = () => dialog?.isOpen();
64
54
 
65
55
  export const toggle = () => {
@@ -82,61 +72,76 @@
82
72
  onclose={() => {
83
73
  if (closeOnOutsideClick) close();
84
74
  }}
85
- class={merge('flex h-full w-full flex-col items-center justify-center p-8 lg:p-12 xl:p-16')}
75
+ class="flex h-full w-full flex-col items-center justify-center p-2 sm:p-4 md:p-8 lg:p-12 xl:p-16"
86
76
  >
87
- {#if dialog?.isOpen()}
88
- {#if modal}
89
- <div {...rest} {onclick}>
90
- {@render modal()}
77
+ {#if inner}
78
+ <div {...rest} {onclick} class={merge('modal-content transition-all ease-in-out', clazz)}>
79
+ {@render inner()}
80
+ </div>
81
+ {:else}
82
+ <div
83
+ class={merge(
84
+ 'modal-content bg-surface-50-950 flex max-h-full max-w-full flex-col overflow-hidden rounded transition-all ease-in-out',
85
+ theme.current.modal?.class,
86
+ clazz
87
+ )}
88
+ {...rest}
89
+ {onclick}
90
+ >
91
+ <div
92
+ class={[
93
+ 'flex flex-row items-center justify-between gap-4 px-4 py-3',
94
+ !variant && 'pb-0',
95
+ variant === 'primary' && 'preset-tonal-primary',
96
+ variant === 'secondary' && 'preset-tonal-secondary',
97
+ variant === 'tertiary' && 'preset-tonal-tertiary',
98
+ variant === 'success' && 'preset-tonal-success',
99
+ variant === 'warning' && 'preset-tonal-warning',
100
+ variant === 'error' && 'preset-tonal-error',
101
+ variant === 'surface' && 'preset-tonal-surface'
102
+ ]}
103
+ >
104
+ {#if title}
105
+ <Heading class="flex grow flex-row items-center gap-4">
106
+ {#if typeof title === 'function'}
107
+ {@render title()}
108
+ {:else}
109
+ {title}
110
+ {/if}
111
+ </Heading>
112
+ {/if}
113
+ <button class="group ml-auto flex justify-end" type="button" onclick={close}>
114
+ <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
115
+ </button>
91
116
  </div>
92
- {:else}
93
117
  <div
94
118
  class={merge(
95
- 'bg-surface-50-950 flex max-h-full max-w-full flex-col overflow-hidden rounded',
96
- theme.current.modal?.class,
97
- clazz
119
+ 'flex grow flex-col gap-4 overflow-hidden bg-inherit p-4 pt-3',
120
+ theme.current.modal?.innerClass,
121
+ innerClass
98
122
  )}
99
- {...rest}
100
- {onclick}
101
- in:inTransition
102
- out:outTransition
103
123
  >
104
- <div
105
- class={[
106
- 'flex flex-row items-center justify-between gap-4 px-4 py-3',
107
- !variant && 'pb-0',
108
- variant === 'primary' && 'preset-tonal-primary',
109
- variant === 'secondary' && 'preset-tonal-secondary',
110
- variant === 'tertiary' && 'preset-tonal-tertiary',
111
- variant === 'success' && 'preset-tonal-success',
112
- variant === 'warning' && 'preset-tonal-warning',
113
- variant === 'error' && 'preset-tonal-error',
114
- variant === 'surface' && 'preset-tonal-surface'
115
- ]}
116
- >
117
- {#if title}
118
- <Heading class="flex grow flex-row items-center gap-4">
119
- {#if typeof title === 'function'}
120
- {@render title()}
121
- {:else}
122
- {title}
123
- {/if}
124
- </Heading>
125
- {/if}
126
- <button class="group ml-auto flex justify-end" type="button" onclick={close}>
127
- <X class="h-full w-auto transition-[stroke-width] group-hover:stroke-3" />
128
- </button>
129
- </div>
130
- <div
131
- class={merge(
132
- 'flex grow flex-col gap-4 overflow-hidden bg-inherit p-4 pt-3',
133
- theme.current.modal?.innerClass,
134
- innerClass
135
- )}
136
- >
137
- {@render children?.()}
138
- </div>
124
+ {@render children?.()}
139
125
  </div>
140
- {/if}
126
+ </div>
141
127
  {/if}
142
128
  </Dialog>
129
+
130
+ <style>
131
+ .modal-content {
132
+ opacity: 0;
133
+ transform: scale(0.97);
134
+ }
135
+
136
+ :global(dialog[open]) .modal-content {
137
+ opacity: 1;
138
+ transform: scale(1);
139
+ }
140
+
141
+ @starting-style {
142
+ :global(dialog[open]) .modal-content {
143
+ opacity: 0;
144
+ transform: scale(0.97);
145
+ }
146
+ }
147
+ </style>
@@ -1,9 +1,7 @@
1
1
  <script lang="ts" module>
2
2
  import { theme } from '$lib/theme.svelte';
3
3
  import type { IvoryComponent } from '$lib/types';
4
- import { pseudoRandomId } from '$lib/utils/functions';
5
- import clsx from 'clsx';
6
- import { twMerge } from 'tailwind-merge';
4
+ import { merge, pseudoRandomId } from '$lib/utils/functions';
7
5
 
8
6
  /** Possible placements for the popover */
9
7
  export type PopoverPlacement =
@@ -177,7 +175,7 @@
177
175
  bind:this={popoverEl}
178
176
  style="{style} {externalStyle}"
179
177
  {popover}
180
- class={twMerge(clsx('bg-transparent', theme.current.popover?.class, clazz))}
178
+ class={merge('bg-transparent not-open:hidden!', theme.current.popover?.class, clazz)}
181
179
  {...rest}
182
180
  >
183
181
  {@render children?.()}
@@ -35,6 +35,9 @@ export interface Theme {
35
35
  class?: ClassValue;
36
36
  };
37
37
  };
38
+ drawer?: {
39
+ class?: ClassValue;
40
+ };
38
41
  popover?: {
39
42
  class?: ClassValue;
40
43
  };
package/src/lib/types.ts CHANGED
@@ -1,12 +1,6 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
- import type { TransitionConfig } from 'svelte/transition';
3
2
 
4
3
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
5
4
  export interface IvoryComponent<
6
5
  RootElement extends EventTarget
7
6
  > extends HTMLAttributes<RootElement> {}
8
-
9
- export interface TransitionProps {
10
- inTransition?: (node: Element) => TransitionConfig;
11
- outTransition?: (node: Element) => TransitionConfig;
12
- }