@immich/ui 0.7.0 → 0.9.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/assets/appstore-badge.svg +46 -0
- package/dist/assets/fdroid-badge.svg +124 -0
- package/dist/assets/playstore-badge.png +0 -0
- package/dist/components/Alert/Alert.svelte +73 -19
- package/dist/components/Alert/Alert.svelte.d.ts +7 -1
- package/dist/components/AppShell/AppShell.svelte +34 -0
- package/dist/components/AppShell/AppShell.svelte.d.ts +6 -0
- package/dist/components/AppShell/AppShellHeader.svelte +15 -0
- package/dist/components/AppShell/AppShellHeader.svelte.d.ts +5 -0
- package/dist/components/AppShell/AppShellSidebar.svelte +23 -0
- package/dist/components/AppShell/AppShellSidebar.svelte.d.ts +7 -0
- package/dist/components/AppShell/PageLayout.svelte +44 -0
- package/dist/components/AppShell/PageLayout.svelte.d.ts +9 -0
- package/dist/components/Avatar/Avatar.svelte +66 -0
- package/dist/components/Avatar/Avatar.svelte.d.ts +7 -0
- package/dist/components/Card/Card.svelte +9 -11
- package/dist/components/Card/CardBody.svelte +1 -1
- package/dist/components/Card/CardFooter.svelte +6 -2
- package/dist/components/Card/CardFooter.svelte.d.ts +1 -0
- package/dist/components/CloseButton/CloseButton.svelte +2 -2
- package/dist/components/Code/Code.svelte +62 -0
- package/dist/components/Code/Code.svelte.d.ts +9 -0
- package/dist/components/Form/Checkbox.svelte +67 -27
- package/dist/components/Form/Checkbox.svelte.d.ts +1 -1
- package/dist/components/Form/HelperText.svelte +3 -3
- package/dist/components/Form/HelperText.svelte.d.ts +2 -2
- package/dist/components/Form/Input.svelte +2 -1
- package/dist/components/Form/Input.svelte.d.ts +1 -1
- package/dist/components/Form/PasswordInput.svelte +3 -1
- package/dist/components/Form/PasswordInput.svelte.d.ts +1 -1
- package/dist/components/FormatBytes/FormatBytes.svelte +16 -0
- package/dist/components/FormatBytes/FormatBytes.svelte.d.ts +6 -0
- package/dist/components/Heading/Heading.svelte +3 -2
- package/dist/components/Heading/Heading.svelte.d.ts +2 -2
- package/dist/components/Logo/Logo.svelte +8 -8
- package/dist/components/Logo/Logo.svelte.d.ts +1 -2
- package/dist/components/MultiSelect/MultiSelect.svelte +15 -0
- package/dist/components/MultiSelect/MultiSelect.svelte.d.ts +3 -0
- package/dist/components/Navbar/NavbarGroup.svelte +12 -0
- package/dist/components/Navbar/NavbarGroup.svelte.d.ts +4 -0
- package/dist/components/Navbar/NavbarItem.svelte +30 -0
- package/dist/components/Navbar/NavbarItem.svelte.d.ts +7 -0
- package/dist/components/Scrollable/Scrollable.svelte +41 -0
- package/dist/components/Scrollable/Scrollable.svelte.d.ts +6 -0
- package/dist/components/Select/Select.svelte +15 -0
- package/dist/components/Select/Select.svelte.d.ts +3 -0
- package/dist/components/Switch/Switch.svelte +99 -0
- package/dist/components/Switch/Switch.svelte.d.ts +10 -0
- package/dist/components/Text/Text.svelte +16 -4
- package/dist/components/Text/Text.svelte.d.ts +2 -2
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +3 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +26 -0
- package/dist/internal/Button.svelte +1 -10
- package/dist/internal/Select.svelte +174 -0
- package/dist/internal/Select.svelte.d.ts +9 -0
- package/dist/services/theme.svelte.d.ts +5 -0
- package/dist/services/theme.svelte.js +13 -0
- package/dist/types.d.ts +53 -18
- package/dist/types.js +5 -1
- package/dist/utilities/byte-units.d.ts +52 -0
- package/dist/utilities/byte-units.js +75 -0
- package/package.json +6 -4
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Color } from '../../types.js';
|
|
2
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
+
declare const Switch: import("svelte").Component<{
|
|
4
|
+
checked?: boolean;
|
|
5
|
+
color?: Color;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
class?: string;
|
|
8
|
+
onToggle?: ((checked: boolean) => void) | undefined;
|
|
9
|
+
} & HTMLInputAttributes, {}, "checked">;
|
|
10
|
+
export default Switch;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type {
|
|
2
|
+
import type { Size, TextColor } from '../../types.js';
|
|
3
3
|
import { cleanClass } from '../../utils.js';
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
import { tv } from 'tailwind-variants';
|
|
6
6
|
|
|
7
7
|
type Props = {
|
|
8
|
-
color?:
|
|
8
|
+
color?: TextColor;
|
|
9
9
|
class?: string;
|
|
10
10
|
size?: Size;
|
|
11
11
|
children: Snippet;
|
|
@@ -13,11 +13,19 @@
|
|
|
13
13
|
fontWeight?: 'light' | 'normal' | 'semi-bold' | 'bold';
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
const {
|
|
16
|
+
const {
|
|
17
|
+
color,
|
|
18
|
+
size,
|
|
19
|
+
variant,
|
|
20
|
+
fontWeight = 'normal',
|
|
21
|
+
children,
|
|
22
|
+
class: className,
|
|
23
|
+
}: Props = $props();
|
|
17
24
|
|
|
18
25
|
const styles = tv({
|
|
19
26
|
variants: {
|
|
20
27
|
color: {
|
|
28
|
+
muted: 'text-gray-600 dark:text-gray-400',
|
|
21
29
|
primary: 'text-primary',
|
|
22
30
|
secondary: 'text-dark',
|
|
23
31
|
success: 'text-success',
|
|
@@ -26,6 +34,10 @@
|
|
|
26
34
|
info: 'text-info',
|
|
27
35
|
},
|
|
28
36
|
|
|
37
|
+
variant: {
|
|
38
|
+
italic: 'italic',
|
|
39
|
+
},
|
|
40
|
+
|
|
29
41
|
size: {
|
|
30
42
|
tiny: 'text-xs',
|
|
31
43
|
small: 'text-sm',
|
|
@@ -44,6 +56,6 @@
|
|
|
44
56
|
});
|
|
45
57
|
</script>
|
|
46
58
|
|
|
47
|
-
<p class={cleanClass(styles({ color, size, fontWeight }), className)}>
|
|
59
|
+
<p class={cleanClass(styles({ color, size, fontWeight, variant }), className)}>
|
|
48
60
|
{@render children()}
|
|
49
61
|
</p>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Size, TextColor } from '../../types.js';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
declare const Text: import("svelte").Component<{
|
|
4
|
-
color?:
|
|
4
|
+
color?: TextColor;
|
|
5
5
|
class?: string;
|
|
6
6
|
size?: Size;
|
|
7
7
|
children: Snippet;
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
|
@@ -2,6 +2,9 @@ export var ChildKey;
|
|
|
2
2
|
(function (ChildKey) {
|
|
3
3
|
ChildKey["Field"] = "field";
|
|
4
4
|
ChildKey["HelperText"] = "helped-text";
|
|
5
|
+
ChildKey["AppShell"] = "app-shell";
|
|
6
|
+
ChildKey["AppShellHeader"] = "app-shell-header";
|
|
7
|
+
ChildKey["AppShellSidebar"] = "app-shell-sidebar";
|
|
5
8
|
ChildKey["Card"] = "card";
|
|
6
9
|
ChildKey["CardHeader"] = "card-header";
|
|
7
10
|
ChildKey["CardBody"] = "card-body";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
+
export { default as appStoreBadge } from './assets/appstore-badge.svg';
|
|
2
|
+
export { default as fdroidBadge } from './assets/fdroid-badge.svg';
|
|
3
|
+
export { default as immichLogoInlineDark } from './assets/immich-logo-inline-dark.svg';
|
|
4
|
+
export { default as immichLogoInlineLight } from './assets/immich-logo-inline-light.svg';
|
|
5
|
+
export { default as immichLogoStackedDark } from './assets/immich-logo-stacked-dark.svg';
|
|
6
|
+
export { default as immichLogoStackedLight } from './assets/immich-logo-stacked-light.svg';
|
|
7
|
+
export { default as immichLogoJson } from './assets/immich-logo.json';
|
|
8
|
+
export { default as immichLogo } from './assets/immich-logo.svg';
|
|
9
|
+
export { default as playStoreBadge } from './assets/playstore-badge.png';
|
|
1
10
|
export { default as Alert } from './components/Alert/Alert.svelte';
|
|
11
|
+
export { default as AppShell } from './components/AppShell/AppShell.svelte';
|
|
12
|
+
export { default as AppShellHeader } from './components/AppShell/AppShellHeader.svelte';
|
|
13
|
+
export { default as AppShellSidebar } from './components/AppShell/AppShellSidebar.svelte';
|
|
14
|
+
export { default as Avatar } from './components/Avatar/Avatar.svelte';
|
|
2
15
|
export { default as Button } from './components/Button/Button.svelte';
|
|
3
16
|
export { default as Card } from './components/Card/Card.svelte';
|
|
4
17
|
export { default as CardBody } from './components/Card/CardBody.svelte';
|
|
@@ -7,21 +20,31 @@ export { default as CardFooter } from './components/Card/CardFooter.svelte';
|
|
|
7
20
|
export { default as CardHeader } from './components/Card/CardHeader.svelte';
|
|
8
21
|
export { default as CardTitle } from './components/Card/CardTitle.svelte';
|
|
9
22
|
export { default as CloseButton } from './components/CloseButton/CloseButton.svelte';
|
|
23
|
+
export { default as Code } from './components/Code/Code.svelte';
|
|
10
24
|
export { default as Checkbox } from './components/Form/Checkbox.svelte';
|
|
11
25
|
export { default as Field } from './components/Form/Field.svelte';
|
|
12
26
|
export { default as HelperText } from './components/Form/HelperText.svelte';
|
|
13
27
|
export { default as Input } from './components/Form/Input.svelte';
|
|
14
28
|
export { default as Label } from './components/Form/Label.svelte';
|
|
15
29
|
export { default as PasswordInput } from './components/Form/PasswordInput.svelte';
|
|
30
|
+
export { default as FormatBytes } from './components/FormatBytes/FormatBytes.svelte';
|
|
16
31
|
export { default as Heading } from './components/Heading/Heading.svelte';
|
|
17
32
|
export { default as Icon } from './components/Icon/Icon.svelte';
|
|
18
33
|
export { default as IconButton } from './components/IconButton/IconButton.svelte';
|
|
19
34
|
export { default as Link } from './components/Link/Link.svelte';
|
|
20
35
|
export { default as LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner.svelte';
|
|
21
36
|
export { default as Logo } from './components/Logo/Logo.svelte';
|
|
37
|
+
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.svelte';
|
|
38
|
+
export { default as NavbarGroup } from './components/Navbar/NavbarGroup.svelte';
|
|
39
|
+
export { default as NavbarItem } from './components/Navbar/NavbarItem.svelte';
|
|
40
|
+
export { default as Scrollable } from './components/Scrollable/Scrollable.svelte';
|
|
41
|
+
export { default as Select } from './components/Select/Select.svelte';
|
|
22
42
|
export { default as HStack } from './components/Stack/HStack.svelte';
|
|
23
43
|
export { default as Stack } from './components/Stack/Stack.svelte';
|
|
24
44
|
export { default as VStack } from './components/Stack/VStack.svelte';
|
|
25
45
|
export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
|
|
46
|
+
export { default as Switch } from './components/Switch/Switch.svelte';
|
|
26
47
|
export { default as Text } from './components/Text/Text.svelte';
|
|
48
|
+
export * from './services/theme.svelte.js';
|
|
27
49
|
export * from './types.js';
|
|
50
|
+
export * from './utilities/byte-units.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
// files
|
|
2
|
+
export { default as appStoreBadge } from './assets/appstore-badge.svg';
|
|
3
|
+
export { default as fdroidBadge } from './assets/fdroid-badge.svg';
|
|
4
|
+
export { default as immichLogoInlineDark } from './assets/immich-logo-inline-dark.svg';
|
|
5
|
+
export { default as immichLogoInlineLight } from './assets/immich-logo-inline-light.svg';
|
|
6
|
+
export { default as immichLogoStackedDark } from './assets/immich-logo-stacked-dark.svg';
|
|
7
|
+
export { default as immichLogoStackedLight } from './assets/immich-logo-stacked-light.svg';
|
|
8
|
+
export { default as immichLogoJson } from './assets/immich-logo.json';
|
|
9
|
+
export { default as immichLogo } from './assets/immich-logo.svg';
|
|
10
|
+
export { default as playStoreBadge } from './assets/playstore-badge.png';
|
|
11
|
+
// components
|
|
1
12
|
export { default as Alert } from './components/Alert/Alert.svelte';
|
|
13
|
+
export { default as AppShell } from './components/AppShell/AppShell.svelte';
|
|
14
|
+
export { default as AppShellHeader } from './components/AppShell/AppShellHeader.svelte';
|
|
15
|
+
export { default as AppShellSidebar } from './components/AppShell/AppShellSidebar.svelte';
|
|
16
|
+
export { default as Avatar } from './components/Avatar/Avatar.svelte';
|
|
2
17
|
export { default as Button } from './components/Button/Button.svelte';
|
|
3
18
|
export { default as Card } from './components/Card/Card.svelte';
|
|
4
19
|
export { default as CardBody } from './components/Card/CardBody.svelte';
|
|
@@ -7,21 +22,32 @@ export { default as CardFooter } from './components/Card/CardFooter.svelte';
|
|
|
7
22
|
export { default as CardHeader } from './components/Card/CardHeader.svelte';
|
|
8
23
|
export { default as CardTitle } from './components/Card/CardTitle.svelte';
|
|
9
24
|
export { default as CloseButton } from './components/CloseButton/CloseButton.svelte';
|
|
25
|
+
export { default as Code } from './components/Code/Code.svelte';
|
|
10
26
|
export { default as Checkbox } from './components/Form/Checkbox.svelte';
|
|
11
27
|
export { default as Field } from './components/Form/Field.svelte';
|
|
12
28
|
export { default as HelperText } from './components/Form/HelperText.svelte';
|
|
13
29
|
export { default as Input } from './components/Form/Input.svelte';
|
|
14
30
|
export { default as Label } from './components/Form/Label.svelte';
|
|
15
31
|
export { default as PasswordInput } from './components/Form/PasswordInput.svelte';
|
|
32
|
+
export { default as FormatBytes } from './components/FormatBytes/FormatBytes.svelte';
|
|
16
33
|
export { default as Heading } from './components/Heading/Heading.svelte';
|
|
17
34
|
export { default as Icon } from './components/Icon/Icon.svelte';
|
|
18
35
|
export { default as IconButton } from './components/IconButton/IconButton.svelte';
|
|
19
36
|
export { default as Link } from './components/Link/Link.svelte';
|
|
20
37
|
export { default as LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner.svelte';
|
|
21
38
|
export { default as Logo } from './components/Logo/Logo.svelte';
|
|
39
|
+
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.svelte';
|
|
40
|
+
export { default as NavbarGroup } from './components/Navbar/NavbarGroup.svelte';
|
|
41
|
+
export { default as NavbarItem } from './components/Navbar/NavbarItem.svelte';
|
|
42
|
+
export { default as Scrollable } from './components/Scrollable/Scrollable.svelte';
|
|
43
|
+
export { default as Select } from './components/Select/Select.svelte';
|
|
22
44
|
export { default as HStack } from './components/Stack/HStack.svelte';
|
|
23
45
|
export { default as Stack } from './components/Stack/Stack.svelte';
|
|
24
46
|
export { default as VStack } from './components/Stack/VStack.svelte';
|
|
25
47
|
export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
|
|
48
|
+
export { default as Switch } from './components/Switch/Switch.svelte';
|
|
26
49
|
export { default as Text } from './components/Text/Text.svelte';
|
|
50
|
+
// helpers
|
|
51
|
+
export * from './services/theme.svelte.js';
|
|
27
52
|
export * from './types.js';
|
|
53
|
+
export * from './utilities/byte-units.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import LoadingSpinner from '../components/LoadingSpinner/LoadingSpinner.svelte';
|
|
2
3
|
import type { ButtonProps, Size } from '../types.js';
|
|
3
4
|
import { cleanClass } from '../utils.js';
|
|
4
|
-
import { LoadingSpinner } from '../index.js';
|
|
5
5
|
import { Button as ButtonPrimitive } from 'bits-ui';
|
|
6
6
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
7
7
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -84,14 +84,6 @@
|
|
|
84
84
|
warning: 'bg-warning/10 text-warning border border-warning hover:bg-warning/20',
|
|
85
85
|
info: 'bg-info/10 text-info border border-info hover:bg-info/20',
|
|
86
86
|
},
|
|
87
|
-
heroColor: {
|
|
88
|
-
primary: 'bg-gradient-to-tr from-primary to-primary/60 text-light hover:bg-primary',
|
|
89
|
-
secondary: 'bg-gradient-to-tr from-dark to-dark/60 text-light hover:bg-dark',
|
|
90
|
-
success: 'bg-gradient-to-tr from-success to-success/60 text-light hover:bg-success',
|
|
91
|
-
danger: 'bg-gradient-to-tr from-danger to-danger/60 text-light hover:bg-danger',
|
|
92
|
-
warning: 'bg-gradient-to-tr from-warning to-warning/60 text-light hover:bg-warning',
|
|
93
|
-
info: 'bg-gradient-to-tr from-info to-info/60 text-light hover:bg-info',
|
|
94
|
-
},
|
|
95
87
|
ghostColor: {
|
|
96
88
|
primary: 'text-primary hover:bg-primary/10',
|
|
97
89
|
secondary: 'text-dark hover:bg-dark/10',
|
|
@@ -123,7 +115,6 @@
|
|
|
123
115
|
roundedSize: shape === 'semi-round' ? size : undefined,
|
|
124
116
|
filledColor: variant === 'filled' ? color : undefined,
|
|
125
117
|
outlineColor: variant === 'outline' ? color : undefined,
|
|
126
|
-
heroColor: variant === 'hero' ? color : undefined,
|
|
127
118
|
ghostColor: variant === 'ghost' ? color : undefined,
|
|
128
119
|
}),
|
|
129
120
|
className,
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getFieldContext } from '../common/context.svelte.js';
|
|
3
|
+
import Field from '../components/Form/Field.svelte';
|
|
4
|
+
import Input from '../components/Form/Input.svelte';
|
|
5
|
+
import Icon from '../components/Icon/Icon.svelte';
|
|
6
|
+
import IconButton from '../components/IconButton/IconButton.svelte';
|
|
7
|
+
import type { SelectCommonProps, SelectItem } from '../types.js';
|
|
8
|
+
import { cleanClass, generateId } from '../utils.js';
|
|
9
|
+
import { mdiArrowDown, mdiArrowUp, mdiCheck, mdiUnfoldMoreHorizontal } from '@mdi/js';
|
|
10
|
+
import { Select } from 'bits-ui';
|
|
11
|
+
import { tv } from 'tailwind-variants';
|
|
12
|
+
|
|
13
|
+
type T = SelectItem;
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
multiple?: boolean;
|
|
17
|
+
values?: T[];
|
|
18
|
+
asLabel?: (items: T[]) => string;
|
|
19
|
+
onChange?: (values: T[]) => void;
|
|
20
|
+
} & SelectCommonProps<T>;
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
data,
|
|
24
|
+
shape,
|
|
25
|
+
color = 'primary',
|
|
26
|
+
size = 'medium',
|
|
27
|
+
multiple = false,
|
|
28
|
+
values = $bindable([]),
|
|
29
|
+
onChange,
|
|
30
|
+
asLabel = (options: T[]) => options.map(({ label }) => label).join(', '),
|
|
31
|
+
placeholder,
|
|
32
|
+
class: className,
|
|
33
|
+
}: Props = $props();
|
|
34
|
+
|
|
35
|
+
const asOptions = (items: string[] | T[]) => {
|
|
36
|
+
return items.map((item) => {
|
|
37
|
+
if (typeof item === 'string') {
|
|
38
|
+
return { value: item, label: item } as T;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const label = item.label ?? item.value;
|
|
42
|
+
return { ...item, label };
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const options = $derived(asOptions(data));
|
|
47
|
+
|
|
48
|
+
const {
|
|
49
|
+
label,
|
|
50
|
+
readOnly = false,
|
|
51
|
+
required = false,
|
|
52
|
+
invalid = false,
|
|
53
|
+
disabled = false,
|
|
54
|
+
} = $derived(getFieldContext());
|
|
55
|
+
|
|
56
|
+
const labelStyles = tv({
|
|
57
|
+
base: '',
|
|
58
|
+
variants: {
|
|
59
|
+
size: {
|
|
60
|
+
tiny: 'text-xs',
|
|
61
|
+
small: 'text-sm',
|
|
62
|
+
medium: 'text-md',
|
|
63
|
+
large: 'text-lg',
|
|
64
|
+
giant: 'text-xl',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const id = generateId();
|
|
70
|
+
const inputId = `input-${id}`;
|
|
71
|
+
const labelId = `label-${id}`;
|
|
72
|
+
|
|
73
|
+
const selectedLabel = $derived(asLabel(values));
|
|
74
|
+
|
|
75
|
+
let inputRef = $state<HTMLElement | null>(null);
|
|
76
|
+
let contentRef = $state<HTMLElement | null>(null);
|
|
77
|
+
let ref = $state<HTMLElement | null>(null);
|
|
78
|
+
|
|
79
|
+
$effect(() => {
|
|
80
|
+
if (ref && contentRef) {
|
|
81
|
+
contentRef.style.width = `${ref.clientWidth}px`;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const findOption = (value: string) => options.find((option) => option.value === value);
|
|
86
|
+
|
|
87
|
+
const onValueChange = (items: string[] | string) => {
|
|
88
|
+
values = multiple
|
|
89
|
+
? ((items as string[]).map(findOption) as T[])
|
|
90
|
+
: [findOption(items as string) as T].filter(Boolean);
|
|
91
|
+
|
|
92
|
+
onChange?.(values);
|
|
93
|
+
};
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<div class={cleanClass('flex flex-col gap-1', className)} bind:this={ref}>
|
|
97
|
+
{#if label}
|
|
98
|
+
<label id={labelId} for={inputId} class={labelStyles({ size })}>{label}</label>
|
|
99
|
+
{/if}
|
|
100
|
+
|
|
101
|
+
<Select.Root type={multiple ? 'multiple' : 'single'} {onValueChange}>
|
|
102
|
+
<Select.Trigger
|
|
103
|
+
{disabled}
|
|
104
|
+
class="w-full items-center gap-1 rounded-lg focus-visible:outline-none"
|
|
105
|
+
aria-label={placeholder}
|
|
106
|
+
>
|
|
107
|
+
<Field {readOnly} {required} {disabled} {invalid}>
|
|
108
|
+
<Input
|
|
109
|
+
bind:containerRef={inputRef}
|
|
110
|
+
id={inputId}
|
|
111
|
+
{size}
|
|
112
|
+
{shape}
|
|
113
|
+
{color}
|
|
114
|
+
{placeholder}
|
|
115
|
+
value={selectedLabel}
|
|
116
|
+
readonly
|
|
117
|
+
aria-labelledby={labelId}
|
|
118
|
+
aria-readonly
|
|
119
|
+
>
|
|
120
|
+
{#snippet trailingIcon()}
|
|
121
|
+
<IconButton
|
|
122
|
+
variant="ghost"
|
|
123
|
+
shape="round"
|
|
124
|
+
color="secondary"
|
|
125
|
+
class="m-1"
|
|
126
|
+
icon={mdiUnfoldMoreHorizontal}
|
|
127
|
+
{disabled}
|
|
128
|
+
/>
|
|
129
|
+
{/snippet}
|
|
130
|
+
</Input>
|
|
131
|
+
</Field>
|
|
132
|
+
</Select.Trigger>
|
|
133
|
+
<Select.Portal>
|
|
134
|
+
<Select.Content
|
|
135
|
+
bind:ref={contentRef}
|
|
136
|
+
class="max-h-96 select-none rounded-xl border bg-light py-3 text-dark outline-none"
|
|
137
|
+
sideOffset={10}
|
|
138
|
+
>
|
|
139
|
+
<Select.ScrollUpButton class="flex w-full items-center justify-center">
|
|
140
|
+
<Icon icon={mdiArrowUp} />
|
|
141
|
+
</Select.ScrollUpButton>
|
|
142
|
+
<Select.Viewport>
|
|
143
|
+
{#each options as { value, label, disabled }, i (i + value)}
|
|
144
|
+
<Select.Item
|
|
145
|
+
class={cleanClass(
|
|
146
|
+
'flex h-10 w-full select-none items-center px-5 py-3 text-sm outline-none duration-75 hover:bg-subtle data-[selected]:bg-primary/10 data-[disabled]:opacity-50',
|
|
147
|
+
disabled ? 'cursor-not-allowed' : 'cursor-pointer',
|
|
148
|
+
)}
|
|
149
|
+
{value}
|
|
150
|
+
{label}
|
|
151
|
+
{disabled}
|
|
152
|
+
>
|
|
153
|
+
{#snippet children({ selected })}
|
|
154
|
+
<div
|
|
155
|
+
class="flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-colors"
|
|
156
|
+
>
|
|
157
|
+
<span>{label}</span>
|
|
158
|
+
</div>
|
|
159
|
+
{#if selected}
|
|
160
|
+
<div class="ml-auto">
|
|
161
|
+
<Icon icon={mdiCheck} />
|
|
162
|
+
</div>
|
|
163
|
+
{/if}
|
|
164
|
+
{/snippet}
|
|
165
|
+
</Select.Item>
|
|
166
|
+
{/each}
|
|
167
|
+
</Select.Viewport>
|
|
168
|
+
<Select.ScrollDownButton class="flex w-full items-center justify-center">
|
|
169
|
+
<Icon icon={mdiArrowDown} />
|
|
170
|
+
</Select.ScrollDownButton>
|
|
171
|
+
</Select.Content>
|
|
172
|
+
</Select.Portal>
|
|
173
|
+
</Select.Root>
|
|
174
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SelectCommonProps, SelectItem } from '../types.js';
|
|
2
|
+
import { Select } from 'bits-ui';
|
|
3
|
+
declare const Select: import("svelte").Component<{
|
|
4
|
+
multiple?: boolean;
|
|
5
|
+
values?: SelectItem[];
|
|
6
|
+
asLabel?: (items: SelectItem[]) => string;
|
|
7
|
+
onChange?: (values: SelectItem[]) => void;
|
|
8
|
+
} & SelectCommonProps<SelectItem>, {}, "values">;
|
|
9
|
+
export default Select;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Theme } from '../types.js';
|
|
2
|
+
export const theme = $state({ value: Theme.Dark });
|
|
3
|
+
export const syncToDom = () => {
|
|
4
|
+
switch (theme.value) {
|
|
5
|
+
case Theme.Dark: {
|
|
6
|
+
document.body.classList.add('dark');
|
|
7
|
+
break;
|
|
8
|
+
}
|
|
9
|
+
default: {
|
|
10
|
+
document.body.classList.remove('dark');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,25 +1,17 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes, HTMLInputAttributes } from 'svelte/elements';
|
|
3
3
|
export type Color = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
|
|
4
|
+
export type TextColor = Color | 'muted';
|
|
5
|
+
export type HeadingColor = TextColor;
|
|
4
6
|
export type Size = 'tiny' | 'small' | 'medium' | 'large' | 'giant';
|
|
5
7
|
export type HeadingSize = Size | 'title';
|
|
6
8
|
export type Shape = 'rectangle' | 'semi-round' | 'round';
|
|
7
|
-
export type Variants = 'filled' | 'outline' | 'ghost'
|
|
9
|
+
export type Variants = 'filled' | 'outline' | 'ghost';
|
|
8
10
|
export type Gap = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} & HTMLAnchorAttributes);
|
|
14
|
-
export type CloseButtonProps = {
|
|
15
|
-
size?: Size;
|
|
16
|
-
variant?: Variants;
|
|
17
|
-
};
|
|
18
|
-
type ButtonBaseProps = CloseButtonProps & {
|
|
19
|
-
class?: string;
|
|
20
|
-
color?: Color;
|
|
21
|
-
shape?: Shape;
|
|
22
|
-
} & ButtonOrAnchor;
|
|
11
|
+
export declare enum Theme {
|
|
12
|
+
Light = "light",
|
|
13
|
+
Dark = "dark"
|
|
14
|
+
}
|
|
23
15
|
export type IconProps = {
|
|
24
16
|
icon: string;
|
|
25
17
|
title?: string;
|
|
@@ -34,11 +26,32 @@ export type IconProps = {
|
|
|
34
26
|
strokeWidth?: number;
|
|
35
27
|
strokeColor?: string;
|
|
36
28
|
};
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
type ButtonOrAnchor = ({
|
|
30
|
+
href?: never;
|
|
31
|
+
} & HTMLButtonAttributes) | ({
|
|
32
|
+
href: string;
|
|
33
|
+
} & HTMLAnchorAttributes);
|
|
34
|
+
type ButtonBase = {
|
|
35
|
+
size?: Size;
|
|
36
|
+
variant?: Variants;
|
|
37
|
+
class?: string;
|
|
38
|
+
color?: Color;
|
|
39
|
+
shape?: Shape;
|
|
40
|
+
};
|
|
41
|
+
export type ButtonProps = ButtonBase & {
|
|
39
42
|
fullWidth?: boolean;
|
|
40
43
|
loading?: boolean;
|
|
41
|
-
};
|
|
44
|
+
} & ButtonOrAnchor;
|
|
45
|
+
export type CloseButtonProps = {
|
|
46
|
+
size?: Size;
|
|
47
|
+
variant?: Variants;
|
|
48
|
+
class?: string;
|
|
49
|
+
} & ButtonOrAnchor;
|
|
50
|
+
export type IconButtonProps = ButtonBase & {
|
|
51
|
+
icon: string;
|
|
52
|
+
flipped?: boolean;
|
|
53
|
+
flopped?: boolean;
|
|
54
|
+
} & ButtonOrAnchor;
|
|
42
55
|
type StackBaseProps = {
|
|
43
56
|
class?: string;
|
|
44
57
|
children: Snippet;
|
|
@@ -68,6 +81,7 @@ type BaseInputProps = {
|
|
|
68
81
|
inputSize?: HTMLInputAttributes['size'];
|
|
69
82
|
} & Omit<HTMLInputAttributes, 'size' | 'type'>;
|
|
70
83
|
export type InputProps = BaseInputProps & {
|
|
84
|
+
containerRef?: HTMLElement | null;
|
|
71
85
|
type?: HTMLInputAttributes['type'];
|
|
72
86
|
trailingIcon?: Snippet;
|
|
73
87
|
};
|
|
@@ -76,4 +90,25 @@ export type PasswordInputProps = BaseInputProps & {
|
|
|
76
90
|
hideLabel?: string;
|
|
77
91
|
isVisible?: boolean;
|
|
78
92
|
};
|
|
93
|
+
export type SelectItem = {
|
|
94
|
+
label?: string;
|
|
95
|
+
value: string;
|
|
96
|
+
disabled?: boolean;
|
|
97
|
+
};
|
|
98
|
+
export type SelectCommonProps<T extends SelectItem> = {
|
|
99
|
+
data: string[] | T[];
|
|
100
|
+
size?: Size;
|
|
101
|
+
color?: Color;
|
|
102
|
+
shape?: Shape;
|
|
103
|
+
placeholder?: string;
|
|
104
|
+
class?: string;
|
|
105
|
+
};
|
|
106
|
+
export type SelectProps<T extends SelectItem> = SelectCommonProps<T> & {
|
|
107
|
+
value?: T;
|
|
108
|
+
onChange?: (value: T) => void;
|
|
109
|
+
};
|
|
110
|
+
export type MultiSelectProps<T extends SelectItem> = SelectCommonProps<T> & {
|
|
111
|
+
value?: T[];
|
|
112
|
+
onChange?: (values: T[]) => void;
|
|
113
|
+
};
|
|
79
114
|
export {};
|
package/dist/types.js
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare const enum ByteUnit {
|
|
2
|
+
'B' = "B",
|
|
3
|
+
'KiB' = "KiB",
|
|
4
|
+
'MiB' = "MiB",
|
|
5
|
+
'GiB' = "GiB",
|
|
6
|
+
'TiB' = "TiB",
|
|
7
|
+
'PiB' = "PiB",
|
|
8
|
+
'EiB' = "EiB"
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Convert bytes to best human readable unit and number of that unit.
|
|
12
|
+
*
|
|
13
|
+
* * For `1024` bytes, returns `1` and `KiB`.
|
|
14
|
+
* * For `1536` bytes, returns `1.5` and `KiB`.
|
|
15
|
+
*
|
|
16
|
+
* @param bytes number of bytes
|
|
17
|
+
* @param maxPrecision maximum number of decimal places, default is `1`
|
|
18
|
+
* @returns size (number) and unit (string)
|
|
19
|
+
*/
|
|
20
|
+
export declare function getBytesWithUnit(bytes: number, maxPrecision?: number): [number, ByteUnit];
|
|
21
|
+
/**
|
|
22
|
+
* Localized number of bytes with a unit.
|
|
23
|
+
*
|
|
24
|
+
* For `1536` bytes:
|
|
25
|
+
* * en: `1.5 KiB`
|
|
26
|
+
* * de: `1,5 KiB`
|
|
27
|
+
*
|
|
28
|
+
* @param bytes number of bytes
|
|
29
|
+
* @param maxPrecision maximum number of decimal places, default is `1`
|
|
30
|
+
* @returns localized bytes with unit as string
|
|
31
|
+
*/
|
|
32
|
+
export declare function getByteUnitString(bytes: number, locale?: string, maxPrecision?: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* Convert to bytes from on a specified unit.
|
|
35
|
+
*
|
|
36
|
+
* * `1, 'GiB'`, returns `1073741824` bytes
|
|
37
|
+
*
|
|
38
|
+
* @param size value to be converted
|
|
39
|
+
* @param unit unit to convert from
|
|
40
|
+
* @returns bytes (number)
|
|
41
|
+
*/
|
|
42
|
+
export declare function convertToBytes(size: number, unit: ByteUnit): number;
|
|
43
|
+
/**
|
|
44
|
+
* Convert from bytes to a specified unit.
|
|
45
|
+
*
|
|
46
|
+
* * `11073741824, 'GiB'`, returns `1` GiB
|
|
47
|
+
*
|
|
48
|
+
* @param bytes value to be converted
|
|
49
|
+
* @param unit unit to convert to
|
|
50
|
+
* @returns bytes (number)
|
|
51
|
+
*/
|
|
52
|
+
export declare function convertFromBytes(bytes: number, unit: ByteUnit): number;
|