@immich/ui 0.28.1 → 0.29.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.
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
value = $bindable<string>(),
|
|
17
17
|
leadingIcon,
|
|
18
18
|
trailingIcon,
|
|
19
|
+
inputSize,
|
|
19
20
|
...restProps
|
|
20
21
|
}: InputProps = $props();
|
|
21
22
|
|
|
@@ -119,6 +120,7 @@
|
|
|
119
120
|
aria-disabled={disabled}
|
|
120
121
|
aria-describedby={descriptionId}
|
|
121
122
|
readonly={readOnly}
|
|
123
|
+
size={inputSize}
|
|
122
124
|
aria-readonly={readOnly}
|
|
123
125
|
class={cleanClass(
|
|
124
126
|
inputStyles({
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getFieldContext } from '../../common/context.svelte.js';
|
|
3
|
+
import Label from '../Label/Label.svelte';
|
|
4
|
+
import Text from '../Text/Text.svelte';
|
|
5
|
+
import type { TextareaProps } from '../../types.js';
|
|
6
|
+
import { cleanClass, generateId } from '../../utils.js';
|
|
7
|
+
import type { FormEventHandler } from 'svelte/elements';
|
|
8
|
+
import { tv } from 'tailwind-variants';
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
ref = $bindable(null),
|
|
12
|
+
containerRef = $bindable(null),
|
|
13
|
+
shape = 'semi-round',
|
|
14
|
+
size = 'medium',
|
|
15
|
+
class: className,
|
|
16
|
+
grow,
|
|
17
|
+
value = $bindable<string>(),
|
|
18
|
+
...restProps
|
|
19
|
+
}: TextareaProps = $props();
|
|
20
|
+
|
|
21
|
+
const { label, description, readOnly, required, invalid, disabled, ...labelProps } =
|
|
22
|
+
$derived(getFieldContext());
|
|
23
|
+
|
|
24
|
+
const styles = tv({
|
|
25
|
+
base: 'w-full bg-gray-200 outline-none disabled:cursor-not-allowed disabled:bg-gray-300 disabled:text-gray-400 dark:bg-gray-600 dark:disabled:bg-gray-800 dark:disabled:text-gray-200',
|
|
26
|
+
variants: {
|
|
27
|
+
shape: {
|
|
28
|
+
rectangle: 'rounded-none',
|
|
29
|
+
'semi-round': '',
|
|
30
|
+
round: 'rounded-full',
|
|
31
|
+
},
|
|
32
|
+
padding: {
|
|
33
|
+
base: 'px-4 py-3',
|
|
34
|
+
round: 'px-5 py-3',
|
|
35
|
+
},
|
|
36
|
+
grow: {
|
|
37
|
+
true: 'resize-none',
|
|
38
|
+
false: '',
|
|
39
|
+
},
|
|
40
|
+
roundedSize: {
|
|
41
|
+
tiny: 'rounded-xl',
|
|
42
|
+
small: 'rounded-xl',
|
|
43
|
+
medium: 'rounded-2xl',
|
|
44
|
+
large: 'rounded-2xl',
|
|
45
|
+
giant: 'rounded-2xl',
|
|
46
|
+
},
|
|
47
|
+
textSize: {
|
|
48
|
+
tiny: 'text-xs',
|
|
49
|
+
small: 'text-sm',
|
|
50
|
+
medium: 'text-base',
|
|
51
|
+
large: 'text-lg',
|
|
52
|
+
giant: 'text-xl',
|
|
53
|
+
},
|
|
54
|
+
invalid: {
|
|
55
|
+
true: 'border-danger/80 border',
|
|
56
|
+
false: '',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const id = generateId();
|
|
62
|
+
const inputId = `input-${id}`;
|
|
63
|
+
const labelId = `label-${id}`;
|
|
64
|
+
const descriptionId = $derived(description ? `description-${id}` : undefined);
|
|
65
|
+
|
|
66
|
+
const onInput: FormEventHandler<HTMLTextAreaElement> = (event) => {
|
|
67
|
+
const element = event.target as HTMLTextAreaElement;
|
|
68
|
+
if (element && grow) {
|
|
69
|
+
element.style.height = 'auto';
|
|
70
|
+
element.style.height = `${element.scrollHeight}px`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
restProps?.oninput?.(event);
|
|
74
|
+
};
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<div class="flex w-full flex-col gap-1" bind:this={containerRef}>
|
|
78
|
+
{#if label}
|
|
79
|
+
<Label id={labelId} for={inputId} {label} {...labelProps} />
|
|
80
|
+
{/if}
|
|
81
|
+
|
|
82
|
+
{#if description}
|
|
83
|
+
<Text color="secondary" size="small" id={descriptionId}>{description}</Text>
|
|
84
|
+
{/if}
|
|
85
|
+
|
|
86
|
+
<div class="relative w-full">
|
|
87
|
+
<textarea
|
|
88
|
+
oninput={onInput}
|
|
89
|
+
id={inputId}
|
|
90
|
+
aria-labelledby={label && labelId}
|
|
91
|
+
{required}
|
|
92
|
+
aria-required={required}
|
|
93
|
+
{disabled}
|
|
94
|
+
aria-disabled={disabled}
|
|
95
|
+
aria-describedby={descriptionId}
|
|
96
|
+
readonly={readOnly}
|
|
97
|
+
aria-readonly={readOnly}
|
|
98
|
+
class={cleanClass(
|
|
99
|
+
styles({
|
|
100
|
+
shape,
|
|
101
|
+
textSize: size,
|
|
102
|
+
padding: shape === 'round' ? 'round' : 'base',
|
|
103
|
+
grow,
|
|
104
|
+
roundedSize: shape === 'semi-round' ? size : undefined,
|
|
105
|
+
invalid,
|
|
106
|
+
}),
|
|
107
|
+
className,
|
|
108
|
+
)}
|
|
109
|
+
bind:this={ref}
|
|
110
|
+
bind:value
|
|
111
|
+
{...restProps}
|
|
112
|
+
></textarea>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<style>
|
|
117
|
+
textarea::-ms-reveal {
|
|
118
|
+
display: none;
|
|
119
|
+
}
|
|
120
|
+
</style>
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,7 @@ export { default as VStack } from './components/Stack/VStack.svelte';
|
|
|
56
56
|
export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
|
|
57
57
|
export { default as Switch } from './components/Switch/Switch.svelte';
|
|
58
58
|
export { default as Text } from './components/Text/Text.svelte';
|
|
59
|
+
export { default as Textarea } from './components/Textarea/Textarea.svelte';
|
|
59
60
|
export { default as ThemeSwitcher } from './components/ThemeSwitcher/ThemeSwitcher.svelte';
|
|
60
61
|
export * from './services/command-palette-manager.svelte.js';
|
|
61
62
|
export * from './services/modal-manager.svelte.js';
|
package/dist/index.js
CHANGED
|
@@ -58,6 +58,7 @@ export { default as VStack } from './components/Stack/VStack.svelte';
|
|
|
58
58
|
export { default as SupporterBadge } from './components/SupporterBadge/SupporterBadge.svelte';
|
|
59
59
|
export { default as Switch } from './components/Switch/Switch.svelte';
|
|
60
60
|
export { default as Text } from './components/Text/Text.svelte';
|
|
61
|
+
export { default as Textarea } from './components/Textarea/Textarea.svelte';
|
|
61
62
|
export { default as ThemeSwitcher } from './components/ThemeSwitcher/ThemeSwitcher.svelte';
|
|
62
63
|
// helpers
|
|
63
64
|
export * from './services/command-palette-manager.svelte.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Translations } from './services/translation.svelte.js';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { HTMLAnchorAttributes, HTMLButtonAttributes, HTMLInputAttributes, HTMLLabelAttributes } from 'svelte/elements';
|
|
3
|
+
import type { HTMLAnchorAttributes, HTMLButtonAttributes, HTMLInputAttributes, HTMLLabelAttributes, HTMLTextareaAttributes } from 'svelte/elements';
|
|
4
4
|
export type Color = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
|
|
5
5
|
export type TextColor = Color | 'muted';
|
|
6
6
|
export type TextVariant = 'italic';
|
|
@@ -119,9 +119,19 @@ export type InputProps = BaseInputProps & {
|
|
|
119
119
|
trailingIcon?: IconLike | Snippet;
|
|
120
120
|
};
|
|
121
121
|
export type PasswordInputProps = BaseInputProps & {
|
|
122
|
+
ref?: HTMLInputElement | null;
|
|
122
123
|
translations?: TranslationProps<'show_password' | 'hide_password'>;
|
|
123
124
|
isVisible?: boolean;
|
|
124
125
|
};
|
|
126
|
+
export type TextareaProps = {
|
|
127
|
+
ref?: HTMLTextAreaElement | null;
|
|
128
|
+
containerRef?: HTMLElement | null;
|
|
129
|
+
class?: string;
|
|
130
|
+
value?: string;
|
|
131
|
+
size?: Size;
|
|
132
|
+
shape?: Shape;
|
|
133
|
+
grow?: boolean;
|
|
134
|
+
} & HTMLTextareaAttributes;
|
|
125
135
|
export type SelectItem = {
|
|
126
136
|
label?: string;
|
|
127
137
|
value: string;
|