Files
ttrpg-tools/src/components/journal/CreateSessionDialog.tsx
T
hypercross 40b6fbe157 feat(ui): replace unicode icons with solid-icons
Swap emoji and unicode glyphs for Tabler components so icons inherit
currentColor and font-size and render consistently across platforms.

- add src/components/doc-icons.ts to resolve doc-entry frontmatter icon
  keys to components; frontmatter now stores semantic keys
- replace the align-*.png assets with TbOutlineAlign* icons
- render RevealManager action SVGs as components instead of injected
  innerHTML strings
- carry completion icons via an optional CompletionItem.icon field
2026-09-13 14:01:03 +08:00

88 lines
2.6 KiB
TypeScript

/**
* CreateSessionDialog — modal for naming a new session
*/
import { Component, createSignal, onMount } from "solid-js";
import { TbOutlineX } from "solid-icons/tb";
import { createSession, joinSession } from "../stores/journalStream";
interface CreateSessionDialogProps {
onClose: () => void;
}
export const CreateSessionDialog: Component<CreateSessionDialogProps> = (
props,
) => {
const [name, setName] = createSignal("");
const [creating, setCreating] = createSignal(false);
let inputRef!: HTMLInputElement;
const handleCreate = async () => {
const trimmed = name().trim();
if (!trimmed) return;
setCreating(true);
try {
const id = await createSession(trimmed);
if (id) await joinSession(id);
} catch (e) {
console.error("[journal] failed to create session:", e);
} finally {
setName("");
setCreating(false);
props.onClose();
}
};
onMount(() => inputRef?.focus());
return (
<div
class="absolute inset-0 z-50 flex items-center justify-center bg-black/20"
onClick={props.onClose}
>
<div
class="bg-white rounded-lg border border-gray-200 shadow-xl w-[280px] p-4 space-y-3"
onClick={(e) => e.stopPropagation()}
>
<div class="flex items-center justify-between">
<h3 class="text-sm font-semibold text-gray-800">新建会话</h3>
<button
onClick={props.onClose}
class="text-gray-400 hover:text-gray-600 text-sm"
>
<TbOutlineX />
</button>
</div>
<p class="text-xs text-gray-500">输入新会话的名称。</p>
<input
ref={inputRef!}
type="text"
value={name()}
onInput={(e) => setName(e.currentTarget.value)}
onKeyDown={(e) => {
if (e.key === "Enter") handleCreate();
if (e.key === "Escape") props.onClose();
}}
placeholder="会话名称"
class="w-full border border-gray-300 rounded px-2 py-1.5 text-sm"
autofocus
/>
<div class="flex justify-end gap-1">
<button
onClick={props.onClose}
class="px-3 py-1 text-xs text-gray-600 hover:text-gray-800"
>
取消
</button>
<button
onClick={handleCreate}
disabled={!name().trim()}
class="bg-blue-600 text-white rounded px-3 py-1 text-xs font-medium hover:bg-blue-700 disabled:opacity-50"
>
创建
</button>
</div>
</div>
</div>
);
};