Spaces:
Runtime error
Runtime error
| <script lang="ts"> | |
| import Modal from "$lib/components/Modal.svelte"; | |
| import { onMount } from "svelte"; | |
| interface Props { | |
| open?: boolean; | |
| title?: string; | |
| onclose?: () => void; | |
| onsave?: (payload: { title: string }) => void; | |
| } | |
| let { open = false, title = "", onclose, onsave }: Props = $props(); | |
| let newTitle = $state(title); | |
| let inputEl: HTMLInputElement | undefined = $state(); | |
| $effect(() => { | |
| // keep local input in sync if parent changes title while open | |
| if (open) { | |
| newTitle = title; | |
| } | |
| }); | |
| function close() { | |
| open = false; | |
| onclose?.(); | |
| } | |
| function save() { | |
| const trimmed = (newTitle ?? "").trim(); | |
| if (!trimmed) return; | |
| onsave?.({ title: trimmed }); | |
| close(); | |
| } | |
| onMount(() => { | |
| // small delay to ensure modal mounted then focus/select | |
| setTimeout(() => { | |
| inputEl?.focus(); | |
| inputEl?.select(); | |
| }, 0); | |
| }); | |
| </script> | |
| {#if open} | |
| <Modal onclose={close} width="w-[90dvh] md:w-[480px]"> | |
| <form | |
| class="flex w-full flex-col gap-5 p-6" | |
| onsubmit={(e) => { | |
| e.preventDefault(); | |
| save(); | |
| }} | |
| > | |
| <div class="flex items-start justify-between"> | |
| <h2 class="text-xl font-semibold text-gray-800 dark:text-gray-200">Rename conversation</h2> | |
| <button type="button" class="group" onclick={close} aria-label="Close"> | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 32 32" | |
| class="size-5 text-gray-700 group-hover:text-gray-500 dark:text-gray-300 dark:group-hover:text-gray-400" | |
| ><path | |
| d="M24 9.41 22.59 8 16 14.59 9.41 8 8 9.41 14.59 16 8 22.59 9.41 24 16 17.41 22.59 24 24 22.59 17.41 16 24 9.41z" | |
| fill="currentColor" | |
| /></svg | |
| > | |
| </button> | |
| </div> | |
| <div class="flex flex-col gap-2"> | |
| <label for="conv-title" class="text-sm text-gray-600 dark:text-gray-400">Title</label> | |
| <input | |
| autocomplete="off" | |
| id="conv-title" | |
| bind:this={inputEl} | |
| value={newTitle} | |
| oninput={(e) => (newTitle = (e.currentTarget as HTMLInputElement).value)} | |
| class="w-full rounded-xl border border-gray-200 bg-white px-3 py-2 text-[15px] text-gray-800 outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder:text-gray-500 dark:focus:ring-gray-700" | |
| placeholder="Enter a title" | |
| /> | |
| </div> | |
| <div class="flex items-center justify-end gap-2"> | |
| <button | |
| type="button" | |
| class="inline-flex items-center rounded-xl border border-gray-300 bg-white px-3 py-1.5 text-sm font-medium text-gray-900 shadow hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-700 dark:text-gray-100 dark:hover:bg-gray-600" | |
| onclick={close} | |
| > | |
| Cancel | |
| </button> | |
| <button | |
| type="submit" | |
| class="inline-flex items-center rounded-xl border border-gray-900 bg-gray-900 px-3 py-1.5 text-sm font-semibold text-white hover:bg-black disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-100 dark:bg-gray-100 dark:text-gray-900 dark:hover:bg-white" | |
| disabled={!newTitle?.trim()} | |
| > | |
| Save | |
| </button> | |
| </div> | |
| </form> | |
| </Modal> | |
| {/if} | |