1
0
Fork 0
tsgames/src/games/storywriter/components/editor.tsx

89 lines
2.9 KiB
TypeScript

import { ContentEditable } from "@common/components/ContentEditable";
import { highlight } from "@common/highlight";
import { useAppState, type Tab } from "../contexts/state";
import styles from '../assets/editor.module.css';
import { useMemo } from "preact/hooks";
import clsx from "clsx";
import { CharacterEditor } from "./character-editor";
import { LocationEditor } from "./location-editor";
import { ChaptersEditor } from "./chapters-editor";
import { LoreEditor } from "./lore-editor";
import { useInputCallback } from "@common/hooks/useInputCallback";
const TABS: { id: Tab; label: string }[] = [
{ id: "story", label: "Story" },
{ id: "chapters", label: "Chapters" },
{ id: "lore", label: "Lore" },
{ id: "characters", label: "Characters" },
{ id: "locations", label: "Locations" },
];
export const Editor = () => {
const { currentStory, dispatch } = useAppState();
const handleInput = useInputCallback((text: string) => {
if (!currentStory) return;
dispatch({
type: 'EDIT_STORY',
id: currentStory.id,
text,
});
}, [currentStory?.id]);
const handleTabChange = (tab: Tab) => {
if (!currentStory) return;
dispatch({
type: 'SET_CURRENT_TAB',
id: currentStory.id,
tab,
});
};
const storyValue = useMemo(() => currentStory ? highlight(currentStory.text) : '', [currentStory?.text]);
if (!currentStory) {
return <div class={styles.editor} />;
}
return (
<div class={styles.editor}>
<div class={styles.title}>
{currentStory.title}
</div>
<div class={styles.content}>
{currentStory.currentTab === "story" && (
<ContentEditable
class={styles.editable}
value={storyValue}
onInput={handleInput}
placeholder="Start writing your story..."
/>
)}
{currentStory.currentTab === "lore" && (
<LoreEditor />
)}
{currentStory.currentTab === "characters" && (
<CharacterEditor />
)}
{currentStory.currentTab === "locations" && (
<LocationEditor />
)}
{currentStory.currentTab === "chapters" && (
<ChaptersEditor />
)}
</div>
<div class={styles.tabs}>
{TABS.map((tab) => (
<button
key={tab.id}
class={clsx(styles.tab, currentStory.currentTab === tab.id && styles.active)}
onClick={() => handleTabChange(tab.id)}
>
{tab.label}
</button>
))}
</div>
</div>
);
};