|
|
<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(() => { |
|
|
|
|
|
if (open) { |
|
|
newTitle = title; |
|
|
} |
|
|
}); |
|
|
|
|
|
function close() { |
|
|
open = false; |
|
|
onclose?.(); |
|
|
} |
|
|
|
|
|
function save() { |
|
|
const trimmed = (newTitle ?? "").trim(); |
|
|
if (!trimmed) return; |
|
|
onsave?.({ title: trimmed }); |
|
|
close(); |
|
|
} |
|
|
|
|
|
onMount(() => { |
|
|
|
|
|
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} |
|
|
|