@immich/ui 0.22.8 → 0.23.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/Form/PasswordInput.svelte +2 -2
- package/dist/components/ThemeSwitcher/ThemeSwitcher.svelte +2 -2
- package/dist/components/ThemeSwitcher/ThemeSwitcher.svelte.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/internal/ConfirmModal.svelte +49 -0
- package/dist/internal/ConfirmModal.svelte.d.ts +15 -0
- package/dist/services/modalManager.svelte.d.ts +20 -0
- package/dist/services/modalManager.svelte.js +32 -0
- package/dist/services/translation.svelte.d.ts +6 -3
- package/dist/services/translation.svelte.js +6 -3
- package/dist/types.d.ts +1 -1
- package/package.json +4 -4
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
class="me-1"
|
|
27
27
|
icon={isVisible ? mdiEyeOffOutline : mdiEyeOutline}
|
|
28
28
|
onclick={() => (isVisible = !isVisible)}
|
|
29
|
-
title={isVisible ? t('
|
|
30
|
-
aria-label={t('
|
|
29
|
+
title={isVisible ? t('hide_password', translations) : t('show_password', translations)}
|
|
30
|
+
aria-label={t('show_password', translations)}
|
|
31
31
|
/>
|
|
32
32
|
{/if}
|
|
33
33
|
{/snippet}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
class?: string;
|
|
18
18
|
color?: Color;
|
|
19
19
|
variant?: Variants;
|
|
20
|
-
translations?: TranslationProps<'
|
|
20
|
+
translations?: TranslationProps<'dark_theme'>;
|
|
21
21
|
onChange?: (theme: Theme) => void;
|
|
22
22
|
};
|
|
23
23
|
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
icon={themeIcon}
|
|
48
48
|
onclick={handleToggleTheme}
|
|
49
49
|
class={cleanClass(className)}
|
|
50
|
-
aria-label={t('
|
|
50
|
+
aria-label={t('dark_theme', translations)}
|
|
51
51
|
role="switch"
|
|
52
52
|
aria-checked={theme.value === Theme.Dark}
|
|
53
53
|
/>
|
|
@@ -4,7 +4,7 @@ type Props = {
|
|
|
4
4
|
class?: string;
|
|
5
5
|
color?: Color;
|
|
6
6
|
variant?: Variants;
|
|
7
|
-
translations?: TranslationProps<'
|
|
7
|
+
translations?: TranslationProps<'dark_theme'>;
|
|
8
8
|
onChange?: (theme: Theme) => void;
|
|
9
9
|
};
|
|
10
10
|
declare const ThemeSwitcher: import("svelte").Component<Props, {}, "">;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Button, HStack, Modal, ModalBody, ModalFooter, t, type Color } from '../index.ts';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
title?: string;
|
|
7
|
+
prompt?: string;
|
|
8
|
+
confirmText?: string;
|
|
9
|
+
confirmColor?: Color;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
size?: 'small' | 'medium';
|
|
12
|
+
onClose: (confirmed: boolean) => void;
|
|
13
|
+
promptSnippet?: Snippet;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
title = t('confirm'),
|
|
18
|
+
prompt = t('prompt_default'),
|
|
19
|
+
confirmText = t('confirm'),
|
|
20
|
+
confirmColor = 'danger',
|
|
21
|
+
disabled = false,
|
|
22
|
+
size = 'small',
|
|
23
|
+
onClose,
|
|
24
|
+
promptSnippet,
|
|
25
|
+
}: Props = $props();
|
|
26
|
+
|
|
27
|
+
const handleConfirm = () => {
|
|
28
|
+
onClose(true);
|
|
29
|
+
};
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<Modal {title} onClose={() => onClose(false)} {size}>
|
|
33
|
+
<ModalBody>
|
|
34
|
+
{#if promptSnippet}{@render promptSnippet()}{:else}
|
|
35
|
+
<p>{prompt}</p>
|
|
36
|
+
{/if}
|
|
37
|
+
</ModalBody>
|
|
38
|
+
|
|
39
|
+
<ModalFooter>
|
|
40
|
+
<HStack fullWidth>
|
|
41
|
+
<Button shape="round" color="secondary" fullWidth onclick={() => onClose(false)}>
|
|
42
|
+
{t('cancel')}
|
|
43
|
+
</Button>
|
|
44
|
+
<Button shape="round" color={confirmColor} fullWidth onclick={handleConfirm} {disabled}>
|
|
45
|
+
{confirmText}
|
|
46
|
+
</Button>
|
|
47
|
+
</HStack>
|
|
48
|
+
</ModalFooter>
|
|
49
|
+
</Modal>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Color } from '../index.ts';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
interface Props {
|
|
4
|
+
title?: string;
|
|
5
|
+
prompt?: string;
|
|
6
|
+
confirmText?: string;
|
|
7
|
+
confirmColor?: Color;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
size?: 'small' | 'medium';
|
|
10
|
+
onClose: (confirmed: boolean) => void;
|
|
11
|
+
promptSnippet?: Snippet;
|
|
12
|
+
}
|
|
13
|
+
declare const ConfirmModal: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type ConfirmModal = ReturnType<typeof ConfirmModal>;
|
|
15
|
+
export default ConfirmModal;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Component, type ComponentProps } from 'svelte';
|
|
2
|
+
import ConfirmModal from '../internal/ConfirmModal.svelte';
|
|
3
|
+
type OnCloseData<T> = T extends {
|
|
4
|
+
onClose: (data?: infer R) => void;
|
|
5
|
+
} ? R | undefined : T extends {
|
|
6
|
+
onClose: (data: infer R) => void;
|
|
7
|
+
} ? R : never;
|
|
8
|
+
type ExtendsEmptyObject<T> = keyof T extends never ? never : T;
|
|
9
|
+
type StripValueIfOptional<T> = T extends undefined ? undefined : T;
|
|
10
|
+
type OptionalParamIfEmpty<T> = ExtendsEmptyObject<T> extends never ? [] | [Record<string, never> | undefined] : [T];
|
|
11
|
+
declare class ModalManager {
|
|
12
|
+
show<T extends object>(Component: Component<T>, ...props: OptionalParamIfEmpty<Omit<T, 'onClose'>>): Promise<StripValueIfOptional<OnCloseData<T>>>;
|
|
13
|
+
open<T extends object, K = OnCloseData<T>>(Component: Component<T>, ...props: OptionalParamIfEmpty<Omit<T, 'onClose'>>): {
|
|
14
|
+
onClose: Promise<StripValueIfOptional<K>>;
|
|
15
|
+
close: (args_0: StripValueIfOptional<K>) => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
showDialog(options: Omit<ComponentProps<typeof ConfirmModal>, 'onClose'>): Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
export declare const modalManager: ModalManager;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { mount, unmount } from 'svelte';
|
|
2
|
+
import ConfirmModal from '../internal/ConfirmModal.svelte';
|
|
3
|
+
class ModalManager {
|
|
4
|
+
show(Component, ...props) {
|
|
5
|
+
return this.open(Component, ...props).onClose;
|
|
6
|
+
}
|
|
7
|
+
open(Component, ...props) {
|
|
8
|
+
let modal = {};
|
|
9
|
+
let onClose;
|
|
10
|
+
const deferred = new Promise((resolve) => {
|
|
11
|
+
onClose = async (...args) => {
|
|
12
|
+
await unmount(modal);
|
|
13
|
+
resolve(args?.[0]);
|
|
14
|
+
};
|
|
15
|
+
modal = mount(Component, {
|
|
16
|
+
target: document.body,
|
|
17
|
+
props: {
|
|
18
|
+
...(props?.[0] ?? {}),
|
|
19
|
+
onClose,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
onClose: deferred,
|
|
25
|
+
close: (...args) => onClose(args[0]),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
showDialog(options) {
|
|
29
|
+
return this.show(ConfirmModal, options);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export const modalManager = new ModalManager();
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { TranslationProps } from '../types.js';
|
|
2
2
|
declare const defaultTranslations: {
|
|
3
3
|
close: string;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
show_password: string;
|
|
5
|
+
hide_password: string;
|
|
6
|
+
dark_theme: string;
|
|
7
|
+
confirm: string;
|
|
8
|
+
prompt_default: string;
|
|
9
|
+
cancel: string;
|
|
7
10
|
};
|
|
8
11
|
export type Translations = typeof defaultTranslations;
|
|
9
12
|
export declare const translate: <T extends keyof Translations>(key: T, overrides?: TranslationProps<T>) => string;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
const defaultTranslations = {
|
|
2
2
|
close: 'Close',
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
show_password: 'Show password',
|
|
4
|
+
hide_password: 'Hide password',
|
|
5
|
+
dark_theme: 'Toggle dark theme',
|
|
6
|
+
confirm: 'Confirm',
|
|
7
|
+
prompt_default: 'Are you sure you want to do this?',
|
|
8
|
+
cancel: 'Cancel',
|
|
6
9
|
};
|
|
7
10
|
let translations = $state(defaultTranslations);
|
|
8
11
|
export const translate = (key, overrides) => overrides?.[key] ?? translations[key];
|
package/dist/types.d.ts
CHANGED
|
@@ -109,7 +109,7 @@ export type InputProps = BaseInputProps & {
|
|
|
109
109
|
trailingIcon?: Snippet;
|
|
110
110
|
};
|
|
111
111
|
export type PasswordInputProps = BaseInputProps & {
|
|
112
|
-
translations?: TranslationProps<'
|
|
112
|
+
translations?: TranslationProps<'show_password' | 'hide_password'>;
|
|
113
113
|
isVisible?: boolean;
|
|
114
114
|
};
|
|
115
115
|
export type SelectItem = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@immich/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"license": "GNU Affero General Public License version 3",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"create": "node scripts/create.js",
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"@sveltejs/adapter-static": "^3.0.6",
|
|
45
45
|
"@sveltejs/kit": "^2.13.0",
|
|
46
46
|
"@sveltejs/package": "^2.0.0",
|
|
47
|
-
"@sveltejs/vite-plugin-svelte": "^5.0
|
|
47
|
+
"@sveltejs/vite-plugin-svelte": "^5.1.0",
|
|
48
48
|
"@tailwindcss/postcss": "^4.1.7",
|
|
49
49
|
"@tailwindcss/vite": "^4.1.7",
|
|
50
50
|
"@types/eslint": "^9.6.0",
|
|
51
51
|
"autoprefixer": "^10.4.20",
|
|
52
52
|
"eslint": "^9.7.0",
|
|
53
53
|
"eslint-config-prettier": "^10.0.0",
|
|
54
|
-
"eslint-plugin-svelte": "^
|
|
54
|
+
"eslint-plugin-svelte": "^3.9.3",
|
|
55
55
|
"globals": "^16.0.0",
|
|
56
56
|
"prettier": "^3.3.2",
|
|
57
57
|
"prettier-plugin-svelte": "^3.2.6",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"svelte-highlight": "^7.8.0",
|
|
63
63
|
"tailwindcss": "^4.1.7",
|
|
64
64
|
"typescript": "^5.0.0",
|
|
65
|
-
"typescript-eslint": "^8.
|
|
65
|
+
"typescript-eslint": "^8.34.1",
|
|
66
66
|
"vite": "^6.0.3",
|
|
67
67
|
"vitest": "^3.0.0"
|
|
68
68
|
},
|