import Placeholder from '@tiptap/extension-placeholder'; import { EditorContent, useEditor, useEditorState } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import React, { useEffect, useMemo } from 'react'; import { normalizeSceneDescriptionHtml } from '../editor/sceneDescriptionHtml'; import modalStyles from '../editor/SceneDescriptionModal.module.css'; import { useEditorI18n } from '../editor/i18n/EditorI18nContext'; import styles from './NpcsEditorApp.module.css'; type NpcDescriptionFieldProps = { html: string; onCommit: (html: string) => void; }; function ToolButton({ active = false, title, onClick, children, }: { active?: boolean; title: string; onClick: () => void; children: React.ReactNode; }) { return ( ); } export function NpcDescriptionField({ html, onCommit }: NpcDescriptionFieldProps) { const { t } = useEditorI18n(); const extensions = useMemo( () => [ StarterKit.configure({ heading: { levels: [2, 3] }, codeBlock: false, link: false, }), Placeholder.configure({ placeholder: t('npcs.descriptionPlaceholder'), }), ], [t], ); const editor = useEditor({ extensions, content: html || '', immediatelyRender: true, shouldRerenderOnTransaction: true, editorProps: { attributes: { class: [modalStyles.prose, 'tiptap'].join(' '), 'aria-label': t('npcs.description'), }, }, onBlur: ({ editor: ed }) => { onCommit(normalizeSceneDescriptionHtml(ed.getHTML())); }, }); useEffect(() => { if (!editor) return; const current = normalizeSceneDescriptionHtml(editor.getHTML()); const next = normalizeSceneDescriptionHtml(html); if (current !== next) { editor.commands.setContent(html || '', { emitUpdate: false }); } }, [editor, html]); const toolbarState = useEditorState({ editor, selector: ({ editor: ed }) => ({ bold: ed.isActive('bold'), italic: ed.isActive('italic'), bulletList: ed.isActive('bulletList'), orderedList: ed.isActive('orderedList'), h2: ed.isActive('heading', { level: 2 }), h3: ed.isActive('heading', { level: 3 }), }), }); if (!editor) return null; return (
editor.chain().focus().toggleBold().run()} > B editor.chain().focus().toggleItalic().run()} > I
editor.chain().focus().toggleHeading({ level: 2 }).run()} > H2 editor.chain().focus().toggleHeading({ level: 3 }).run()} > H3
editor.chain().focus().toggleBulletList().run()} > • editor.chain().focus().toggleOrderedList().run()} > 1.
); }