39 lines
1.1 KiB
Svelte
39 lines
1.1 KiB
Svelte
<!--
|
|
Component: Textarea
|
|
Brutalist multi-line input. Same styling as Input but <textarea>.
|
|
Non-resizable by default (matches prototype).
|
|
-->
|
|
<script lang="ts">
|
|
import { cn } from '$shared/lib/cn';
|
|
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
|
|
|
interface Props extends HTMLTextareaAttributes {
|
|
label?: string;
|
|
error?: string;
|
|
rows?: number;
|
|
class?: string;
|
|
}
|
|
|
|
let { label, error, rows = 4, class: className, ...rest }: Props = $props();
|
|
|
|
const textareaClasses = $derived(cn(
|
|
'brutal-border bg-white px-4 py-3 text-carbon-black w-full resize-none',
|
|
'focus:outline-none focus:ring-2 focus:ring-burnt-oxide focus:ring-offset-2 focus:ring-offset-ochre-clay',
|
|
'transition-all duration-150',
|
|
'disabled:opacity-50 disabled:cursor-not-allowed',
|
|
className,
|
|
));
|
|
</script>
|
|
|
|
<div class="flex flex-col gap-2">
|
|
{#if label}
|
|
<label class="text-carbon-black">{label}</label>
|
|
{/if}
|
|
|
|
<textarea {rows} class={textareaClasses} {...rest}></textarea>
|
|
|
|
{#if error}
|
|
<span class="text-sm text-burnt-oxide">{error}</span>
|
|
{/if}
|
|
</div>
|