1
0
Fork 0
mirror of https://github.com/kou029w/quot.git synced 2025-01-19 16:38:06 +00:00
quot/app/views/components/editor.tsx

63 lines
2 KiB
TypeScript
Raw Normal View History

2022-08-28 17:49:49 +09:00
import { onCleanup, onMount } from "solid-js";
2022-09-16 21:30:29 +09:00
import { minimalSetup } from "codemirror";
2022-09-19 16:28:45 +09:00
import { emacsStyleKeymap } from "@codemirror/commands";
2022-09-16 21:30:29 +09:00
import { EditorView, keymap } from "@codemirror/view";
2022-09-01 23:54:20 +09:00
import type Pages from "../../protocol/pages";
2022-08-23 09:49:34 +09:00
import "./editor.css";
2022-09-16 21:30:29 +09:00
import { quotHighlighting, quotLanguage } from "../../syntax/quot";
2022-09-19 16:28:45 +09:00
import indentPlugins from "../../syntax/indent-plugins";
2022-08-28 17:49:49 +09:00
2022-08-24 12:49:02 +09:00
export default (props: {
2022-08-24 09:50:35 +09:00
id: number;
2022-08-28 17:49:49 +09:00
title: string;
text: string;
2022-08-24 12:49:02 +09:00
onUpdatePage: (content: Pages.RequestContentPage) => void;
2022-08-28 17:49:49 +09:00
}) => {
2022-09-16 21:30:29 +09:00
let ref: HTMLElement;
onMount(() => {
const view = new EditorView({
doc: props.text,
selection: { anchor: props.text.length },
parent: ref,
extensions: [
EditorView.updateListener.of((update) => {
if (!update.docChanged) return;
const defaultTitle = new Date()
.toLocaleDateString(navigator.language, {
year: "numeric",
month: "2-digit",
day: "2-digit",
})
.replaceAll("/", "-");
const [heading, ...lines] = update.state.doc.toJSON();
const title =
heading?.trim() || (lines.length === 0 ? "" : defaultTitle);
const text = [title, ...lines].join("\n");
2022-09-07 19:54:48 +09:00
props.onUpdatePage({ id: props.id, title, text });
2022-09-16 21:30:29 +09:00
}),
EditorView.lineWrapping,
2022-09-19 16:28:45 +09:00
keymap.of(emacsStyleKeymap.filter(({ key }) => key !== "Ctrl-v")),
2022-09-16 21:30:29 +09:00
minimalSetup,
quotLanguage,
quotHighlighting,
2022-09-19 16:28:45 +09:00
...indentPlugins,
2022-09-16 21:30:29 +09:00
],
});
ref.addEventListener("click", (e) => {
if (!(e.target instanceof HTMLElement)) return;
if (e.target.classList.contains("auto-link") && e.target.textContent) {
window.open(e.target.textContent, "_blank", "noreferrer");
}
});
onCleanup(() => view.destroy());
view.focus();
});
2022-09-07 19:09:24 +09:00
return (
<article
2022-09-16 21:30:29 +09:00
ref={(el) => (ref = el)}
id={props.id.toString(16)}
2022-09-07 19:09:24 +09:00
class="editor"
/>
);
2022-08-28 17:49:49 +09:00
};