2025-10-31 11:38:17 -04:00

69 lines
1.6 KiB
Svelte

<script lang="ts">
import type { Snippet } from 'svelte';
import { t } from 'svelte-i18n';
import { quintOut } from 'svelte/easing';
import { fly } from 'svelte/transition';
interface Props {
value: string;
label?: string;
description?: string;
required?: boolean;
disabled?: boolean;
isEdited?: boolean;
descriptionSnippet?: Snippet;
}
let {
value = $bindable(),
label = '',
description = '',
required = false,
disabled = false,
isEdited = false,
descriptionSnippet,
}: Props = $props();
const handleInput = (e: Event) => {
value = (e.target as HTMLInputElement).value;
};
</script>
<div class="mb-4 w-full">
<div class="flex h-6.5 place-items-center gap-1">
<label class="font-medium text-primary text-sm" for={label}>{label}</label>
{#if required}
<div class="text-red-400">*</div>
{/if}
{#if isEdited}
<div
transition:fly={{ x: 10, duration: 200, easing: quintOut }}
class="rounded-full bg-orange-100 px-2 text-[10px] text-orange-900"
>
{$t('unsaved_change')}
</div>
{/if}
</div>
{#if description}
<p class="immich-form-label pb-2 text-sm" id="{label}-desc">
{description}
</p>
{:else}
{@render descriptionSnippet?.()}
{/if}
<textarea
class="immich-form-input w-full pb-2"
aria-describedby={description ? `${label}-desc` : undefined}
aria-labelledby="{label}-label"
id={label}
name={label}
{required}
{value}
oninput={handleInput}
{disabled}
></textarea>
</div>