@immich/ui 0.9.0 → 0.11.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/common/use-child.svelte.d.ts +2 -2
- package/dist/common/use-child.svelte.js +3 -9
- package/dist/components/Alert/Alert.svelte +6 -6
- package/dist/components/AppShell/AppShell.svelte +2 -2
- package/dist/components/Avatar/Avatar.svelte +6 -6
- package/dist/components/Card/Card.svelte +84 -109
- package/dist/components/Card/Card.svelte.d.ts +4 -4
- package/dist/components/Card/CardBody.svelte +2 -6
- package/dist/components/Card/CardFooter.svelte +4 -7
- package/dist/components/Card/CardFooter.svelte.d.ts +1 -1
- package/dist/components/Card/CardHeader.svelte +3 -2
- package/dist/components/Card/CardHeader.svelte.d.ts +1 -0
- package/dist/components/CloseButton/CloseButton.svelte +16 -2
- package/dist/components/Code/Code.svelte +1 -1
- package/dist/components/Form/Checkbox.svelte +1 -1
- package/dist/components/Form/Field.svelte +3 -2
- package/dist/components/Form/Input.svelte +1 -1
- package/dist/components/Form/PasswordInput.svelte +3 -3
- package/dist/components/Heading/Heading.svelte +1 -1
- package/dist/components/Kbd/Kbd.svelte +33 -0
- package/dist/components/Kbd/Kbd.svelte.d.ts +10 -0
- package/dist/components/Modal/Modal.svelte +88 -0
- package/dist/components/Modal/Modal.svelte.d.ts +16 -0
- package/dist/components/Modal/ModalBody.svelte +15 -0
- package/dist/components/Modal/ModalBody.svelte.d.ts +5 -0
- package/dist/components/Modal/ModalFooter.svelte +15 -0
- package/dist/components/Modal/ModalFooter.svelte.d.ts +5 -0
- package/dist/components/Modal/ModalHeader.svelte +15 -0
- package/dist/components/Modal/ModalHeader.svelte.d.ts +5 -0
- package/dist/components/Navbar/NavbarItem.svelte +1 -1
- package/dist/components/SupporterBadge/SupporterBadge.svelte +3 -3
- package/dist/components/Switch/Switch.svelte +2 -2
- package/dist/components/ThemeSwitcher/ThemeSwitcher.svelte +33 -0
- package/dist/components/ThemeSwitcher/ThemeSwitcher.svelte.d.ts +8 -0
- package/dist/constants.d.ts +5 -1
- package/dist/constants.js +4 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/internal/Button.svelte +7 -7
- package/dist/internal/Child.svelte +10 -3
- package/dist/internal/Child.svelte.d.ts +1 -0
- package/dist/services/translation.svelte.d.ts +11 -0
- package/dist/services/translation.svelte.js +11 -0
- package/dist/types.d.ts +11 -2
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChildKey } from '../constants.js';
|
|
2
|
-
import {
|
|
2
|
+
import type { ChildData } from '../types.js';
|
|
3
3
|
export declare const withChildrenSnippets: (key: ChildKey) => {
|
|
4
|
-
getChildren: (key: ChildKey) =>
|
|
4
|
+
getChildren: (key: ChildKey) => ChildData | undefined;
|
|
5
5
|
};
|
|
@@ -3,17 +3,11 @@ import { withPrefix } from '../utils.js';
|
|
|
3
3
|
import { setContext } from 'svelte';
|
|
4
4
|
import { SvelteMap } from 'svelte/reactivity';
|
|
5
5
|
export const withChildrenSnippets = (key) => {
|
|
6
|
-
const map =
|
|
6
|
+
const map = new SvelteMap();
|
|
7
7
|
setContext(withPrefix(key), {
|
|
8
|
-
register:
|
|
9
|
-
if (map.has(child)) {
|
|
10
|
-
console.warn(`Snippet with key ${child} already exists in the context`);
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
map.set(child, snippet);
|
|
14
|
-
},
|
|
8
|
+
register: (child, data) => map.set(child, data),
|
|
15
9
|
});
|
|
16
10
|
return {
|
|
17
|
-
getChildren: (key) => map.get(key),
|
|
11
|
+
getChildren: (key) => map.get(key)?.(),
|
|
18
12
|
};
|
|
19
13
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Card from '../Card/Card.svelte';
|
|
3
|
-
import
|
|
3
|
+
import CardBody from '../Card/CardBody.svelte';
|
|
4
|
+
import CloseButton from '../CloseButton/CloseButton.svelte';
|
|
4
5
|
import Icon from '../Icon/Icon.svelte';
|
|
5
6
|
import Text from '../Text/Text.svelte';
|
|
6
|
-
import CloseButton from '../CloseButton/CloseButton.svelte';
|
|
7
7
|
import type { Color, Size } from '../../types.js';
|
|
8
8
|
import { cleanClass } from '../../utils.js';
|
|
9
9
|
import {
|
|
@@ -78,9 +78,9 @@
|
|
|
78
78
|
</script>
|
|
79
79
|
|
|
80
80
|
{#if open}
|
|
81
|
-
<Card {color}
|
|
82
|
-
<
|
|
83
|
-
<div class="flex justify-between">
|
|
81
|
+
<Card {color} class={cleanClass(className)}>
|
|
82
|
+
<CardBody>
|
|
83
|
+
<div class="flex items-center justify-between">
|
|
84
84
|
<div class={cleanClass('flex gap-2')}>
|
|
85
85
|
{#if icon}
|
|
86
86
|
<div>
|
|
@@ -103,6 +103,6 @@
|
|
|
103
103
|
</div>
|
|
104
104
|
{/if}
|
|
105
105
|
</div>
|
|
106
|
-
</
|
|
106
|
+
</CardBody>
|
|
107
107
|
</Card>
|
|
108
108
|
{/if}
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
<div class={cleanClass('flex h-screen flex-col overflow-hidden', className)}>
|
|
21
21
|
{#if header}
|
|
22
22
|
<header class="border-b">
|
|
23
|
-
{@render header?.()}
|
|
23
|
+
{@render header?.snippet()}
|
|
24
24
|
</header>
|
|
25
25
|
{/if}
|
|
26
26
|
<div class="flex w-full grow overflow-y-auto">
|
|
27
27
|
{#if sidebar}
|
|
28
|
-
{@render sidebar()}
|
|
28
|
+
{@render sidebar?.snippet()}
|
|
29
29
|
{/if}
|
|
30
30
|
<Scrollable class="grow">
|
|
31
31
|
{@render children?.()}
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
base: 'flex h-full w-full select-none items-center justify-center font-medium',
|
|
25
25
|
variants: {
|
|
26
26
|
size: {
|
|
27
|
-
tiny: '
|
|
28
|
-
small: '
|
|
29
|
-
medium: '
|
|
30
|
-
large: '
|
|
31
|
-
giant: '
|
|
27
|
+
tiny: 'h-5 w-5 text-xs',
|
|
28
|
+
small: 'h-7 w-7 text-sm',
|
|
29
|
+
medium: 'text-md h-10 w-10',
|
|
30
|
+
large: 'h-12 w-12 text-lg',
|
|
31
|
+
giant: 'h-16 w-16 text-xl',
|
|
32
32
|
},
|
|
33
33
|
color: {
|
|
34
34
|
primary: 'bg-primary text-light',
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
const wrapper = tv({
|
|
49
|
-
base: 'overflow-hidden shadow-md
|
|
49
|
+
base: 'overflow-hidden rounded-full shadow-md',
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
const getInitials = (name: string) => {
|
|
@@ -1,50 +1,54 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { withChildrenSnippets } from '../../common/use-child.svelte.js';
|
|
3
3
|
import IconButton from '../IconButton/IconButton.svelte';
|
|
4
|
+
import Scrollable from '../Scrollable/Scrollable.svelte';
|
|
4
5
|
import { ChildKey } from '../../constants.js';
|
|
5
|
-
import type { Color
|
|
6
|
+
import type { Color } from '../../types.js';
|
|
6
7
|
import { cleanClass } from '../../utils.js';
|
|
7
8
|
import { mdiChevronDown } from '@mdi/js';
|
|
8
9
|
import { type Snippet } from 'svelte';
|
|
9
10
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
11
|
+
import { twMerge } from 'tailwind-merge';
|
|
10
12
|
import { tv } from 'tailwind-variants';
|
|
11
13
|
|
|
12
14
|
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
13
15
|
color?: Color;
|
|
14
|
-
shape?:
|
|
15
|
-
|
|
16
|
+
shape?: 'round' | 'rectangle';
|
|
17
|
+
expanded?: boolean;
|
|
16
18
|
expandable?: boolean;
|
|
17
19
|
children: Snippet;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
let {
|
|
21
|
-
color
|
|
23
|
+
color,
|
|
22
24
|
class: className,
|
|
25
|
+
shape = 'round',
|
|
26
|
+
expanded = $bindable(true),
|
|
23
27
|
expandable = false,
|
|
24
|
-
variant,
|
|
25
28
|
children,
|
|
26
29
|
...restProps
|
|
27
30
|
}: Props = $props();
|
|
28
31
|
|
|
29
|
-
const
|
|
30
|
-
base: '
|
|
32
|
+
const containerStyles = tv({
|
|
33
|
+
base: 'w-full overflow-hidden bg-light text-dark shadow-sm',
|
|
31
34
|
variants: {
|
|
32
|
-
|
|
35
|
+
shape: {
|
|
36
|
+
rectangle: '',
|
|
37
|
+
round: 'rounded-2xl',
|
|
38
|
+
},
|
|
39
|
+
border: {
|
|
33
40
|
true: 'border',
|
|
34
41
|
false: '',
|
|
35
|
-
default: '',
|
|
36
42
|
},
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
},
|
|
45
|
-
subtleColor: {
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const cardStyles = tv({
|
|
47
|
+
base: 'flex h-full w-full flex-col',
|
|
48
|
+
variants: {
|
|
49
|
+
color: {
|
|
46
50
|
primary: 'bg-primary/25 dark:bg-primary/25',
|
|
47
|
-
secondary: 'bg-dark/5 dark:bg-dark/25
|
|
51
|
+
secondary: 'bg-dark/5 text-dark dark:bg-dark/25',
|
|
48
52
|
success: 'bg-success/15 dark:bg-success/30',
|
|
49
53
|
danger: 'bg-danger/15 dark:bg-danger/50',
|
|
50
54
|
warning: 'bg-warning/25 dark:bg-warning/50',
|
|
@@ -54,132 +58,103 @@
|
|
|
54
58
|
});
|
|
55
59
|
|
|
56
60
|
const headerContainerStyles = tv({
|
|
61
|
+
base: 'p-4',
|
|
57
62
|
variants: {
|
|
58
|
-
|
|
63
|
+
padding: {
|
|
59
64
|
true: '',
|
|
60
65
|
false: 'pb-0',
|
|
61
66
|
},
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
success: 'bg-success text-light rounded-t-xl',
|
|
66
|
-
danger: 'bg-danger text-light rounded-t-xl',
|
|
67
|
-
warning: 'bg-warning text-black rounded-t-xl',
|
|
68
|
-
info: 'bg-info text-light rounded-t-xl',
|
|
69
|
-
},
|
|
70
|
-
outlineColor: {
|
|
71
|
-
primary: 'text-primary',
|
|
72
|
-
secondary: 'text-dark',
|
|
73
|
-
success: 'text-success',
|
|
74
|
-
danger: 'text-danger',
|
|
75
|
-
warning: 'text-warning',
|
|
76
|
-
info: 'text-info',
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const iconStyles = tv({
|
|
82
|
-
variants: {
|
|
83
|
-
filledColor: {
|
|
84
|
-
primary: 'text-light',
|
|
85
|
-
secondary: 'text-light',
|
|
86
|
-
success: 'text-light',
|
|
87
|
-
danger: 'text-light',
|
|
88
|
-
warning: 'text-dark',
|
|
89
|
-
info: 'text-light',
|
|
90
|
-
},
|
|
91
|
-
outlineColor: {
|
|
92
|
-
primary: 'text-primary',
|
|
93
|
-
secondary: 'text-dark',
|
|
94
|
-
success: 'text-success',
|
|
95
|
-
danger: 'text-danger',
|
|
96
|
-
warning: 'text-warning',
|
|
97
|
-
info: 'text-info',
|
|
67
|
+
border: {
|
|
68
|
+
true: 'border-b',
|
|
69
|
+
false: '',
|
|
98
70
|
},
|
|
99
71
|
},
|
|
100
72
|
});
|
|
101
73
|
|
|
102
|
-
let expanded = $state(!expandable);
|
|
103
74
|
const onToggle = () => {
|
|
104
75
|
expanded = !expanded;
|
|
105
76
|
};
|
|
106
77
|
|
|
107
78
|
const { getChildren: getChildSnippet } = withChildrenSnippets(ChildKey.Card);
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
const
|
|
79
|
+
const headerChild = $derived(getChildSnippet(ChildKey.CardHeader));
|
|
80
|
+
const bodyChild = $derived(getChildSnippet(ChildKey.CardBody));
|
|
81
|
+
const footerChild = $derived(getChildSnippet(ChildKey.CardFooter));
|
|
82
|
+
|
|
83
|
+
const headerBorder = $derived(!color);
|
|
84
|
+
const headerPadding = $derived(headerBorder || !expanded);
|
|
111
85
|
|
|
112
|
-
const headerClasses = 'flex flex-col space-y-1.5';
|
|
113
86
|
const headerContainerClasses = $derived(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
87
|
+
twMerge(
|
|
88
|
+
cleanClass(
|
|
89
|
+
headerContainerStyles({
|
|
90
|
+
padding: headerPadding,
|
|
91
|
+
border: headerBorder,
|
|
92
|
+
}),
|
|
93
|
+
headerChild?.class,
|
|
94
|
+
),
|
|
120
95
|
),
|
|
121
96
|
);
|
|
122
97
|
</script>
|
|
123
98
|
|
|
124
99
|
{#snippet header()}
|
|
125
100
|
{#if expandable}
|
|
126
|
-
<button
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
</div>
|
|
101
|
+
<button
|
|
102
|
+
type="button"
|
|
103
|
+
onclick={onToggle}
|
|
104
|
+
class={cleanClass('flex w-full items-center justify-between px-4', headerContainerClasses)}
|
|
105
|
+
>
|
|
106
|
+
<div class="flex flex-col">
|
|
107
|
+
{@render headerChild?.snippet()}
|
|
108
|
+
</div>
|
|
109
|
+
<div>
|
|
110
|
+
<IconButton
|
|
111
|
+
color="secondary"
|
|
112
|
+
icon={mdiChevronDown}
|
|
113
|
+
flopped={expanded}
|
|
114
|
+
variant="ghost"
|
|
115
|
+
shape="round"
|
|
116
|
+
size="large"
|
|
117
|
+
/>
|
|
144
118
|
</div>
|
|
145
119
|
</button>
|
|
146
120
|
{:else}
|
|
147
|
-
<div class={cleanClass(
|
|
148
|
-
{@render
|
|
121
|
+
<div class={cleanClass('flex flex-col', headerContainerClasses)}>
|
|
122
|
+
{@render headerChild?.snippet()}
|
|
149
123
|
</div>
|
|
150
124
|
{/if}
|
|
151
125
|
{/snippet}
|
|
152
126
|
|
|
153
|
-
{#snippet body()}
|
|
154
|
-
{@render bodyChildren?.()}
|
|
155
|
-
{/snippet}
|
|
156
|
-
|
|
157
|
-
{#snippet footer()}
|
|
158
|
-
{@render footerChildren?.()}
|
|
159
|
-
{/snippet}
|
|
160
|
-
|
|
161
127
|
<div
|
|
162
128
|
class={cleanClass(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
subtleColor: variant === 'subtle' ? color : undefined,
|
|
129
|
+
containerStyles({
|
|
130
|
+
shape,
|
|
131
|
+
border: !color,
|
|
167
132
|
}),
|
|
168
133
|
className,
|
|
169
134
|
)}
|
|
170
135
|
{...restProps}
|
|
171
136
|
>
|
|
172
|
-
{
|
|
173
|
-
{
|
|
174
|
-
|
|
137
|
+
<div class={cleanClass(cardStyles({ color }))}>
|
|
138
|
+
{#if headerChild}
|
|
139
|
+
{@render header()}
|
|
140
|
+
{/if}
|
|
175
141
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
142
|
+
{#if bodyChild && expanded}
|
|
143
|
+
<Scrollable class={twMerge(cleanClass('p-4', bodyChild?.class))}>
|
|
144
|
+
{@render bodyChild?.snippet()}
|
|
145
|
+
</Scrollable>
|
|
146
|
+
{/if}
|
|
179
147
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
148
|
+
{#if footerChild}
|
|
149
|
+
<div
|
|
150
|
+
class={twMerge(
|
|
151
|
+
cleanClass('flex items-center border-t border-t-subtle p-4', footerChild.class),
|
|
152
|
+
)}
|
|
153
|
+
>
|
|
154
|
+
{@render footerChild.snippet()}
|
|
155
|
+
</div>
|
|
156
|
+
{/if}
|
|
183
157
|
|
|
184
|
-
|
|
158
|
+
{@render children()}
|
|
159
|
+
</div>
|
|
185
160
|
</div>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { Color
|
|
1
|
+
import type { Color } from '../../types.js';
|
|
2
2
|
import { type Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
declare const Card: import("svelte").Component<HTMLAttributes<HTMLDivElement> & {
|
|
5
5
|
color?: Color;
|
|
6
|
-
shape?:
|
|
7
|
-
|
|
6
|
+
shape?: "round" | "rectangle";
|
|
7
|
+
expanded?: boolean;
|
|
8
8
|
expandable?: boolean;
|
|
9
9
|
children: Snippet;
|
|
10
|
-
}, {}, "">;
|
|
10
|
+
}, {}, "expanded">;
|
|
11
11
|
export default Card;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { ChildKey } from '../../constants.js';
|
|
3
3
|
import Child from '../../internal/Child.svelte';
|
|
4
|
-
import { cleanClass } from '../../utils.js';
|
|
5
4
|
import type { Snippet } from 'svelte';
|
|
6
|
-
import { twMerge } from 'tailwind-merge';
|
|
7
5
|
|
|
8
6
|
type Props = {
|
|
9
7
|
class?: string;
|
|
@@ -13,8 +11,6 @@
|
|
|
13
11
|
let { class: className, children }: Props = $props();
|
|
14
12
|
</script>
|
|
15
13
|
|
|
16
|
-
<Child for={ChildKey.Card} as={ChildKey.CardBody}>
|
|
17
|
-
|
|
18
|
-
{@render children?.()}
|
|
19
|
-
</div>
|
|
14
|
+
<Child for={ChildKey.Card} as={ChildKey.CardBody} class={className}>
|
|
15
|
+
{@render children?.()}
|
|
20
16
|
</Child>
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { ChildKey } from '../../constants.js';
|
|
3
3
|
import Child from '../../internal/Child.svelte';
|
|
4
|
-
import { cleanClass } from '../../utils.js';
|
|
5
4
|
import type { Snippet } from 'svelte';
|
|
6
5
|
|
|
7
6
|
type Props = {
|
|
8
|
-
children: Snippet;
|
|
9
7
|
class?: string;
|
|
8
|
+
children: Snippet;
|
|
10
9
|
};
|
|
11
10
|
|
|
12
|
-
let {
|
|
11
|
+
let { class: className, children }: Props = $props();
|
|
13
12
|
</script>
|
|
14
13
|
|
|
15
|
-
<Child for={ChildKey.Card} as={ChildKey.CardFooter}>
|
|
16
|
-
|
|
17
|
-
{@render children?.()}
|
|
18
|
-
</div>
|
|
14
|
+
<Child for={ChildKey.Card} as={ChildKey.CardFooter} class={className}>
|
|
15
|
+
{@render children?.()}
|
|
19
16
|
</Child>
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
|
|
6
6
|
type Props = {
|
|
7
|
+
class?: string;
|
|
7
8
|
children: Snippet;
|
|
8
9
|
};
|
|
9
10
|
|
|
10
|
-
let { children }: Props = $props();
|
|
11
|
+
let { class: className, children }: Props = $props();
|
|
11
12
|
</script>
|
|
12
13
|
|
|
13
|
-
<Child for={ChildKey.Card} as={ChildKey.CardHeader}>
|
|
14
|
+
<Child for={ChildKey.Card} as={ChildKey.CardHeader} class={className}>
|
|
14
15
|
{@render children?.()}
|
|
15
16
|
</Child>
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import IconButton from '../IconButton/IconButton.svelte';
|
|
3
|
+
import { t } from '../../services/translation.svelte.js';
|
|
3
4
|
import type { CloseButtonProps } from '../../types.js';
|
|
4
5
|
import { mdiClose } from '@mdi/js';
|
|
5
6
|
|
|
6
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
size = 'medium',
|
|
9
|
+
variant = 'ghost',
|
|
10
|
+
translations,
|
|
11
|
+
...restProps
|
|
12
|
+
}: CloseButtonProps = $props();
|
|
7
13
|
</script>
|
|
8
14
|
|
|
9
|
-
<IconButton
|
|
15
|
+
<IconButton
|
|
16
|
+
{...restProps}
|
|
17
|
+
icon={mdiClose}
|
|
18
|
+
shape="round"
|
|
19
|
+
{variant}
|
|
20
|
+
{size}
|
|
21
|
+
color="secondary"
|
|
22
|
+
title={t('close', translations)}
|
|
23
|
+
/>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
} = $derived(getFieldContext());
|
|
33
33
|
|
|
34
34
|
const containerStyles = tv({
|
|
35
|
-
base: '
|
|
35
|
+
base: 'ring-offset-background focus-visible:ring-ring peer box-content overflow-hidden border-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[disabled=true]:cursor-not-allowed data-[state=checked]:bg-primary data-[disabled=true]:opacity-50',
|
|
36
36
|
variants: {
|
|
37
37
|
shape: {
|
|
38
38
|
rectangle: 'rounded-none',
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { withChildrenSnippets } from '../../common/use-child.svelte.js';
|
|
4
4
|
import { ChildKey } from '../../constants.js';
|
|
5
5
|
import type { FieldContext } from '../../types.js';
|
|
6
|
+
import { cleanClass } from '../../utils.js';
|
|
6
7
|
import { type Snippet } from 'svelte';
|
|
7
8
|
|
|
8
9
|
type Props = FieldContext & {
|
|
@@ -22,8 +23,8 @@
|
|
|
22
23
|
<div>
|
|
23
24
|
{@render children()}
|
|
24
25
|
{#if helperTextChildren}
|
|
25
|
-
<div class=
|
|
26
|
-
{@render helperTextChildren
|
|
26
|
+
<div class={cleanClass('pt-1', helperTextChildren.class)}>
|
|
27
|
+
{@render helperTextChildren.snippet()}
|
|
27
28
|
</div>
|
|
28
29
|
{/if}
|
|
29
30
|
</div>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
const inputStyles = tv({
|
|
39
|
-
base: 'w-full outline-none disabled:cursor-not-allowed
|
|
39
|
+
base: 'w-full bg-gray-200 outline-none disabled:cursor-not-allowed disabled:bg-gray-300 disabled:text-gray-200 aria-readonly:text-dark/50 dark:bg-gray-600 dark:disabled:bg-gray-800 dark:aria-readonly:text-dark/75',
|
|
40
40
|
variants: {
|
|
41
41
|
shape: {
|
|
42
42
|
rectangle: 'rounded-none',
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Input from './Input.svelte';
|
|
3
3
|
import IconButton from '../IconButton/IconButton.svelte';
|
|
4
|
+
import { t } from '../../services/translation.svelte.js';
|
|
4
5
|
import type { PasswordInputProps } from '../../types.js';
|
|
5
6
|
import { mdiEyeOffOutline, mdiEyeOutline } from '@mdi/js';
|
|
6
7
|
|
|
7
8
|
let {
|
|
8
9
|
value = $bindable<string>(),
|
|
9
|
-
|
|
10
|
-
hideLabel = 'Hide password',
|
|
10
|
+
translations,
|
|
11
11
|
isVisible = $bindable<boolean>(false),
|
|
12
12
|
color = 'secondary',
|
|
13
13
|
...props
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
class="m-1"
|
|
25
25
|
icon={isVisible ? mdiEyeOffOutline : mdiEyeOutline}
|
|
26
26
|
onclick={() => (isVisible = !isVisible)}
|
|
27
|
-
title={isVisible ?
|
|
27
|
+
title={isVisible ? t('hidePassword', translations) : t('showPassword', translations)}
|
|
28
28
|
></IconButton>
|
|
29
29
|
{/if}
|
|
30
30
|
{/snippet}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Color, Size } from '../../types.js';
|
|
3
|
+
import { cleanClass } from '../../utils.js';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
6
|
+
import { tv } from 'tailwind-variants';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
size?: Size;
|
|
10
|
+
color?: Color;
|
|
11
|
+
class?: string;
|
|
12
|
+
children?: Snippet;
|
|
13
|
+
} & HTMLAttributes<HTMLElement>;
|
|
14
|
+
|
|
15
|
+
const { class: className, size = 'small', children, ...restProps }: Props = $props();
|
|
16
|
+
|
|
17
|
+
const styles = tv({
|
|
18
|
+
base: 'flex flex-col rounded-md border border-b-2 bg-subtle px-1 font-mono text-dark shadow',
|
|
19
|
+
variants: {
|
|
20
|
+
size: {
|
|
21
|
+
tiny: 'text-xs',
|
|
22
|
+
small: 'text-sm',
|
|
23
|
+
medium: 'text-md',
|
|
24
|
+
large: 'text-lg',
|
|
25
|
+
giant: 'text-xl',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<kbd class={cleanClass(styles({ size }), className)} {...restProps}>
|
|
32
|
+
{@render children?.()}
|
|
33
|
+
</kbd>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Color, Size } from '../../types.js';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
declare const Kbd: import("svelte").Component<{
|
|
5
|
+
size?: Size;
|
|
6
|
+
color?: Color;
|
|
7
|
+
class?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
} & HTMLAttributes<HTMLElement>, {}, "">;
|
|
10
|
+
export default Kbd;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { withChildrenSnippets } from '../../common/use-child.svelte.js';
|
|
3
|
+
import Card from '../Card/Card.svelte';
|
|
4
|
+
import CardBody from '../Card/CardBody.svelte';
|
|
5
|
+
import CardFooter from '../Card/CardFooter.svelte';
|
|
6
|
+
import CardHeader from '../Card/CardHeader.svelte';
|
|
7
|
+
import CardTitle from '../Card/CardTitle.svelte';
|
|
8
|
+
import CloseButton from '../CloseButton/CloseButton.svelte';
|
|
9
|
+
import { ChildKey } from '../../constants.js';
|
|
10
|
+
import type { ModalSize } from '../../types.js';
|
|
11
|
+
import { cleanClass } from '../../utils.js';
|
|
12
|
+
import { Dialog } from 'bits-ui';
|
|
13
|
+
import { type Snippet } from 'svelte';
|
|
14
|
+
import { tv } from 'tailwind-variants';
|
|
15
|
+
|
|
16
|
+
type Props = Dialog.RootProps & {
|
|
17
|
+
title: string;
|
|
18
|
+
size?: ModalSize;
|
|
19
|
+
class?: string;
|
|
20
|
+
open?: boolean;
|
|
21
|
+
expandable?: boolean;
|
|
22
|
+
children: Snippet;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
title,
|
|
27
|
+
size = 'medium',
|
|
28
|
+
open = $bindable(true),
|
|
29
|
+
class: className,
|
|
30
|
+
children,
|
|
31
|
+
...restProps
|
|
32
|
+
}: Props = $props();
|
|
33
|
+
|
|
34
|
+
const modalStyles = tv({
|
|
35
|
+
base: 'flex rounded-none border border-subtle bg-subtle sm:rounded-2xl',
|
|
36
|
+
variants: {
|
|
37
|
+
size: {
|
|
38
|
+
tiny: 'h-full sm:h-min md:max-w-64',
|
|
39
|
+
small: 'h-full sm:h-min md:max-w-96',
|
|
40
|
+
medium: 'h-full sm:h-min md:max-w-screen-sm',
|
|
41
|
+
large: 'h-full sm:h-min md:max-w-screen-md',
|
|
42
|
+
giant: 'h-full sm:h-min md:max-w-screen-lg',
|
|
43
|
+
full: 'h-full w-full',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const { getChildren: getChildSnippet } = withChildrenSnippets(ChildKey.Modal);
|
|
49
|
+
const bodyChildren = $derived(getChildSnippet(ChildKey.ModalBody));
|
|
50
|
+
const footerChildren = $derived(getChildSnippet(ChildKey.ModalFooter));
|
|
51
|
+
|
|
52
|
+
const handleClose = () => {
|
|
53
|
+
open = false;
|
|
54
|
+
};
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<Dialog.Root bind:open {...restProps}>
|
|
58
|
+
<Dialog.Portal>
|
|
59
|
+
<Dialog.Overlay class="absolute left-0 top-0 flex h-screen w-screen backdrop-blur" />
|
|
60
|
+
<Dialog.Content
|
|
61
|
+
class={cleanClass(
|
|
62
|
+
'absolute left-0 top-0 flex h-dvh w-screen items-center justify-center overflow-hidden sm:p-4',
|
|
63
|
+
)}
|
|
64
|
+
>
|
|
65
|
+
<div class={cleanClass('flex h-full w-full flex-col items-center justify-center ')}>
|
|
66
|
+
<Card class={cleanClass(modalStyles({ size }), className)}>
|
|
67
|
+
<CardHeader class="border-0 py-2">
|
|
68
|
+
<div class="flex items-center justify-between">
|
|
69
|
+
<CardTitle>{title}</CardTitle>
|
|
70
|
+
<CloseButton size="large" onclick={handleClose} />
|
|
71
|
+
</div>
|
|
72
|
+
</CardHeader>
|
|
73
|
+
|
|
74
|
+
<CardBody class="grow py-2">
|
|
75
|
+
{@render bodyChildren?.snippet()}
|
|
76
|
+
</CardBody>
|
|
77
|
+
|
|
78
|
+
{#if footerChildren}
|
|
79
|
+
<CardFooter class="py-2">
|
|
80
|
+
{@render footerChildren.snippet()}
|
|
81
|
+
</CardFooter>
|
|
82
|
+
{/if}
|
|
83
|
+
</Card>
|
|
84
|
+
</div>
|
|
85
|
+
</Dialog.Content>
|
|
86
|
+
</Dialog.Portal>
|
|
87
|
+
</Dialog.Root>
|
|
88
|
+
{@render children?.()}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ModalSize } from '../../types.js';
|
|
2
|
+
import { type Snippet } from 'svelte';
|
|
3
|
+
declare const Modal: import("svelte").Component<{
|
|
4
|
+
open?: boolean;
|
|
5
|
+
onOpenChange?: import("bits-ui/dist/internal/types").OnChangeFn<boolean>;
|
|
6
|
+
} & {
|
|
7
|
+
children?: Snippet | undefined;
|
|
8
|
+
} & {
|
|
9
|
+
title: string;
|
|
10
|
+
size?: ModalSize;
|
|
11
|
+
class?: string;
|
|
12
|
+
open?: boolean;
|
|
13
|
+
expandable?: boolean;
|
|
14
|
+
children: Snippet;
|
|
15
|
+
}, {}, "open">;
|
|
16
|
+
export default Modal;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { ChildKey } from '../../constants.js';
|
|
3
|
+
import Child from '../../internal/Child.svelte';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
children: Snippet;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let { children }: Props = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<Child for={ChildKey.Modal} as={ChildKey.ModalBody}>
|
|
14
|
+
{@render children?.()}
|
|
15
|
+
</Child>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { ChildKey } from '../../constants.js';
|
|
3
|
+
import Child from '../../internal/Child.svelte';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
children: Snippet;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let { children }: Props = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<Child for={ChildKey.Modal} as={ChildKey.ModalFooter}>
|
|
14
|
+
{@render children?.()}
|
|
15
|
+
</Child>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { ChildKey } from '../../constants.js';
|
|
3
|
+
import Child from '../../internal/Child.svelte';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
children: Snippet;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let { children }: Props = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<Child for={ChildKey.Modal} as={ChildKey.ModalHeader}>
|
|
14
|
+
{@render children?.()}
|
|
15
|
+
</Child>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
let { href, title, active = false, ...iconProps }: Props = $props();
|
|
13
13
|
|
|
14
14
|
const styles = tv({
|
|
15
|
-
base: '
|
|
15
|
+
base: 'flex w-full place-items-center gap-4 rounded-r-full py-3 pl-5 transition-[padding] delay-100 duration-100 hover:bg-subtle hover:text-primary group-hover:sm:px-5 md:px-5',
|
|
16
16
|
variants: {
|
|
17
17
|
active: {
|
|
18
18
|
true: 'bg-primary/10 text-primary',
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const containerStyles = tv({
|
|
27
|
-
base: 'bg-secondary flex place-items-center gap-2 overflow-hidden rounded-lg
|
|
27
|
+
base: 'bg-secondary flex place-items-center gap-2 overflow-hidden rounded-lg transition-all',
|
|
28
28
|
variants: {
|
|
29
29
|
size: {
|
|
30
30
|
tiny: 'px-2 py-1',
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
giant: 'px-3 py-2',
|
|
35
35
|
},
|
|
36
36
|
effect: {
|
|
37
|
-
hover: 'border border-dark/25
|
|
38
|
-
always: '
|
|
37
|
+
hover: 'supporter-effect-hover border border-dark/25',
|
|
38
|
+
always: 'supporter-effect shadow',
|
|
39
39
|
},
|
|
40
40
|
},
|
|
41
41
|
});
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
const bar = tv({
|
|
46
|
-
base: '
|
|
46
|
+
base: 'my-2 h-3 w-12 rounded-full border border-transparent',
|
|
47
47
|
variants: {
|
|
48
48
|
fillColor: {
|
|
49
49
|
default: 'bg-gray-400',
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
const dot = tv({
|
|
61
|
-
base: 'absolute
|
|
61
|
+
base: 'absolute h-6 w-6 rounded-full transition-transform duration-[400ms]',
|
|
62
62
|
variants: {
|
|
63
63
|
checked: {
|
|
64
64
|
true: 'translate-x-6',
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import IconButton from '../IconButton/IconButton.svelte';
|
|
3
|
+
import { theme } from '../../services/theme.svelte.js';
|
|
4
|
+
import { Theme, type Size, type Variants } from '../../types.js';
|
|
5
|
+
import { cleanClass } from '../../utils.js';
|
|
6
|
+
import { mdiWeatherNight, mdiWeatherSunny } from '@mdi/js';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
size?: Size;
|
|
10
|
+
class?: string;
|
|
11
|
+
variant?: Variants;
|
|
12
|
+
onChange?: (theme: Theme) => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const { variant = 'ghost', size, class: className, onChange }: Props = $props();
|
|
16
|
+
|
|
17
|
+
const handleToggleTheme = () => {
|
|
18
|
+
theme.value = theme.value === Theme.Dark ? Theme.Light : Theme.Dark;
|
|
19
|
+
onChange?.(theme.value);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const themeIcon = $derived(theme.value === Theme.Light ? mdiWeatherSunny : mdiWeatherNight);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<IconButton
|
|
26
|
+
shape="round"
|
|
27
|
+
color="primary"
|
|
28
|
+
{size}
|
|
29
|
+
{variant}
|
|
30
|
+
icon={themeIcon}
|
|
31
|
+
onclick={handleToggleTheme}
|
|
32
|
+
class={cleanClass(className)}
|
|
33
|
+
/>
|
package/dist/constants.d.ts
CHANGED
|
@@ -7,5 +7,9 @@ export declare enum ChildKey {
|
|
|
7
7
|
Card = "card",
|
|
8
8
|
CardHeader = "card-header",
|
|
9
9
|
CardBody = "card-body",
|
|
10
|
-
CardFooter = "card-footer"
|
|
10
|
+
CardFooter = "card-footer",
|
|
11
|
+
Modal = "modal",
|
|
12
|
+
ModalHeader = "modal-header",
|
|
13
|
+
ModalBody = "modal-body",
|
|
14
|
+
ModalFooter = "modal-footer"
|
|
11
15
|
}
|
package/dist/constants.js
CHANGED
|
@@ -9,4 +9,8 @@ export var ChildKey;
|
|
|
9
9
|
ChildKey["CardHeader"] = "card-header";
|
|
10
10
|
ChildKey["CardBody"] = "card-body";
|
|
11
11
|
ChildKey["CardFooter"] = "card-footer";
|
|
12
|
+
ChildKey["Modal"] = "modal";
|
|
13
|
+
ChildKey["ModalHeader"] = "modal-header";
|
|
14
|
+
ChildKey["ModalBody"] = "modal-body";
|
|
15
|
+
ChildKey["ModalFooter"] = "modal-footer";
|
|
12
16
|
})(ChildKey || (ChildKey = {}));
|
package/dist/index.d.ts
CHANGED
|
@@ -31,9 +31,13 @@ export { default as FormatBytes } from './components/FormatBytes/FormatBytes.sve
|
|
|
31
31
|
export { default as Heading } from './components/Heading/Heading.svelte';
|
|
32
32
|
export { default as Icon } from './components/Icon/Icon.svelte';
|
|
33
33
|
export { default as IconButton } from './components/IconButton/IconButton.svelte';
|
|
34
|
+
export { default as Kbd } from './components/Kbd/Kbd.svelte';
|
|
34
35
|
export { default as Link } from './components/Link/Link.svelte';
|
|
35
36
|
export { default as LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner.svelte';
|
|
36
37
|
export { default as Logo } from './components/Logo/Logo.svelte';
|
|
38
|
+
export { default as Modal } from './components/Modal/Modal.svelte';
|
|
39
|
+
export { default as ModalBody } from './components/Modal/ModalBody.svelte';
|
|
40
|
+
export { default as ModalFooter } from './components/Modal/ModalFooter.svelte';
|
|
37
41
|
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.svelte';
|
|
38
42
|
export { default as NavbarGroup } from './components/Navbar/NavbarGroup.svelte';
|
|
39
43
|
export { default as NavbarItem } from './components/Navbar/NavbarItem.svelte';
|
|
@@ -45,6 +49,8 @@ export { default as VStack } from './components/Stack/VStack.svelte';
|
|
|
45
49
|
export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
|
|
46
50
|
export { default as Switch } from './components/Switch/Switch.svelte';
|
|
47
51
|
export { default as Text } from './components/Text/Text.svelte';
|
|
52
|
+
export { default as ThemeSwitcher } from './components/ThemeSwitcher/ThemeSwitcher.svelte';
|
|
48
53
|
export * from './services/theme.svelte.js';
|
|
49
54
|
export * from './types.js';
|
|
50
55
|
export * from './utilities/byte-units.js';
|
|
56
|
+
export * from './services/translation.svelte.js';
|
package/dist/index.js
CHANGED
|
@@ -33,9 +33,13 @@ export { default as FormatBytes } from './components/FormatBytes/FormatBytes.sve
|
|
|
33
33
|
export { default as Heading } from './components/Heading/Heading.svelte';
|
|
34
34
|
export { default as Icon } from './components/Icon/Icon.svelte';
|
|
35
35
|
export { default as IconButton } from './components/IconButton/IconButton.svelte';
|
|
36
|
+
export { default as Kbd } from './components/Kbd/Kbd.svelte';
|
|
36
37
|
export { default as Link } from './components/Link/Link.svelte';
|
|
37
38
|
export { default as LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner.svelte';
|
|
38
39
|
export { default as Logo } from './components/Logo/Logo.svelte';
|
|
40
|
+
export { default as Modal } from './components/Modal/Modal.svelte';
|
|
41
|
+
export { default as ModalBody } from './components/Modal/ModalBody.svelte';
|
|
42
|
+
export { default as ModalFooter } from './components/Modal/ModalFooter.svelte';
|
|
39
43
|
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.svelte';
|
|
40
44
|
export { default as NavbarGroup } from './components/Navbar/NavbarGroup.svelte';
|
|
41
45
|
export { default as NavbarItem } from './components/Navbar/NavbarItem.svelte';
|
|
@@ -47,7 +51,9 @@ export { default as VStack } from './components/Stack/VStack.svelte';
|
|
|
47
51
|
export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
|
|
48
52
|
export { default as Switch } from './components/Switch/Switch.svelte';
|
|
49
53
|
export { default as Text } from './components/Text/Text.svelte';
|
|
54
|
+
export { default as ThemeSwitcher } from './components/ThemeSwitcher/ThemeSwitcher.svelte';
|
|
50
55
|
// helpers
|
|
51
56
|
export * from './services/theme.svelte.js';
|
|
52
57
|
export * from './types.js';
|
|
53
58
|
export * from './utilities/byte-units.js';
|
|
59
|
+
export * from './services/translation.svelte.js';
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
iconSize: {
|
|
58
58
|
tiny: 'h-4 w-4 text-xs',
|
|
59
59
|
small: 'h-6 w-6 text-sm',
|
|
60
|
-
medium: 'h-8 w-8
|
|
60
|
+
medium: 'text-md h-8 w-8',
|
|
61
61
|
large: 'h-10 w-10 text-lg',
|
|
62
62
|
giant: 'h-12 w-12 text-lg',
|
|
63
63
|
},
|
|
@@ -77,12 +77,12 @@
|
|
|
77
77
|
info: 'bg-info text-light hover:bg-info/80',
|
|
78
78
|
},
|
|
79
79
|
outlineColor: {
|
|
80
|
-
primary: 'bg-primary/10 text-primary
|
|
81
|
-
secondary: 'bg-dark/10 text-dark
|
|
82
|
-
success: 'bg-success/10 text-success
|
|
83
|
-
danger: 'bg-danger/10 text-danger
|
|
84
|
-
warning: 'bg-warning/10 text-warning
|
|
85
|
-
info: 'bg-info/10 text-info
|
|
80
|
+
primary: 'border border-primary bg-primary/10 text-primary hover:bg-primary/20',
|
|
81
|
+
secondary: 'border border-dark bg-dark/10 text-dark hover:bg-dark/20',
|
|
82
|
+
success: 'border border-success bg-success/10 text-success hover:bg-success/20',
|
|
83
|
+
danger: 'border border-danger bg-danger/10 text-danger hover:bg-danger/20',
|
|
84
|
+
warning: 'border border-warning bg-warning/10 text-warning hover:bg-warning/20',
|
|
85
|
+
info: 'border border-info bg-info/10 text-info hover:bg-info/20',
|
|
86
86
|
},
|
|
87
87
|
ghostColor: {
|
|
88
88
|
primary: 'text-primary hover:bg-primary/10',
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { ChildKey } from '../constants.js';
|
|
3
|
+
import type { ChildData } from '../types.js';
|
|
3
4
|
import { withPrefix } from '../utils.js';
|
|
4
5
|
import { getContext, type Snippet } from 'svelte';
|
|
5
6
|
|
|
6
|
-
type ContextType = {
|
|
7
|
+
type ContextType = {
|
|
8
|
+
register: (key: ChildKey, data: () => ChildData) => void;
|
|
9
|
+
};
|
|
7
10
|
type Props = {
|
|
8
11
|
for: ChildKey;
|
|
9
12
|
as: ChildKey;
|
|
13
|
+
class?: string;
|
|
10
14
|
children: Snippet;
|
|
11
15
|
};
|
|
12
16
|
|
|
13
|
-
const { for: key, as, children }: Props = $props();
|
|
17
|
+
const { for: key, as, children, class: className }: Props = $props();
|
|
14
18
|
|
|
15
19
|
const context = getContext<ContextType>(withPrefix(key));
|
|
20
|
+
|
|
21
|
+
const data = $derived({ snippet: children, class: className });
|
|
22
|
+
|
|
16
23
|
if (context) {
|
|
17
|
-
context.register(as,
|
|
24
|
+
context.register(as, () => data);
|
|
18
25
|
} else {
|
|
19
26
|
console.log('Unable to find context for key:', key);
|
|
20
27
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TranslationProps } from '../types.js';
|
|
2
|
+
declare const defaultTranslations: {
|
|
3
|
+
close: string;
|
|
4
|
+
showPassword: string;
|
|
5
|
+
hidePassword: string;
|
|
6
|
+
};
|
|
7
|
+
export type Translations = typeof defaultTranslations;
|
|
8
|
+
export declare const translate: <T extends keyof Translations>(key: T, overrides?: TranslationProps<T>) => string;
|
|
9
|
+
export declare const t: <T extends keyof Translations>(key: T, overrides?: TranslationProps<T>) => string;
|
|
10
|
+
export declare const setTranslations: (newTranslations: Partial<Translations>) => void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const defaultTranslations = {
|
|
2
|
+
close: 'Close',
|
|
3
|
+
showPassword: 'Show password',
|
|
4
|
+
hidePassword: 'Hide password',
|
|
5
|
+
};
|
|
6
|
+
let translations = $state(defaultTranslations);
|
|
7
|
+
export const translate = (key, overrides) => overrides?.[key] ?? translations[key];
|
|
8
|
+
export const t = translate;
|
|
9
|
+
export const setTranslations = (newTranslations) => {
|
|
10
|
+
translations = { ...defaultTranslations, ...newTranslations };
|
|
11
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import type { Translations } from './services/translation.svelte.js';
|
|
1
2
|
import type { Snippet } from 'svelte';
|
|
2
3
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes, HTMLInputAttributes } from 'svelte/elements';
|
|
3
4
|
export type Color = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
|
|
4
5
|
export type TextColor = Color | 'muted';
|
|
5
6
|
export type HeadingColor = TextColor;
|
|
6
7
|
export type Size = 'tiny' | 'small' | 'medium' | 'large' | 'giant';
|
|
8
|
+
export type ModalSize = Size | 'full';
|
|
7
9
|
export type HeadingSize = Size | 'title';
|
|
8
10
|
export type Shape = 'rectangle' | 'semi-round' | 'round';
|
|
9
11
|
export type Variants = 'filled' | 'outline' | 'ghost';
|
|
@@ -12,6 +14,9 @@ export declare enum Theme {
|
|
|
12
14
|
Light = "light",
|
|
13
15
|
Dark = "dark"
|
|
14
16
|
}
|
|
17
|
+
export type TranslationProps<T extends keyof Translations> = {
|
|
18
|
+
[K in T]?: string;
|
|
19
|
+
};
|
|
15
20
|
export type IconProps = {
|
|
16
21
|
icon: string;
|
|
17
22
|
title?: string;
|
|
@@ -46,6 +51,7 @@ export type CloseButtonProps = {
|
|
|
46
51
|
size?: Size;
|
|
47
52
|
variant?: Variants;
|
|
48
53
|
class?: string;
|
|
54
|
+
translations?: TranslationProps<'close'>;
|
|
49
55
|
} & ButtonOrAnchor;
|
|
50
56
|
export type IconButtonProps = ButtonBase & {
|
|
51
57
|
icon: string;
|
|
@@ -60,6 +66,10 @@ type StackBaseProps = {
|
|
|
60
66
|
fullWidth?: boolean;
|
|
61
67
|
fullHeight?: boolean;
|
|
62
68
|
};
|
|
69
|
+
export type ChildData = {
|
|
70
|
+
snippet: Snippet;
|
|
71
|
+
class?: string;
|
|
72
|
+
};
|
|
63
73
|
export type StackProps = StackBaseProps & {
|
|
64
74
|
align?: 'start' | 'center' | 'end';
|
|
65
75
|
direction?: 'row' | 'column';
|
|
@@ -86,8 +96,7 @@ export type InputProps = BaseInputProps & {
|
|
|
86
96
|
trailingIcon?: Snippet;
|
|
87
97
|
};
|
|
88
98
|
export type PasswordInputProps = BaseInputProps & {
|
|
89
|
-
|
|
90
|
-
hideLabel?: string;
|
|
99
|
+
translations?: TranslationProps<'showPassword' | 'hidePassword'>;
|
|
91
100
|
isVisible?: boolean;
|
|
92
101
|
};
|
|
93
102
|
export type SelectItem = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@immich/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "GNU Affero General Public License version 3",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"create": "node scripts/create.js",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"prettier": "^3.3.2",
|
|
54
54
|
"prettier-plugin-svelte": "^3.2.6",
|
|
55
55
|
"prettier-plugin-tailwindcss": "^0.6.5",
|
|
56
|
-
"publint": "^0.
|
|
56
|
+
"publint": "^0.3.0",
|
|
57
57
|
"svelte": "^5.0.0",
|
|
58
58
|
"svelte-check": "^4.0.0",
|
|
59
59
|
"svelte-highlight": "^7.8.0",
|