@immich/ui 0.24.5 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Button/Button.svelte +2 -2
- package/dist/components/Button/Button.svelte.d.ts +1 -1
- package/dist/components/Card/Card.svelte +7 -1
- package/dist/components/Card/Card.svelte.d.ts +2 -1
- package/dist/components/Modal/Modal.svelte +39 -15
- package/dist/components/Modal/Modal.svelte.d.ts +4 -2
- package/dist/components/ThemeSwitcher/ThemeSwitcher.svelte +2 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/internal/Button.svelte +10 -2
- package/dist/internal/Button.svelte.d.ts +1 -1
- package/dist/services/theme.svelte.d.ts +1 -0
- package/dist/services/theme.svelte.js +4 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import Button from '../../internal/Button.svelte';
|
|
3
3
|
import type { ButtonProps } from '../../types.js';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
let { ref = $bindable(null), ...props }: ButtonProps = $props();
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
|
-
<Button {...props} />
|
|
8
|
+
<Button bind:ref {...props} />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Button from '../../internal/Button.svelte';
|
|
2
2
|
import type { ButtonProps } from '../../types.js';
|
|
3
|
-
declare const Button: import("svelte").Component<ButtonProps, {}, "">;
|
|
3
|
+
declare const Button: import("svelte").Component<ButtonProps, {}, "ref">;
|
|
4
4
|
type Button = ReturnType<typeof Button>;
|
|
5
5
|
export default Button;
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { tv } from 'tailwind-variants';
|
|
13
13
|
|
|
14
14
|
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
15
|
+
ref?: HTMLElement | null;
|
|
15
16
|
color?: Color;
|
|
16
17
|
shape?: 'round' | 'rectangle';
|
|
17
18
|
expanded?: boolean;
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
let {
|
|
24
|
+
ref = $bindable(null),
|
|
23
25
|
color,
|
|
24
26
|
class: className,
|
|
25
27
|
shape = 'round',
|
|
@@ -125,7 +127,11 @@
|
|
|
125
127
|
{/if}
|
|
126
128
|
{/snippet}
|
|
127
129
|
|
|
128
|
-
<div
|
|
130
|
+
<div
|
|
131
|
+
bind:this={ref}
|
|
132
|
+
class={cleanClass(containerStyles({ shape, border: !color }), className)}
|
|
133
|
+
{...restProps}
|
|
134
|
+
>
|
|
129
135
|
<div class={cleanClass(cardStyles({ color }))}>
|
|
130
136
|
{#if headerChild}
|
|
131
137
|
{@render header()}
|
|
@@ -2,12 +2,13 @@ import type { Color } from '../../types.js';
|
|
|
2
2
|
import { type Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
5
|
+
ref?: HTMLElement | null;
|
|
5
6
|
color?: Color;
|
|
6
7
|
shape?: 'round' | 'rectangle';
|
|
7
8
|
expanded?: boolean;
|
|
8
9
|
expandable?: boolean;
|
|
9
10
|
children: Snippet;
|
|
10
11
|
};
|
|
11
|
-
declare const Card: import("svelte").Component<Props, {}, "expanded">;
|
|
12
|
+
declare const Card: import("svelte").Component<Props, {}, "ref" | "expanded">;
|
|
12
13
|
type Card = ReturnType<typeof Card>;
|
|
13
14
|
export default Card;
|
|
@@ -16,21 +16,25 @@
|
|
|
16
16
|
import { tv } from 'tailwind-variants';
|
|
17
17
|
|
|
18
18
|
type Props = {
|
|
19
|
-
title
|
|
19
|
+
title?: string;
|
|
20
|
+
icon?: string | boolean;
|
|
20
21
|
size?: ModalSize;
|
|
21
22
|
class?: string;
|
|
22
|
-
icon?: string | boolean;
|
|
23
23
|
expandable?: boolean;
|
|
24
|
+
closeOnEsc?: boolean;
|
|
25
|
+
closeOnBackdropClick?: boolean;
|
|
24
26
|
children: Snippet;
|
|
25
27
|
onClose?: () => void;
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
let {
|
|
29
|
-
title,
|
|
30
31
|
size = 'medium',
|
|
31
|
-
icon = true,
|
|
32
32
|
onClose,
|
|
33
|
+
icon = true,
|
|
34
|
+
title,
|
|
33
35
|
class: className,
|
|
36
|
+
closeOnEsc = true,
|
|
37
|
+
closeOnBackdropClick = false,
|
|
34
38
|
children,
|
|
35
39
|
}: Props = $props();
|
|
36
40
|
|
|
@@ -49,6 +53,7 @@
|
|
|
49
53
|
});
|
|
50
54
|
|
|
51
55
|
const { getChildren: getChildSnippet } = withChildrenSnippets(ChildKey.Modal);
|
|
56
|
+
const headerChildren = $derived(getChildSnippet(ChildKey.ModalHeader));
|
|
52
57
|
const bodyChildren = $derived(getChildSnippet(ChildKey.ModalBody));
|
|
53
58
|
const footerChildren = $derived(getChildSnippet(ChildKey.ModalFooter));
|
|
54
59
|
|
|
@@ -59,6 +64,16 @@
|
|
|
59
64
|
|
|
60
65
|
onClose?.();
|
|
61
66
|
};
|
|
67
|
+
|
|
68
|
+
let cardRef = $state<HTMLElement | null>(null);
|
|
69
|
+
|
|
70
|
+
const handleCloseOnClick = (event: Event) => {
|
|
71
|
+
if (!closeOnBackdropClick || cardRef?.contains(event.target as Node)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
onClose?.();
|
|
76
|
+
};
|
|
62
77
|
</script>
|
|
63
78
|
|
|
64
79
|
<Dialog.Root open={true}>
|
|
@@ -69,25 +84,34 @@
|
|
|
69
84
|
if (e.key === 'Escape') {
|
|
70
85
|
e.stopPropagation();
|
|
71
86
|
e.preventDefault();
|
|
72
|
-
|
|
87
|
+
if (closeOnEsc) {
|
|
88
|
+
handleClose();
|
|
89
|
+
}
|
|
73
90
|
}
|
|
74
91
|
}}
|
|
92
|
+
onclick={handleCloseOnClick}
|
|
75
93
|
class={cleanClass(
|
|
76
94
|
'fixed start-0 top-0 flex h-dvh w-screen items-center justify-center overflow-hidden sm:p-4',
|
|
77
95
|
)}
|
|
78
96
|
>
|
|
79
97
|
<div class={cleanClass('flex h-full w-full flex-col items-center justify-center')}>
|
|
80
|
-
<Card class={cleanClass(modalStyles({ size }), className)}>
|
|
98
|
+
<Card bind:ref={cardRef} class={cleanClass(modalStyles({ size }), className)}>
|
|
81
99
|
<CardHeader class="border-b border-gray-200 px-5 py-3 dark:border-white/10">
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
100
|
+
{#if headerChildren}
|
|
101
|
+
{@render headerChildren.snippet()}
|
|
102
|
+
{:else if title}
|
|
103
|
+
<div class="flex items-center justify-between gap-2">
|
|
104
|
+
{#if typeof icon === 'string'}
|
|
105
|
+
<Icon {icon} size="1.5rem" aria-hidden />
|
|
106
|
+
{:else if icon}
|
|
107
|
+
<Logo variant="icon" size="tiny" />
|
|
108
|
+
{/if}
|
|
109
|
+
<CardTitle tag="p" class="text-dark/90 grow text-lg font-semibold"
|
|
110
|
+
>{title}</CardTitle
|
|
111
|
+
>
|
|
112
|
+
<CloseButton class="-me-2" onclick={() => handleClose()} />
|
|
113
|
+
</div>
|
|
114
|
+
{/if}
|
|
91
115
|
</CardHeader>
|
|
92
116
|
|
|
93
117
|
<CardBody class="grow px-5">
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { ModalSize } from '../../types.js';
|
|
2
2
|
import { type Snippet } from 'svelte';
|
|
3
3
|
type Props = {
|
|
4
|
-
title
|
|
4
|
+
title?: string;
|
|
5
|
+
icon?: string | boolean;
|
|
5
6
|
size?: ModalSize;
|
|
6
7
|
class?: string;
|
|
7
|
-
icon?: string | boolean;
|
|
8
8
|
expandable?: boolean;
|
|
9
|
+
closeOnEsc?: boolean;
|
|
10
|
+
closeOnBackdropClick?: boolean;
|
|
9
11
|
children: Snippet;
|
|
10
12
|
onClose?: () => void;
|
|
11
13
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import IconButton from '../IconButton/IconButton.svelte';
|
|
3
|
-
import {
|
|
3
|
+
import { theme, toggleTheme } from '../../services/theme.svelte.js';
|
|
4
4
|
import { t } from '../../services/translation.svelte.js';
|
|
5
5
|
import {
|
|
6
6
|
Theme,
|
|
@@ -31,9 +31,8 @@
|
|
|
31
31
|
}: Props = $props();
|
|
32
32
|
|
|
33
33
|
const handleToggleTheme = () => {
|
|
34
|
-
|
|
34
|
+
toggleTheme();
|
|
35
35
|
onChange?.(theme.value);
|
|
36
|
-
onThemeChange();
|
|
37
36
|
};
|
|
38
37
|
|
|
39
38
|
const themeIcon = $derived(theme.value === Theme.Light ? mdiWeatherSunny : mdiWeatherNight);
|
package/dist/index.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export { default as Link } from './components/Link/Link.svelte';
|
|
|
39
39
|
export { default as LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner.svelte';
|
|
40
40
|
export { default as Logo } from './components/Logo/Logo.svelte';
|
|
41
41
|
export { default as Modal } from './components/Modal/Modal.svelte';
|
|
42
|
+
export { default as ModalHeader } from './components/Modal/ModalHeader.svelte';
|
|
42
43
|
export { default as ModalBody } from './components/Modal/ModalBody.svelte';
|
|
43
44
|
export { default as ModalFooter } from './components/Modal/ModalFooter.svelte';
|
|
44
45
|
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.svelte';
|
package/dist/index.js
CHANGED
|
@@ -41,6 +41,7 @@ export { default as Link } from './components/Link/Link.svelte';
|
|
|
41
41
|
export { default as LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner.svelte';
|
|
42
42
|
export { default as Logo } from './components/Logo/Logo.svelte';
|
|
43
43
|
export { default as Modal } from './components/Modal/Modal.svelte';
|
|
44
|
+
export { default as ModalHeader } from './components/Modal/ModalHeader.svelte';
|
|
44
45
|
export { default as ModalBody } from './components/Modal/ModalBody.svelte';
|
|
45
46
|
export { default as ModalFooter } from './components/Modal/ModalFooter.svelte';
|
|
46
47
|
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.svelte';
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
icon?: boolean;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
let {
|
|
17
|
+
ref = $bindable(null),
|
|
17
18
|
type = 'button',
|
|
18
19
|
href,
|
|
19
20
|
variant = 'filled',
|
|
@@ -152,7 +153,13 @@
|
|
|
152
153
|
{/snippet}
|
|
153
154
|
|
|
154
155
|
{#if href}
|
|
155
|
-
<a
|
|
156
|
+
<a
|
|
157
|
+
bind:this={ref}
|
|
158
|
+
{href}
|
|
159
|
+
class={classList}
|
|
160
|
+
aria-disabled={disabled}
|
|
161
|
+
{...restProps as HTMLAnchorAttributes}
|
|
162
|
+
>
|
|
156
163
|
{#if loading}
|
|
157
164
|
<div class="flex items-center justify-center gap-2">
|
|
158
165
|
<LoadingSpinner {color} size={spinnerSizes[size]} />
|
|
@@ -164,6 +171,7 @@
|
|
|
164
171
|
</a>
|
|
165
172
|
{:else}
|
|
166
173
|
<ButtonPrimitive.Root
|
|
174
|
+
bind:ref
|
|
167
175
|
class={classList}
|
|
168
176
|
type={type as HTMLButtonAttributes['type']}
|
|
169
177
|
{...restProps as HTMLButtonAttributes}
|
|
@@ -3,6 +3,6 @@ type InternalButtonProps = ButtonProps & {
|
|
|
3
3
|
/** when true, button width to height ratio is 1:1 */
|
|
4
4
|
icon?: boolean;
|
|
5
5
|
};
|
|
6
|
-
declare const Button: import("svelte").Component<InternalButtonProps, {}, "">;
|
|
6
|
+
declare const Button: import("svelte").Component<InternalButtonProps, {}, "ref">;
|
|
7
7
|
type Button = ReturnType<typeof Button>;
|
|
8
8
|
export default Button;
|
|
@@ -14,5 +14,6 @@ type ThemePreference = {
|
|
|
14
14
|
};
|
|
15
15
|
export declare const theme: ThemePreference;
|
|
16
16
|
export declare const onThemeChange: () => void;
|
|
17
|
+
export declare const toggleTheme: () => void;
|
|
17
18
|
export declare const initializeTheme: (options?: ThemeOptions) => void;
|
|
18
19
|
export {};
|
|
@@ -56,6 +56,10 @@ const syncToDom = () => {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
+
export const toggleTheme = () => {
|
|
60
|
+
theme.value = theme.value === Theme.Dark ? Theme.Light : Theme.Dark;
|
|
61
|
+
onThemeChange();
|
|
62
|
+
};
|
|
59
63
|
export const initializeTheme = (options) => {
|
|
60
64
|
if (options) {
|
|
61
65
|
setThemeOptions(options);
|
package/dist/types.d.ts
CHANGED