bout to be noice

This commit is contained in:
Michael Freno
2025-12-25 23:26:47 -05:00
parent 95604bff59
commit c50bef3bf8

View File

@@ -231,6 +231,7 @@ const KEYBOARD_SHORTCUTS: ShortcutCategory[] = [
name: "Insert",
shortcuts: [
{ keys: "⌘ K", keysAlt: "Ctrl K", description: "Insert/Edit Link" },
{ keys: "⌘ R", keysAlt: "Ctrl R", description: "Insert Reference [n]" },
{ keys: "⌘ ⇧ C", keysAlt: "Ctrl Shift C", description: "Code Block" },
{ keys: "⌘ Enter", keysAlt: "Ctrl Enter", description: "Hard Break" },
{ keys: "⌘ ⇧ -", keysAlt: "Ctrl Shift -", description: "Horizontal Rule" }
@@ -500,6 +501,15 @@ export default function TextEditor(props: TextEditorProps) {
attributes: {
class: "focus:outline-none"
},
handleKeyDown(view, event) {
// Cmd/Ctrl+R for inserting reference
if ((event.metaKey || event.ctrlKey) && event.key === "r") {
event.preventDefault();
insertReference();
return true;
}
return false;
},
handleClickOn(view, pos, node, nodePos, event) {
const target = event.target as HTMLElement;
@@ -747,6 +757,50 @@ export default function TextEditor(props: TextEditorProps) {
.run();
};
const insertReference = () => {
const instance = editor();
if (!instance) return;
// Get next reference number by scanning document
const doc = instance.state.doc;
const foundRefs = new Set<string>();
doc.descendants((node: any) => {
if (node.isText && node.marks) {
const hasSuperscript = node.marks.some(
(mark: any) => mark.type.name === "superscript"
);
if (hasSuperscript) {
const text = node.text || "";
const match = text.match(/^\[(.+?)\]$/);
if (match) {
foundRefs.add(match[1]);
}
}
}
});
// Calculate next number
const numericRefs = Array.from(foundRefs)
.map((ref) => parseInt(ref))
.filter((num) => !isNaN(num));
const nextNum = numericRefs.length > 0 ? Math.max(...numericRefs) + 1 : 1;
const refNum = window.prompt("Reference number:", nextNum.toString());
if (refNum === null || refNum.trim() === "") return;
// Insert [n] with superscript
instance
.chain()
.focus()
.insertContent({
type: "text",
text: `[${refNum.trim()}]`,
marks: [{ type: "superscript" }]
})
.run();
};
const addIframe = () => {
const instance = editor();
if (!instance) return;
@@ -1781,27 +1835,6 @@ export default function TextEditor(props: TextEditorProps) {
}}
>
<div class="flex flex-wrap gap-1 pb-2">
{/* Undo/Redo buttons - critical for mobile */}
<button
type="button"
onClick={() => instance().chain().focus().undo().run()}
disabled={!instance().can().undo()}
class="hover:bg-surface1 touch-manipulation rounded px-2 py-1 text-xs select-none disabled:cursor-not-allowed disabled:opacity-30"
title="Undo (Cmd/Ctrl+Z)"
>
</button>
<button
type="button"
onClick={() => instance().chain().focus().redo().run()}
disabled={!instance().can().redo()}
class="hover:bg-surface1 touch-manipulation rounded px-2 py-1 text-xs select-none disabled:cursor-not-allowed disabled:opacity-30"
title="Redo (Cmd/Ctrl+Shift+Z)"
>
</button>
<div class="border-surface2 mx-1 border-l"></div>
<button
type="button"
onClick={() =>
@@ -1899,6 +1932,14 @@ export default function TextEditor(props: TextEditorProps) {
>
X<sub class="text-[0.6em]">n</sub>
</button>
<button
type="button"
onClick={insertReference}
class="hover:bg-surface1 touch-manipulation rounded px-2 py-1 text-xs select-none"
title="Insert Reference [n] (Cmd/Ctrl+R)"
>
[n]
</button>
<div class="border-surface2 mx-1 border-l"></div>
<button
type="button"
@@ -2098,6 +2139,27 @@ export default function TextEditor(props: TextEditorProps) {
━━ HR
</button>
<div class="border-surface2 mx-1 border-l"></div>
{/* Undo/Redo buttons - critical for mobile */}
<button
type="button"
onClick={() => instance().chain().focus().undo().run()}
disabled={!instance().can().undo()}
class="hover:bg-surface1 touch-manipulation rounded px-2 py-1 text-xs select-none disabled:cursor-not-allowed disabled:opacity-60"
title="Undo (Cmd/Ctrl+Z)"
>
</button>
<button
type="button"
onClick={() => instance().chain().focus().redo().run()}
disabled={!instance().can().redo()}
class="hover:bg-surface1 touch-manipulation rounded px-2 py-1 text-xs select-none disabled:cursor-not-allowed disabled:opacity-60"
title="Redo (Cmd/Ctrl+Shift+Z)"
>
</button>
<div class="border-surface2 mx-1 border-l"></div>
<button
type="button"
onClick={toggleFullscreen}