Fix newlines in the contenteditable
This commit is contained in:
parent
a605c95890
commit
360bb1d714
|
|
@ -2,9 +2,17 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.root {
|
||||
white-space: pre-wrap;
|
||||
outline: none;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.root:empty::before {
|
||||
content: attr(data-placeholder);
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ export const ContentEditable = ({ value, placeholder, autoLines, onInput, class:
|
|||
}, [value]);
|
||||
|
||||
const handleKeyDown: JSX.KeyboardEventHandler<HTMLDivElement> = (e) => {
|
||||
if (e.key !== 'Enter') return;
|
||||
if (e.key !== 'Enter' || !ref.current) return;
|
||||
e.preventDefault();
|
||||
|
||||
const sel = window.getSelection();
|
||||
|
|
@ -79,7 +79,10 @@ export const ContentEditable = ({ value, placeholder, autoLines, onInput, class:
|
|||
const range = sel.getRangeAt(0);
|
||||
range.deleteContents();
|
||||
|
||||
const newline = document.createTextNode('\n');
|
||||
const endsWithNewline = ref.current.textContent?.endsWith('\n');
|
||||
const caretAtEnd = getCaretOffset(ref.current) === ref.current.textContent.length;
|
||||
|
||||
const newline = document.createTextNode('\n'.repeat((endsWithNewline || !caretAtEnd) ? 1 : 2));
|
||||
range.insertNode(newline);
|
||||
range.setStartAfter(newline);
|
||||
range.collapse(true);
|
||||
|
|
@ -87,11 +90,15 @@ export const ContentEditable = ({ value, placeholder, autoLines, onInput, class:
|
|||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
|
||||
(ref.current as any).value = ref.current.textContent;
|
||||
ref.current?.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
||||
};
|
||||
|
||||
const handleInput: JSX.EventHandler<JSX.TargetedInputEvent<HTMLDivElement>> = (e) => {
|
||||
if (autoLines && ref.current) resizeToContent(ref.current);
|
||||
if (ref.current) {
|
||||
(ref.current as any).value = ref.current.textContent;
|
||||
}
|
||||
onInput?.(e);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -33,12 +33,7 @@
|
|||
line-height: 1.9;
|
||||
color: var(--textColor);
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--text-muted);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import clsx from "clsx";
|
|||
import { CharacterEditor } from "./character-editor";
|
||||
import { LocationEditor } from "./location-editor";
|
||||
import { ChaptersEditor } from "./chapters-editor";
|
||||
import { useInputCallback } from "@common/hooks/useInputCallback";
|
||||
|
||||
const TABS: { id: Tab; label: string }[] = [
|
||||
{ id: "story", label: "Story" },
|
||||
|
|
@ -23,23 +24,21 @@ export const Editor = () => {
|
|||
return <div class={styles.editor} />;
|
||||
}
|
||||
|
||||
const handleInput = (e: Event) => {
|
||||
const text = (e.target as HTMLElement).textContent || '';
|
||||
const handleInput = useInputCallback((text: string) => {
|
||||
dispatch({
|
||||
type: 'EDIT_STORY',
|
||||
id: currentStory.id,
|
||||
text,
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleLoreInput = (e: Event) => {
|
||||
const lore = (e.target as HTMLElement).textContent || '';
|
||||
const handleLoreInput = useInputCallback((lore: string) => {
|
||||
dispatch({
|
||||
type: 'EDIT_LORE',
|
||||
id: currentStory.id,
|
||||
lore,
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleTabChange = (tab: Tab) => {
|
||||
dispatch({
|
||||
|
|
|
|||
Loading…
Reference in New Issue