Replace notes textarea with collaborative CodeMirror editor
- CodeMirror 6 + y-codemirror.next for proper character-level Yjs sync (replaces delete-all/insert-all textarea binding) - Remote cursor awareness: colored carets with participant names - Line wrapping, placeholder text, history (undo/redo) - Awareness user fields include colorLight for cursor selection tint Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
360bd87de2
commit
5f21564a19
3 changed files with 243 additions and 46 deletions
|
|
@ -1,66 +1,106 @@
|
||||||
import { useEffect, useRef, useCallback } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { EditorView, keymap, placeholder } from "@codemirror/view";
|
||||||
|
import { EditorState } from "@codemirror/state";
|
||||||
|
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
||||||
|
import { syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language";
|
||||||
|
import { yCollab } from "y-codemirror.next";
|
||||||
import type { YjsState } from "~/lib/use-yjs";
|
import type { YjsState } from "~/lib/use-yjs";
|
||||||
|
|
||||||
interface NotesPanelProps {
|
interface NotesPanelProps {
|
||||||
yjs: YjsState;
|
yjs: YjsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const theme = EditorView.theme({
|
||||||
|
"&": {
|
||||||
|
height: "100%",
|
||||||
|
fontSize: "13px",
|
||||||
|
},
|
||||||
|
".cm-editor": {
|
||||||
|
height: "100%",
|
||||||
|
},
|
||||||
|
".cm-scroller": {
|
||||||
|
overflow: "auto",
|
||||||
|
fontFamily: "inherit",
|
||||||
|
},
|
||||||
|
".cm-content": {
|
||||||
|
padding: "12px",
|
||||||
|
caretColor: "#1f2937",
|
||||||
|
},
|
||||||
|
".cm-line": {
|
||||||
|
lineHeight: "1.5",
|
||||||
|
},
|
||||||
|
"&.cm-focused": {
|
||||||
|
outline: "none",
|
||||||
|
},
|
||||||
|
// Remote cursor styling
|
||||||
|
".cm-ySelectionInfo": {
|
||||||
|
fontSize: "10px",
|
||||||
|
fontFamily: "system-ui, sans-serif",
|
||||||
|
padding: "1px 4px",
|
||||||
|
borderRadius: "3px",
|
||||||
|
opacity: "0.9",
|
||||||
|
fontWeight: "500",
|
||||||
|
position: "absolute",
|
||||||
|
top: "-1.2em",
|
||||||
|
left: "-1px",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export function NotesPanel({ yjs }: NotesPanelProps) {
|
export function NotesPanel({ yjs }: NotesPanelProps) {
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const { t } = useTranslation("planner");
|
||||||
const isLocalChange = useRef(false);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const viewRef = useRef<EditorView | null>(null);
|
||||||
|
|
||||||
// Sync Y.Text → textarea
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const textarea = textareaRef.current;
|
if (!containerRef.current) return;
|
||||||
if (!textarea) return;
|
|
||||||
|
|
||||||
// Set initial value
|
// Set awareness user fields for cursor display
|
||||||
textarea.value = yjs.notes.toString();
|
const localState = yjs.awareness.getLocalState() as Record<string, unknown> | null;
|
||||||
|
const user = localState?.user as { name: string; color: string } | undefined;
|
||||||
|
if (user) {
|
||||||
|
yjs.awareness.setLocalStateField("user", {
|
||||||
|
...user,
|
||||||
|
colorLight: user.color + "30",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const observer = () => {
|
const state = EditorState.create({
|
||||||
if (isLocalChange.current) return;
|
extensions: [
|
||||||
const pos = textarea.selectionStart;
|
keymap.of([...defaultKeymap, ...historyKeymap]),
|
||||||
textarea.value = yjs.notes.toString();
|
history(),
|
||||||
textarea.selectionStart = pos;
|
syntaxHighlighting(defaultHighlightStyle),
|
||||||
textarea.selectionEnd = pos;
|
EditorView.lineWrapping,
|
||||||
|
placeholder(t("notes.placeholder")),
|
||||||
|
theme,
|
||||||
|
yCollab(yjs.notes, yjs.awareness, {
|
||||||
|
undoManager: yjs.undoManager,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const view = new EditorView({
|
||||||
|
state,
|
||||||
|
parent: containerRef.current,
|
||||||
|
});
|
||||||
|
|
||||||
|
viewRef.current = view;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
view.destroy();
|
||||||
|
viewRef.current = null;
|
||||||
};
|
};
|
||||||
|
}, [yjs]);
|
||||||
yjs.notes.observe(observer);
|
|
||||||
return () => yjs.notes.unobserve(observer);
|
|
||||||
}, [yjs.notes]);
|
|
||||||
|
|
||||||
// textarea → Y.Text
|
|
||||||
const handleInput = useCallback(
|
|
||||||
(e: React.FormEvent<HTMLTextAreaElement>) => {
|
|
||||||
const textarea = e.currentTarget;
|
|
||||||
const newValue = textarea.value;
|
|
||||||
const currentValue = yjs.notes.toString();
|
|
||||||
|
|
||||||
if (newValue === currentValue) return;
|
|
||||||
|
|
||||||
isLocalChange.current = true;
|
|
||||||
yjs.doc.transact(() => {
|
|
||||||
yjs.notes.delete(0, yjs.notes.length);
|
|
||||||
yjs.notes.insert(0, newValue);
|
|
||||||
}, "local");
|
|
||||||
isLocalChange.current = false;
|
|
||||||
},
|
|
||||||
[yjs.notes, yjs.doc],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full flex-col">
|
<div className="flex h-full flex-col">
|
||||||
<div className="border-b border-gray-200 px-4 py-3">
|
<div className="border-b border-gray-200 px-4 py-3">
|
||||||
<h2 className="text-sm font-medium text-gray-900">Notes</h2>
|
<h2 className="text-sm font-medium text-gray-900">
|
||||||
</div>
|
{t("sidebar.notes")}
|
||||||
<div className="flex-1 p-2">
|
</h2>
|
||||||
<textarea
|
|
||||||
ref={textareaRef}
|
|
||||||
onInput={handleInput}
|
|
||||||
className="h-full w-full resize-none rounded border border-gray-200 p-3 text-sm text-gray-700 placeholder-gray-400 focus:border-blue-300 focus:outline-none"
|
|
||||||
placeholder="Add notes for this session..."
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div ref={containerRef} className="flex-1 overflow-hidden" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@
|
||||||
"lint": "eslint ."
|
"lint": "eslint ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@codemirror/commands": "^6.10.3",
|
||||||
|
"@codemirror/language": "^6.12.3",
|
||||||
|
"@codemirror/state": "^6.6.0",
|
||||||
|
"@codemirror/view": "^6.41.0",
|
||||||
"@geoman-io/leaflet-geoman-free": "^2.19.3",
|
"@geoman-io/leaflet-geoman-free": "^2.19.3",
|
||||||
"@react-router/node": "catalog:",
|
"@react-router/node": "catalog:",
|
||||||
"@react-router/serve": "catalog:",
|
"@react-router/serve": "catalog:",
|
||||||
|
|
@ -22,6 +26,7 @@
|
||||||
"@trails-cool/map": "workspace:*",
|
"@trails-cool/map": "workspace:*",
|
||||||
"@trails-cool/types": "workspace:*",
|
"@trails-cool/types": "workspace:*",
|
||||||
"@trails-cool/ui": "workspace:*",
|
"@trails-cool/ui": "workspace:*",
|
||||||
|
"codemirror": "^6.0.2",
|
||||||
"drizzle-orm": "catalog:",
|
"drizzle-orm": "catalog:",
|
||||||
"isbot": "^5.1.37",
|
"isbot": "^5.1.37",
|
||||||
"lib0": "^0.2.117",
|
"lib0": "^0.2.117",
|
||||||
|
|
@ -31,6 +36,7 @@
|
||||||
"react-dom": "catalog:",
|
"react-dom": "catalog:",
|
||||||
"react-router": "catalog:",
|
"react-router": "catalog:",
|
||||||
"ws": "^8.20.0",
|
"ws": "^8.20.0",
|
||||||
|
"y-codemirror.next": "^0.3.5",
|
||||||
"y-protocols": "^1.0.7",
|
"y-protocols": "^1.0.7",
|
||||||
"y-websocket": "^3.0.0",
|
"y-websocket": "^3.0.0",
|
||||||
"yjs": "^13.6.30"
|
"yjs": "^13.6.30"
|
||||||
|
|
|
||||||
151
pnpm-lock.yaml
generated
151
pnpm-lock.yaml
generated
|
|
@ -285,6 +285,18 @@ importers:
|
||||||
|
|
||||||
apps/planner:
|
apps/planner:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@codemirror/commands':
|
||||||
|
specifier: ^6.10.3
|
||||||
|
version: 6.10.3
|
||||||
|
'@codemirror/language':
|
||||||
|
specifier: ^6.12.3
|
||||||
|
version: 6.12.3
|
||||||
|
'@codemirror/state':
|
||||||
|
specifier: ^6.6.0
|
||||||
|
version: 6.6.0
|
||||||
|
'@codemirror/view':
|
||||||
|
specifier: ^6.41.0
|
||||||
|
version: 6.41.0
|
||||||
'@geoman-io/leaflet-geoman-free':
|
'@geoman-io/leaflet-geoman-free':
|
||||||
specifier: ^2.19.3
|
specifier: ^2.19.3
|
||||||
version: 2.19.3(leaflet@1.9.4)
|
version: 2.19.3(leaflet@1.9.4)
|
||||||
|
|
@ -318,6 +330,9 @@ importers:
|
||||||
'@trails-cool/ui':
|
'@trails-cool/ui':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/ui
|
version: link:../../packages/ui
|
||||||
|
codemirror:
|
||||||
|
specifier: ^6.0.2
|
||||||
|
version: 6.0.2
|
||||||
drizzle-orm:
|
drizzle-orm:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(postgres@3.4.9)
|
version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(postgres@3.4.9)
|
||||||
|
|
@ -345,6 +360,9 @@ importers:
|
||||||
ws:
|
ws:
|
||||||
specifier: ^8.20.0
|
specifier: ^8.20.0
|
||||||
version: 8.20.0
|
version: 8.20.0
|
||||||
|
y-codemirror.next:
|
||||||
|
specifier: ^0.3.5
|
||||||
|
version: 0.3.5(@codemirror/state@6.6.0)(@codemirror/view@6.41.0)(yjs@13.6.30)
|
||||||
y-protocols:
|
y-protocols:
|
||||||
specifier: ^1.0.7
|
specifier: ^1.0.7
|
||||||
version: 1.0.7(yjs@13.6.30)
|
version: 1.0.7(yjs@13.6.30)
|
||||||
|
|
@ -588,6 +606,27 @@ packages:
|
||||||
resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
|
resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
'@codemirror/autocomplete@6.20.1':
|
||||||
|
resolution: {integrity: sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A==}
|
||||||
|
|
||||||
|
'@codemirror/commands@6.10.3':
|
||||||
|
resolution: {integrity: sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==}
|
||||||
|
|
||||||
|
'@codemirror/language@6.12.3':
|
||||||
|
resolution: {integrity: sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==}
|
||||||
|
|
||||||
|
'@codemirror/lint@6.9.5':
|
||||||
|
resolution: {integrity: sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==}
|
||||||
|
|
||||||
|
'@codemirror/search@6.6.0':
|
||||||
|
resolution: {integrity: sha512-koFuNXcDvyyotWcgOnZGmY7LZqEOXZaaxD/j6n18TCLx2/9HieZJ5H6hs1g8FiRxBD0DNfs0nXn17g872RmYdw==}
|
||||||
|
|
||||||
|
'@codemirror/state@6.6.0':
|
||||||
|
resolution: {integrity: sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==}
|
||||||
|
|
||||||
|
'@codemirror/view@6.41.0':
|
||||||
|
resolution: {integrity: sha512-6H/qadXsVuDY219Yljhohglve8xf4B8xJkVOEWfA5uiYKiTFppjqsvsfR5iPA0RbvRBoOyTZpbLIxe9+0UR8xA==}
|
||||||
|
|
||||||
'@csstools/color-helpers@6.0.2':
|
'@csstools/color-helpers@6.0.2':
|
||||||
resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==}
|
resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==}
|
||||||
engines: {node: '>=20.19.0'}
|
engines: {node: '>=20.19.0'}
|
||||||
|
|
@ -1185,6 +1224,18 @@ packages:
|
||||||
'@levischuck/tiny-cbor@0.2.11':
|
'@levischuck/tiny-cbor@0.2.11':
|
||||||
resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==}
|
resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==}
|
||||||
|
|
||||||
|
'@lezer/common@1.5.2':
|
||||||
|
resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==}
|
||||||
|
|
||||||
|
'@lezer/highlight@1.2.3':
|
||||||
|
resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
|
||||||
|
|
||||||
|
'@lezer/lr@1.4.8':
|
||||||
|
resolution: {integrity: sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==}
|
||||||
|
|
||||||
|
'@marijn/find-cluster-break@1.0.2':
|
||||||
|
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
|
||||||
|
|
||||||
'@mjackson/node-fetch-server@0.2.0':
|
'@mjackson/node-fetch-server@0.2.0':
|
||||||
resolution: {integrity: sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng==}
|
resolution: {integrity: sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng==}
|
||||||
|
|
||||||
|
|
@ -2368,6 +2419,9 @@ packages:
|
||||||
cjs-module-lexer@2.2.0:
|
cjs-module-lexer@2.2.0:
|
||||||
resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==}
|
resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==}
|
||||||
|
|
||||||
|
codemirror@6.0.2:
|
||||||
|
resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
|
||||||
|
|
||||||
colorette@2.0.20:
|
colorette@2.0.20:
|
||||||
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
||||||
|
|
||||||
|
|
@ -2404,6 +2458,9 @@ packages:
|
||||||
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
crelt@1.0.6:
|
||||||
|
resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
@ -3627,6 +3684,9 @@ packages:
|
||||||
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
|
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
|
||||||
engines: {node: '>=14.16'}
|
engines: {node: '>=14.16'}
|
||||||
|
|
||||||
|
style-mod@4.1.3:
|
||||||
|
resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
|
||||||
|
|
||||||
sweepline-intersections@1.5.0:
|
sweepline-intersections@1.5.0:
|
||||||
resolution: {integrity: sha512-AoVmx72QHpKtItPu72TzFL+kcYjd67BPLDoR0LarIk+xyaRg+pDTMFXndIEvZf9xEKnJv6JdhgRMnocoG0D3AQ==}
|
resolution: {integrity: sha512-AoVmx72QHpKtItPu72TzFL+kcYjd67BPLDoR0LarIk+xyaRg+pDTMFXndIEvZf9xEKnJv6JdhgRMnocoG0D3AQ==}
|
||||||
|
|
||||||
|
|
@ -3909,6 +3969,9 @@ packages:
|
||||||
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
w3c-keyname@2.2.8:
|
||||||
|
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
||||||
|
|
||||||
w3c-xmlserializer@5.0.0:
|
w3c-xmlserializer@5.0.0:
|
||||||
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
|
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
@ -3974,6 +4037,13 @@ packages:
|
||||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||||
engines: {node: '>=0.4'}
|
engines: {node: '>=0.4'}
|
||||||
|
|
||||||
|
y-codemirror.next@0.3.5:
|
||||||
|
resolution: {integrity: sha512-VluNu3e5HfEXybnypnsGwKAj+fKLd4iAnR7JuX1Sfyydmn1jCBS5wwEL/uS04Ch2ib0DnMAOF6ZRR/8kK3wyGw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@codemirror/state': ^6.0.0
|
||||||
|
'@codemirror/view': ^6.0.0
|
||||||
|
yjs: ^13.5.6
|
||||||
|
|
||||||
y-protocols@1.0.7:
|
y-protocols@1.0.7:
|
||||||
resolution: {integrity: sha512-YSVsLoXxO67J6eE/nV4AtFtT3QEotZf5sK5BHxFBXso7VDUT3Tx07IfA6hsu5Q5OmBdMkQVmFZ9QOA7fikWvnw==}
|
resolution: {integrity: sha512-YSVsLoXxO67J6eE/nV4AtFtT3QEotZf5sK5BHxFBXso7VDUT3Tx07IfA6hsu5Q5OmBdMkQVmFZ9QOA7fikWvnw==}
|
||||||
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
|
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
|
||||||
|
|
@ -4209,6 +4279,52 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
css-tree: 3.2.1
|
css-tree: 3.2.1
|
||||||
|
|
||||||
|
'@codemirror/autocomplete@6.20.1':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.12.3
|
||||||
|
'@codemirror/state': 6.6.0
|
||||||
|
'@codemirror/view': 6.41.0
|
||||||
|
'@lezer/common': 1.5.2
|
||||||
|
|
||||||
|
'@codemirror/commands@6.10.3':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.12.3
|
||||||
|
'@codemirror/state': 6.6.0
|
||||||
|
'@codemirror/view': 6.41.0
|
||||||
|
'@lezer/common': 1.5.2
|
||||||
|
|
||||||
|
'@codemirror/language@6.12.3':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.6.0
|
||||||
|
'@codemirror/view': 6.41.0
|
||||||
|
'@lezer/common': 1.5.2
|
||||||
|
'@lezer/highlight': 1.2.3
|
||||||
|
'@lezer/lr': 1.4.8
|
||||||
|
style-mod: 4.1.3
|
||||||
|
|
||||||
|
'@codemirror/lint@6.9.5':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.6.0
|
||||||
|
'@codemirror/view': 6.41.0
|
||||||
|
crelt: 1.0.6
|
||||||
|
|
||||||
|
'@codemirror/search@6.6.0':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.6.0
|
||||||
|
'@codemirror/view': 6.41.0
|
||||||
|
crelt: 1.0.6
|
||||||
|
|
||||||
|
'@codemirror/state@6.6.0':
|
||||||
|
dependencies:
|
||||||
|
'@marijn/find-cluster-break': 1.0.2
|
||||||
|
|
||||||
|
'@codemirror/view@6.41.0':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.6.0
|
||||||
|
crelt: 1.0.6
|
||||||
|
style-mod: 4.1.3
|
||||||
|
w3c-keyname: 2.2.8
|
||||||
|
|
||||||
'@csstools/color-helpers@6.0.2': {}
|
'@csstools/color-helpers@6.0.2': {}
|
||||||
|
|
||||||
'@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
|
'@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
|
||||||
|
|
@ -4573,6 +4689,18 @@ snapshots:
|
||||||
|
|
||||||
'@levischuck/tiny-cbor@0.2.11': {}
|
'@levischuck/tiny-cbor@0.2.11': {}
|
||||||
|
|
||||||
|
'@lezer/common@1.5.2': {}
|
||||||
|
|
||||||
|
'@lezer/highlight@1.2.3':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.5.2
|
||||||
|
|
||||||
|
'@lezer/lr@1.4.8':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.5.2
|
||||||
|
|
||||||
|
'@marijn/find-cluster-break@1.0.2': {}
|
||||||
|
|
||||||
'@mjackson/node-fetch-server@0.2.0': {}
|
'@mjackson/node-fetch-server@0.2.0': {}
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)':
|
'@napi-rs/wasm-runtime@1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)':
|
||||||
|
|
@ -5935,6 +6063,16 @@ snapshots:
|
||||||
|
|
||||||
cjs-module-lexer@2.2.0: {}
|
cjs-module-lexer@2.2.0: {}
|
||||||
|
|
||||||
|
codemirror@6.0.2:
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.20.1
|
||||||
|
'@codemirror/commands': 6.10.3
|
||||||
|
'@codemirror/language': 6.12.3
|
||||||
|
'@codemirror/lint': 6.9.5
|
||||||
|
'@codemirror/search': 6.6.0
|
||||||
|
'@codemirror/state': 6.6.0
|
||||||
|
'@codemirror/view': 6.41.0
|
||||||
|
|
||||||
colorette@2.0.20: {}
|
colorette@2.0.20: {}
|
||||||
|
|
||||||
compressible@2.0.18:
|
compressible@2.0.18:
|
||||||
|
|
@ -5969,6 +6107,8 @@ snapshots:
|
||||||
|
|
||||||
cookie@1.1.1: {}
|
cookie@1.1.1: {}
|
||||||
|
|
||||||
|
crelt@1.0.6: {}
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key: 3.1.1
|
path-key: 3.1.1
|
||||||
|
|
@ -7158,6 +7298,8 @@ snapshots:
|
||||||
|
|
||||||
strip-json-comments@5.0.3: {}
|
strip-json-comments@5.0.3: {}
|
||||||
|
|
||||||
|
style-mod@4.1.3: {}
|
||||||
|
|
||||||
sweepline-intersections@1.5.0:
|
sweepline-intersections@1.5.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
tinyqueue: 2.0.3
|
tinyqueue: 2.0.3
|
||||||
|
|
@ -7368,6 +7510,8 @@ snapshots:
|
||||||
|
|
||||||
void-elements@3.1.0: {}
|
void-elements@3.1.0: {}
|
||||||
|
|
||||||
|
w3c-keyname@2.2.8: {}
|
||||||
|
|
||||||
w3c-xmlserializer@5.0.0:
|
w3c-xmlserializer@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
xml-name-validator: 5.0.0
|
xml-name-validator: 5.0.0
|
||||||
|
|
@ -7416,6 +7560,13 @@ snapshots:
|
||||||
|
|
||||||
xtend@4.0.2: {}
|
xtend@4.0.2: {}
|
||||||
|
|
||||||
|
y-codemirror.next@0.3.5(@codemirror/state@6.6.0)(@codemirror/view@6.41.0)(yjs@13.6.30):
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.6.0
|
||||||
|
'@codemirror/view': 6.41.0
|
||||||
|
lib0: 0.2.117
|
||||||
|
yjs: 13.6.30
|
||||||
|
|
||||||
y-protocols@1.0.7(yjs@13.6.30):
|
y-protocols@1.0.7(yjs@13.6.30):
|
||||||
dependencies:
|
dependencies:
|
||||||
lib0: 0.2.117
|
lib0: 0.2.117
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue