fix: Reset textarea to default size on submit

This commit is contained in:
April Hall 2025-02-07 22:02:47 -05:00
parent 69a8b23c20
commit b95fdf09ef
Signed by: arithefirst
GPG Key ID: 4508A15C4DB91C5B
4 changed files with 14 additions and 77 deletions

View File

@ -1,28 +0,0 @@
import Root from "./textarea.svelte";
type FormTextareaEvent<T extends Event = Event> = T & {
currentTarget: EventTarget & HTMLTextAreaElement;
};
type TextareaEvents = {
blur: FormTextareaEvent<FocusEvent>;
change: FormTextareaEvent<Event>;
click: FormTextareaEvent<MouseEvent>;
focus: FormTextareaEvent<FocusEvent>;
keydown: FormTextareaEvent<KeyboardEvent>;
keypress: FormTextareaEvent<KeyboardEvent>;
keyup: FormTextareaEvent<KeyboardEvent>;
mouseover: FormTextareaEvent<MouseEvent>;
mouseenter: FormTextareaEvent<MouseEvent>;
mouseleave: FormTextareaEvent<MouseEvent>;
paste: FormTextareaEvent<ClipboardEvent>;
input: FormTextareaEvent<InputEvent>;
};
export {
Root,
//
Root as Textarea,
type TextareaEvents,
type FormTextareaEvent,
};

View File

@ -1,43 +0,0 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLTextareaAttributes } from 'svelte/elements';
import type { TextareaEvents } from './index.js';
// Note: The autoResize directive is NOT part of the shadcn-svelte package,
// it just has to be added directly to the root component because of a
// Svelte limitation.
import { autoResize } from '$lib/functions/autoresize.svelte';
type $$Props = HTMLTextareaAttributes;
type $$Events = TextareaEvents;
let className: $$Props['class'] = undefined;
export let value: $$Props['value'] = undefined;
export { className as class };
// Workaround for https://github.com/sveltejs/svelte/issues/9305
// Fixed in Svelte 5, but not backported to 4.x.
export let readonly: $$Props['readonly'] = undefined;
</script>
<textarea
class={cn(
'flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
bind:value
{readonly}
on:blur
on:change
on:click
on:focus
on:keydown
on:keypress
on:keyup
on:mouseover
on:mouseenter
on:mouseleave
on:paste
on:input
use:autoResize
{...$$restProps}></textarea>

View File

@ -1,6 +1,6 @@
export function autoResize(node: HTMLElement) { export function autoResize(node: HTMLElement) {
function resize() { function resize() {
node.style.height = 'auto'; node.style.height = '40px';
node.style.height = node.scrollHeight + 'px'; node.style.height = node.scrollHeight + 'px';
} }

View File

@ -2,7 +2,7 @@
import { page } from '$app/state'; import { page } from '$app/state';
import Message from '$lib/components/message.svelte'; import Message from '$lib/components/message.svelte';
import { Button } from '$lib/components/ui/button/index'; import { Button } from '$lib/components/ui/button/index';
import Textarea from '$lib/components/ui/textarea/textarea.svelte'; import { autoResize } from '$lib/functions/autoresize.svelte';
import Websocket from '$lib/functions/clientWebsocket.svelte'; import Websocket from '$lib/functions/clientWebsocket.svelte';
import type { TypeMessage } from '$lib/types'; import type { TypeMessage } from '$lib/types';
import Send from 'lucide-svelte/icons/send'; import Send from 'lucide-svelte/icons/send';
@ -10,14 +10,14 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import type { PageData } from './$types'; import type { PageData } from './$types';
import { autoResize } from '$lib/functions/autoresize.svelte';
const { data }: { data: PageData } = $props(); const { data }: { data: PageData } = $props();
let user: string = uuidv4(); let user: string = uuidv4();
let socket: Websocket | undefined = $state(); let socket: Websocket | undefined = $state();
let msg: string = $state(''); let msg: string = $state('');
const channel = $derived(page.params.channel); const channel: string = $derived(page.params.channel);
let textareaRef: HTMLElement | undefined = $state();
// Connect on page load // Connect on page load
onMount(() => { onMount(() => {
@ -49,9 +49,17 @@
class="flex w-full gap-1" class="flex w-full gap-1"
onsubmit={() => { onsubmit={() => {
socket?.sendMessage(user!, msg); socket?.sendMessage(user!, msg);
if (textareaRef) textareaRef.style.height = '40px';
msg = ''; msg = '';
}}> }}>
<Textarea placeholder="Type Here" bind:value={msg} /> <textarea
<Button class="h-full w-14" type="submit"><Send class="size-full" /></Button> placeholder="Type Here"
bind:value={msg}
bind:this={textareaRef}
use:autoResize
class="flex min-h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm
placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring
disabled:cursor-not-allowed disabled:opacity-50"></textarea>
<Button class="h-full min-h-10 w-14" type="submit"><Send class="size-full" /></Button>
</form> </form>
</div> </div>