@immich/ui 0.9.0 → 0.10.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/Card/Card.svelte +83 -108
- 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/Form/Field.svelte +3 -2
- package/dist/components/Heading/Heading.svelte +1 -1
- package/dist/components/Modal/Modal.svelte +88 -0
- package/dist/components/Modal/Modal.svelte.d.ts +17 -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/constants.d.ts +5 -1
- package/dist/constants.js +4 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/internal/Child.svelte +10 -3
- package/dist/internal/Child.svelte.d.ts +1 -0
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
|
@@ -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?.()}
|
|
@@ -1,48 +1,52 @@
|
|
|
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 flex-col w-full h-full',
|
|
48
|
+
variants: {
|
|
49
|
+
color: {
|
|
46
50
|
primary: 'bg-primary/25 dark:bg-primary/25',
|
|
47
51
|
secondary: 'bg-dark/5 dark:bg-dark/25 text-dark',
|
|
48
52
|
success: 'bg-success/15 dark:bg-success/30',
|
|
@@ -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>
|
|
@@ -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>
|
|
@@ -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,17 @@
|
|
|
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
|
+
controlledOpen?: boolean;
|
|
7
|
+
} & {
|
|
8
|
+
children?: Snippet | undefined;
|
|
9
|
+
} & {
|
|
10
|
+
title: string;
|
|
11
|
+
size?: ModalSize;
|
|
12
|
+
class?: string;
|
|
13
|
+
open?: boolean;
|
|
14
|
+
expandable?: boolean;
|
|
15
|
+
children: Snippet;
|
|
16
|
+
}, {}, "open">;
|
|
17
|
+
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>
|
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
|
@@ -19,6 +19,9 @@ export { default as CardDescription } from './components/Card/CardDescription.sv
|
|
|
19
19
|
export { default as CardFooter } from './components/Card/CardFooter.svelte';
|
|
20
20
|
export { default as CardHeader } from './components/Card/CardHeader.svelte';
|
|
21
21
|
export { default as CardTitle } from './components/Card/CardTitle.svelte';
|
|
22
|
+
export { default as Modal } from './components/Modal/Modal.svelte';
|
|
23
|
+
export { default as ModalBody } from './components/Modal/ModalBody.svelte';
|
|
24
|
+
export { default as ModalFooter } from './components/Modal/ModalFooter.svelte';
|
|
22
25
|
export { default as CloseButton } from './components/CloseButton/CloseButton.svelte';
|
|
23
26
|
export { default as Code } from './components/Code/Code.svelte';
|
|
24
27
|
export { default as Checkbox } from './components/Form/Checkbox.svelte';
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,9 @@ export { default as CardDescription } from './components/Card/CardDescription.sv
|
|
|
21
21
|
export { default as CardFooter } from './components/Card/CardFooter.svelte';
|
|
22
22
|
export { default as CardHeader } from './components/Card/CardHeader.svelte';
|
|
23
23
|
export { default as CardTitle } from './components/Card/CardTitle.svelte';
|
|
24
|
+
export { default as Modal } from './components/Modal/Modal.svelte';
|
|
25
|
+
export { default as ModalBody } from './components/Modal/ModalBody.svelte';
|
|
26
|
+
export { default as ModalFooter } from './components/Modal/ModalFooter.svelte';
|
|
24
27
|
export { default as CloseButton } from './components/CloseButton/CloseButton.svelte';
|
|
25
28
|
export { default as Code } from './components/Code/Code.svelte';
|
|
26
29
|
export { default as Checkbox } from './components/Form/Checkbox.svelte';
|
|
@@ -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
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export type Color = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' |
|
|
|
4
4
|
export type TextColor = Color | 'muted';
|
|
5
5
|
export type HeadingColor = TextColor;
|
|
6
6
|
export type Size = 'tiny' | 'small' | 'medium' | 'large' | 'giant';
|
|
7
|
+
export type ModalSize = Size | 'full';
|
|
7
8
|
export type HeadingSize = Size | 'title';
|
|
8
9
|
export type Shape = 'rectangle' | 'semi-round' | 'round';
|
|
9
10
|
export type Variants = 'filled' | 'outline' | 'ghost';
|
|
@@ -60,6 +61,10 @@ type StackBaseProps = {
|
|
|
60
61
|
fullWidth?: boolean;
|
|
61
62
|
fullHeight?: boolean;
|
|
62
63
|
};
|
|
64
|
+
export type ChildData = {
|
|
65
|
+
snippet: Snippet;
|
|
66
|
+
class?: string;
|
|
67
|
+
};
|
|
63
68
|
export type StackProps = StackBaseProps & {
|
|
64
69
|
align?: 'start' | 'center' | 'end';
|
|
65
70
|
direction?: 'row' | 'column';
|