@connextar/house 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +205 -28
- package/dist/account/index.d.ts +1 -1
- package/dist/account/index.d.ts.map +1 -1
- package/dist/account/index.js +1 -1
- package/dist/account/index.js.map +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/changelog/changelog.d.ts +60 -0
- package/dist/changelog/changelog.d.ts.map +1 -0
- package/dist/changelog/changelog.js +61 -0
- package/dist/changelog/changelog.js.map +1 -0
- package/dist/changelog/index.d.ts +2 -0
- package/dist/changelog/index.d.ts.map +1 -0
- package/dist/changelog/index.js +2 -0
- package/dist/changelog/index.js.map +1 -0
- package/dist/editor/block-handle.d.ts +15 -0
- package/dist/editor/block-handle.d.ts.map +1 -0
- package/dist/editor/block-handle.js +106 -0
- package/dist/editor/block-handle.js.map +1 -0
- package/dist/editor/blocks.d.ts +35 -0
- package/dist/editor/blocks.d.ts.map +1 -0
- package/dist/editor/blocks.js +114 -0
- package/dist/editor/blocks.js.map +1 -0
- package/dist/editor/bubble-toolbar.d.ts +11 -0
- package/dist/editor/bubble-toolbar.d.ts.map +1 -0
- package/dist/editor/bubble-toolbar.js +87 -0
- package/dist/editor/bubble-toolbar.js.map +1 -0
- package/dist/editor/content-index.d.ts +2 -0
- package/dist/editor/content-index.d.ts.map +1 -0
- package/dist/editor/content-index.js +2 -0
- package/dist/editor/content-index.js.map +1 -0
- package/dist/editor/content.d.ts +30 -0
- package/dist/editor/content.d.ts.map +1 -0
- package/dist/editor/content.js +256 -0
- package/dist/editor/content.js.map +1 -0
- package/dist/editor/editor.d.ts +52 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +160 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/emoji-index.d.ts +2 -0
- package/dist/editor/emoji-index.d.ts.map +1 -0
- package/dist/editor/emoji-index.js +2 -0
- package/dist/editor/emoji-index.js.map +1 -0
- package/dist/editor/emoji-picker.d.ts +16 -0
- package/dist/editor/emoji-picker.d.ts.map +1 -0
- package/dist/editor/emoji-picker.js +37 -0
- package/dist/editor/emoji-picker.js.map +1 -0
- package/dist/editor/emoji.d.ts +18 -0
- package/dist/editor/emoji.d.ts.map +1 -0
- package/dist/editor/emoji.js +418 -0
- package/dist/editor/emoji.js.map +1 -0
- package/dist/editor/index.d.ts +5 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +6 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/suggestion-popup.d.ts +17 -0
- package/dist/editor/suggestion-popup.d.ts.map +1 -0
- package/dist/editor/suggestion-popup.js +57 -0
- package/dist/editor/suggestion-popup.js.map +1 -0
- package/dist/editor/suggestions.d.ts +93 -0
- package/dist/editor/suggestions.d.ts.map +1 -0
- package/dist/editor/suggestions.js +179 -0
- package/dist/editor/suggestions.js.map +1 -0
- package/dist/editor/ui.d.ts +54 -0
- package/dist/editor/ui.d.ts.map +1 -0
- package/dist/editor/ui.js +58 -0
- package/dist/editor/ui.js.map +1 -0
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +2 -2
- package/dist/errors/index.js.map +1 -1
- package/dist/house.css +267 -0
- package/dist/internal/cx.d.ts +3 -0
- package/dist/internal/cx.d.ts.map +1 -0
- package/dist/internal/cx.js +5 -0
- package/dist/internal/cx.js.map +1 -0
- package/dist/internal/next-link.d.ts +23 -0
- package/dist/internal/next-link.d.ts.map +1 -0
- package/dist/internal/next-link.js +3 -0
- package/dist/internal/next-link.js.map +1 -0
- package/dist/markdown/guide.d.ts +98 -0
- package/dist/markdown/guide.d.ts.map +1 -0
- package/dist/markdown/guide.js +328 -0
- package/dist/markdown/guide.js.map +1 -0
- package/dist/markdown/index.d.ts +4 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +4 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/table-view.d.ts +28 -0
- package/dist/markdown/table-view.d.ts.map +1 -0
- package/dist/markdown/table-view.js +25 -0
- package/dist/markdown/table-view.js.map +1 -0
- package/dist/markdown/table.d.ts +35 -0
- package/dist/markdown/table.d.ts.map +1 -0
- package/dist/markdown/table.js +79 -0
- package/dist/markdown/table.js.map +1 -0
- package/dist/release/changelog.d.ts +72 -0
- package/dist/release/changelog.d.ts.map +1 -0
- package/dist/release/changelog.js +92 -0
- package/dist/release/changelog.js.map +1 -0
- package/dist/release/index.d.ts +3 -0
- package/dist/release/index.d.ts.map +1 -0
- package/dist/release/index.js +3 -0
- package/dist/release/index.js.map +1 -0
- package/dist/release/version.d.ts +33 -0
- package/dist/release/version.d.ts.map +1 -0
- package/dist/release/version.js +57 -0
- package/dist/release/version.js.map +1 -0
- package/dist/trail/index.d.ts +3 -0
- package/dist/trail/index.d.ts.map +1 -0
- package/dist/trail/index.js +3 -0
- package/dist/trail/index.js.map +1 -0
- package/dist/trail/rules.d.ts +44 -0
- package/dist/trail/rules.d.ts.map +1 -0
- package/dist/trail/rules.js +74 -0
- package/dist/trail/rules.js.map +1 -0
- package/dist/trail/trail.d.ts +49 -0
- package/dist/trail/trail.d.ts.map +1 -0
- package/dist/trail/trail.js +188 -0
- package/dist/trail/trail.js.map +1 -0
- package/docs/ReleaseProcess.md +315 -0
- package/package.json +76 -11
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ChainedCommands, Editor } from "@tiptap/core";
|
|
2
|
+
import type { Node as PMNode } from "@tiptap/pm/model";
|
|
3
|
+
import { type LucideIcon } from "lucide-react";
|
|
4
|
+
/**
|
|
5
|
+
* The block vocabulary of the editor — one list, read by three surfaces: the
|
|
6
|
+
* `/` menu, the bubble menu's "Turn into", and each block's grip menu.
|
|
7
|
+
*
|
|
8
|
+
* These are exactly the blocks Markdown can say, which is the whole reason there
|
|
9
|
+
* are no callouts, toggles or columns: the stored format is Markdown text, and a
|
|
10
|
+
* block the read-only renderer (and every printed or emailed copy) could not show
|
|
11
|
+
* would silently degrade on the surfaces people hand to someone else.
|
|
12
|
+
*/
|
|
13
|
+
export interface BlockType {
|
|
14
|
+
id: "paragraph" | "heading1" | "heading2" | "heading3" | "bulletList" | "orderedList" | "taskList" | "blockquote" | "codeBlock";
|
|
15
|
+
label: string;
|
|
16
|
+
description: string;
|
|
17
|
+
icon: LucideIcon;
|
|
18
|
+
/** Extra words the `/` menu matches on. */
|
|
19
|
+
keywords: string[];
|
|
20
|
+
/** Markdown shortcut shown as a hint, e.g. "# ". */
|
|
21
|
+
shortcut: string;
|
|
22
|
+
/**
|
|
23
|
+
* Convert whatever the selection is in. `clearNodes()` first lifts the
|
|
24
|
+
* selection out of lists and quotes, so "turn a quote into a heading" and
|
|
25
|
+
* "turn a list into paragraphs" both work in one step.
|
|
26
|
+
*/
|
|
27
|
+
apply: (chain: ChainedCommands) => ChainedCommands;
|
|
28
|
+
isActive: (editor: Editor) => boolean;
|
|
29
|
+
/** Whether a given block node (from the grip, not the caret) is this type. */
|
|
30
|
+
matchesNode: (node: PMNode) => boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare const BLOCK_TYPES: readonly BlockType[];
|
|
33
|
+
/** The block type the selection currently sits in, for "Turn into" state. */
|
|
34
|
+
export declare function activeBlockType(editor: Editor): BlockType;
|
|
35
|
+
//# sourceMappingURL=blocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../src/editor/blocks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAUL,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AAEtB;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EACE,WAAW,GACX,UAAU,GACV,UAAU,GACV,UAAU,GACV,YAAY,GACZ,aAAa,GACb,UAAU,GACV,YAAY,GACZ,WAAW,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,eAAe,CAAC;IACnD,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,8EAA8E;IAC9E,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACxC;AAsBD,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EA0F3C,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAEzD"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Code2, Heading1, Heading2, Heading3, List, ListOrdered, ListTodo, Pilcrow, Quote, } from "lucide-react";
|
|
2
|
+
const named = (name) => (node) => node.type.name === name;
|
|
3
|
+
const headingLevel = (level) => (node) => node.type.name === "heading" && node.attrs.level === level;
|
|
4
|
+
const PARAGRAPH = {
|
|
5
|
+
id: "paragraph",
|
|
6
|
+
label: "Text",
|
|
7
|
+
description: "Plain writing",
|
|
8
|
+
icon: Pilcrow,
|
|
9
|
+
keywords: ["paragraph", "plain", "body"],
|
|
10
|
+
shortcut: "",
|
|
11
|
+
apply: (chain) => chain.clearNodes().setParagraph(),
|
|
12
|
+
isActive: (editor) => editor.isActive("paragraph") &&
|
|
13
|
+
!editor.isActive("bulletList") &&
|
|
14
|
+
!editor.isActive("orderedList") &&
|
|
15
|
+
!editor.isActive("taskList") &&
|
|
16
|
+
!editor.isActive("blockquote"),
|
|
17
|
+
matchesNode: named("paragraph"),
|
|
18
|
+
};
|
|
19
|
+
export const BLOCK_TYPES = [
|
|
20
|
+
PARAGRAPH,
|
|
21
|
+
{
|
|
22
|
+
id: "heading1",
|
|
23
|
+
label: "Heading 1",
|
|
24
|
+
description: "Big section heading",
|
|
25
|
+
icon: Heading1,
|
|
26
|
+
keywords: ["h1", "title", "big"],
|
|
27
|
+
shortcut: "# ",
|
|
28
|
+
apply: (chain) => chain.clearNodes().setHeading({ level: 1 }),
|
|
29
|
+
isActive: (editor) => editor.isActive("heading", { level: 1 }),
|
|
30
|
+
matchesNode: headingLevel(1),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "heading2",
|
|
34
|
+
label: "Heading 2",
|
|
35
|
+
description: "Medium section heading",
|
|
36
|
+
icon: Heading2,
|
|
37
|
+
keywords: ["h2", "subtitle"],
|
|
38
|
+
shortcut: "## ",
|
|
39
|
+
apply: (chain) => chain.clearNodes().setHeading({ level: 2 }),
|
|
40
|
+
isActive: (editor) => editor.isActive("heading", { level: 2 }),
|
|
41
|
+
matchesNode: headingLevel(2),
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "heading3",
|
|
45
|
+
label: "Heading 3",
|
|
46
|
+
description: "Small section heading",
|
|
47
|
+
icon: Heading3,
|
|
48
|
+
keywords: ["h3", "subheading"],
|
|
49
|
+
shortcut: "### ",
|
|
50
|
+
apply: (chain) => chain.clearNodes().setHeading({ level: 3 }),
|
|
51
|
+
isActive: (editor) => editor.isActive("heading", { level: 3 }),
|
|
52
|
+
matchesNode: headingLevel(3),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "bulletList",
|
|
56
|
+
label: "Bulleted list",
|
|
57
|
+
description: "A simple list",
|
|
58
|
+
icon: List,
|
|
59
|
+
keywords: ["bullet", "unordered", "points"],
|
|
60
|
+
shortcut: "- ",
|
|
61
|
+
apply: (chain) => chain.clearNodes().toggleBulletList(),
|
|
62
|
+
isActive: (editor) => editor.isActive("bulletList"),
|
|
63
|
+
matchesNode: named("bulletList"),
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "orderedList",
|
|
67
|
+
label: "Numbered list",
|
|
68
|
+
description: "A list with numbers",
|
|
69
|
+
icon: ListOrdered,
|
|
70
|
+
keywords: ["numbered", "ordered", "steps"],
|
|
71
|
+
shortcut: "1. ",
|
|
72
|
+
apply: (chain) => chain.clearNodes().toggleOrderedList(),
|
|
73
|
+
isActive: (editor) => editor.isActive("orderedList"),
|
|
74
|
+
matchesNode: named("orderedList"),
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: "taskList",
|
|
78
|
+
label: "To-do list",
|
|
79
|
+
description: "Tick things off",
|
|
80
|
+
icon: ListTodo,
|
|
81
|
+
keywords: ["todo", "task", "checkbox", "tick", "checklist"],
|
|
82
|
+
shortcut: "[] ",
|
|
83
|
+
apply: (chain) => chain.clearNodes().toggleTaskList(),
|
|
84
|
+
isActive: (editor) => editor.isActive("taskList"),
|
|
85
|
+
matchesNode: named("taskList"),
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "blockquote",
|
|
89
|
+
label: "Quote",
|
|
90
|
+
description: "Set a passage apart",
|
|
91
|
+
icon: Quote,
|
|
92
|
+
keywords: ["quote", "blockquote", "citation"],
|
|
93
|
+
shortcut: "> ",
|
|
94
|
+
apply: (chain) => chain.clearNodes().setBlockquote(),
|
|
95
|
+
isActive: (editor) => editor.isActive("blockquote"),
|
|
96
|
+
matchesNode: named("blockquote"),
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "codeBlock",
|
|
100
|
+
label: "Code",
|
|
101
|
+
description: "Monospaced block",
|
|
102
|
+
icon: Code2,
|
|
103
|
+
keywords: ["code", "snippet", "monospace", "pre"],
|
|
104
|
+
shortcut: "``` ",
|
|
105
|
+
apply: (chain) => chain.clearNodes().setCodeBlock(),
|
|
106
|
+
isActive: (editor) => editor.isActive("codeBlock"),
|
|
107
|
+
matchesNode: named("codeBlock"),
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
/** The block type the selection currently sits in, for "Turn into" state. */
|
|
111
|
+
export function activeBlockType(editor) {
|
|
112
|
+
return BLOCK_TYPES.find((type) => type.id !== "paragraph" && type.isActive(editor)) ?? PARAGRAPH;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=blocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../src/editor/blocks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Editor } from "@tiptap/react";
|
|
2
|
+
/**
|
|
3
|
+
* The formatting controls, shown only over a text selection — the Notion model.
|
|
4
|
+
* There is no standing toolbar: an empty editor is just a page, and the controls
|
|
5
|
+
* appear when there is something to apply them to. Block changes live under
|
|
6
|
+
* "Turn into", the same list the `/` menu and the block grip use.
|
|
7
|
+
*/
|
|
8
|
+
export declare function BubbleToolbar({ editor }: {
|
|
9
|
+
editor: Editor;
|
|
10
|
+
}): import("react").JSX.Element | null;
|
|
11
|
+
//# sourceMappingURL=bubble-toolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bubble-toolbar.d.ts","sourceRoot":"","sources":["../../src/editor/bubble-toolbar.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAyC5D;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,sCAgE3D"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { TextSelection } from "@tiptap/pm/state";
|
|
4
|
+
import { useEditorState } from "@tiptap/react";
|
|
5
|
+
import { BubbleMenu } from "@tiptap/react/menus";
|
|
6
|
+
import { Bold, Check, ChevronDown, Code, Italic, Link as LinkIcon, Strikethrough } from "lucide-react";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { BLOCK_TYPES, activeBlockType } from "./blocks.js";
|
|
9
|
+
import { ghostButtonClass, IconButton, Menu, MenuContent, MenuItem, MenuLabel, MenuTrigger, PopoverContent, PopoverRoot, PopoverTrigger, primaryButtonClass, TextInput, VerticalSeparator, } from "./ui.js";
|
|
10
|
+
/**
|
|
11
|
+
* Everything the BubbleMenu wrapper is handed must be referentially stable. It
|
|
12
|
+
* re-registers its ProseMirror plugin whenever these props change identity, and
|
|
13
|
+
* re-registering reconfigures the editor's plugin set — which destroys and
|
|
14
|
+
* recreates *every* plugin view, including the suggestion popups, mid-session.
|
|
15
|
+
* An inline object here silently killed the `/` menu on its first re-render.
|
|
16
|
+
*/
|
|
17
|
+
const BUBBLE_OPTIONS = { placement: "top", offset: 8 };
|
|
18
|
+
/** Only over a real text selection: not an empty caret, not a node selection (a
|
|
19
|
+
* dragged block), and not inside a code block, where inline marks are noise. */
|
|
20
|
+
const shouldShowBubble = ({ editor: current, state: editorState }) => {
|
|
21
|
+
const { selection } = editorState;
|
|
22
|
+
if (!current.isEditable || selection.empty)
|
|
23
|
+
return false;
|
|
24
|
+
if (!(selection instanceof TextSelection))
|
|
25
|
+
return false;
|
|
26
|
+
if (current.isActive("codeBlock"))
|
|
27
|
+
return false;
|
|
28
|
+
return editorState.doc.textBetween(selection.from, selection.to).trim().length > 0;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The formatting controls, shown only over a text selection — the Notion model.
|
|
32
|
+
* There is no standing toolbar: an empty editor is just a page, and the controls
|
|
33
|
+
* appear when there is something to apply them to. Block changes live under
|
|
34
|
+
* "Turn into", the same list the `/` menu and the block grip use.
|
|
35
|
+
*/
|
|
36
|
+
export function BubbleToolbar({ editor }) {
|
|
37
|
+
const state = useEditorState({
|
|
38
|
+
editor,
|
|
39
|
+
selector: ({ editor: current }) => ({
|
|
40
|
+
bold: current.isActive("bold"),
|
|
41
|
+
italic: current.isActive("italic"),
|
|
42
|
+
strike: current.isActive("strike"),
|
|
43
|
+
code: current.isActive("code"),
|
|
44
|
+
link: current.isActive("link"),
|
|
45
|
+
linkHref: current.getAttributes("link").href ?? "",
|
|
46
|
+
block: activeBlockType(current),
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
if (!state)
|
|
50
|
+
return null;
|
|
51
|
+
const chain = () => editor.chain().focus();
|
|
52
|
+
const BlockIcon = state.block.icon;
|
|
53
|
+
return (_jsxs(BubbleMenu, { editor: editor, pluginKey: "houseFormattingBubble", updateDelay: 120, options: BUBBLE_OPTIONS, shouldShow: shouldShowBubble, className: "house-bubble-menu flex items-center gap-0.5 rounded-lg border border-border bg-popover p-1 text-popover-foreground shadow-md", children: [_jsxs(Menu, { children: [_jsx(MenuTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: `${ghostButtonClass} h-8 px-2 text-xs`, children: [_jsx(BlockIcon, { className: "size-4", "aria-hidden": true }), state.block.label, _jsx(ChevronDown, { className: "size-3.5 opacity-60", "aria-hidden": true })] }) }), _jsxs(MenuContent, { className: "w-52", children: [_jsx(MenuLabel, { children: "Turn into" }), BLOCK_TYPES.map((type) => (_jsxs(MenuItem, { onSelect: () => void type.apply(chain()).run(), children: [_jsx(type.icon, { className: "size-4", "aria-hidden": true }), _jsx("span", { className: "flex-1", children: type.label }), type.id === state.block.id ? _jsx(Check, { className: "size-4 text-primary", "aria-hidden": true }) : null] }, type.id)))] })] }), _jsx(VerticalSeparator, {}), _jsx(MarkToggle, { label: "Bold", pressed: state.bold, onToggle: () => chain().toggleBold().run(), children: _jsx(Bold, { className: "size-4" }) }), _jsx(MarkToggle, { label: "Italic", pressed: state.italic, onToggle: () => chain().toggleItalic().run(), children: _jsx(Italic, { className: "size-4" }) }), _jsx(MarkToggle, { label: "Strikethrough", pressed: state.strike, onToggle: () => chain().toggleStrike().run(), children: _jsx(Strikethrough, { className: "size-4" }) }), _jsx(MarkToggle, { label: "Inline code", pressed: state.code, onToggle: () => chain().toggleCode().run(), children: _jsx(Code, { className: "size-4" }) }), _jsx(LinkControl, { editor: editor, active: state.link, href: state.linkHref })] }));
|
|
54
|
+
}
|
|
55
|
+
function MarkToggle({ label, pressed, onToggle, children, }) {
|
|
56
|
+
return (_jsx(IconButton, { "aria-label": label, title: label, pressed: pressed, onClick: onToggle, children: children }));
|
|
57
|
+
}
|
|
58
|
+
/** Set, change or clear the link on the current selection. */
|
|
59
|
+
function LinkControl({ editor, active, href }) {
|
|
60
|
+
const [open, setOpen] = useState(false);
|
|
61
|
+
const [draft, setDraft] = useState("");
|
|
62
|
+
const apply = () => {
|
|
63
|
+
const url = draft.trim();
|
|
64
|
+
const valid = /^https?:\/\//i.test(url) || (url.startsWith("/") && !url.startsWith("//"));
|
|
65
|
+
if (url && valid) {
|
|
66
|
+
editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
|
|
67
|
+
}
|
|
68
|
+
else if (!url) {
|
|
69
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
70
|
+
}
|
|
71
|
+
setOpen(false);
|
|
72
|
+
};
|
|
73
|
+
return (_jsxs(PopoverRoot, { open: open, onOpenChange: (next) => {
|
|
74
|
+
setOpen(next);
|
|
75
|
+
if (next)
|
|
76
|
+
setDraft(href);
|
|
77
|
+
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(IconButton, { "aria-label": "Link", title: "Link", pressed: active, children: _jsx(LinkIcon, { className: "size-4" }) }) }), _jsxs(PopoverContent, { className: "w-80 space-y-2", children: [_jsx("p", { className: "text-sm font-medium", children: "Link" }), _jsx(TextInput, { value: draft, onChange: (event) => setDraft(event.target.value), placeholder: "https://\u2026", "aria-label": "Link address", onKeyDown: (event) => {
|
|
78
|
+
if (event.key === "Enter") {
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
apply();
|
|
81
|
+
}
|
|
82
|
+
} }), _jsxs("div", { className: "flex justify-end gap-2", children: [active ? (_jsx("button", { type: "button", className: `${ghostButtonClass} h-8 px-3`, onClick: () => {
|
|
83
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
84
|
+
setOpen(false);
|
|
85
|
+
}, children: "Remove" })) : null, _jsx("button", { type: "button", className: primaryButtonClass, onClick: apply, children: "Apply" })] })] })] }));
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=bubble-toolbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bubble-toolbar.js","sourceRoot":"","sources":["../../src/editor/bubble-toolbar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-index.d.ts","sourceRoot":"","sources":["../../src/editor/content-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-index.js","sourceRoot":"","sources":["../../src/editor/content-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only display for what `RichTextEditor` writes — the Markdown dialect the
|
|
3
|
+
* editor produces (headings, lists incl. task lists, quotes, code fences,
|
|
4
|
+
* bold/italic/strike/inline code, links, `@`-references, `#hashtags`), with a
|
|
5
|
+
* bare newline shown as a line break so legacy plain-text values in the same
|
|
6
|
+
* columns read exactly as they always did.
|
|
7
|
+
*
|
|
8
|
+
* Separate from a guide renderer deliberately: a help centre wants guide-scale
|
|
9
|
+
* headings and link rewriting; a note wants task lists, fences and line breaks.
|
|
10
|
+
* Folding both dialects and both type scales into one would serve neither well.
|
|
11
|
+
*
|
|
12
|
+
* This is a trust boundary: whatever is stored in a text column is drawn here,
|
|
13
|
+
* often in front of a *different* person. Everything comes out as React
|
|
14
|
+
* elements with checked hrefs — never as markup.
|
|
15
|
+
*
|
|
16
|
+
* Server-safe: no hooks, so views can render bodies without a client boundary.
|
|
17
|
+
* Styled by `.house-prose` in `@connextar/house/house.css`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function RichTextContent({ content, className }: {
|
|
20
|
+
content: string;
|
|
21
|
+
className?: string;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
|
+
/** Only hrefs safe to hand a browser; anything else renders as plain text. */
|
|
24
|
+
export declare function safeHref(href: string): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* A plain-text preview of a Markdown body — for list cards and search rows.
|
|
27
|
+
* Strips block and inline syntax rather than rendering it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function richTextPreview(content: string, max?: number): string;
|
|
30
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/editor/content.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE9F;AAiBD,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBpD;AAsPD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAM,GAAG,MAAM,CAclE"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Link } from "../internal/next-link.js";
|
|
3
|
+
import { cx } from "../internal/cx.js";
|
|
4
|
+
/**
|
|
5
|
+
* Read-only display for what `RichTextEditor` writes — the Markdown dialect the
|
|
6
|
+
* editor produces (headings, lists incl. task lists, quotes, code fences,
|
|
7
|
+
* bold/italic/strike/inline code, links, `@`-references, `#hashtags`), with a
|
|
8
|
+
* bare newline shown as a line break so legacy plain-text values in the same
|
|
9
|
+
* columns read exactly as they always did.
|
|
10
|
+
*
|
|
11
|
+
* Separate from a guide renderer deliberately: a help centre wants guide-scale
|
|
12
|
+
* headings and link rewriting; a note wants task lists, fences and line breaks.
|
|
13
|
+
* Folding both dialects and both type scales into one would serve neither well.
|
|
14
|
+
*
|
|
15
|
+
* This is a trust boundary: whatever is stored in a text column is drawn here,
|
|
16
|
+
* often in front of a *different* person. Everything comes out as React
|
|
17
|
+
* elements with checked hrefs — never as markup.
|
|
18
|
+
*
|
|
19
|
+
* Server-safe: no hooks, so views can render bodies without a client boundary.
|
|
20
|
+
* Styled by `.house-prose` in `@connextar/house/house.css`.
|
|
21
|
+
*/
|
|
22
|
+
export function RichTextContent({ content, className }) {
|
|
23
|
+
return _jsx("div", { className: cx("house-prose", className), children: renderBlocks(content) });
|
|
24
|
+
}
|
|
25
|
+
/* ── Inline ───────────────────────────────────────────────────────────── */
|
|
26
|
+
// Link labels exclude `[` and both halves are bounded: `[^\]]+` let every `[`
|
|
27
|
+
// of a long run swallow the rest and backtrack, so a 100 KB run of `[` stalled
|
|
28
|
+
// a server for seconds (AltEd security round 8, 8.1).
|
|
29
|
+
const INLINE = /(`([^`\n]+)`)|(\[([^[\]\n]{1,500})\]\(([^)\s]{1,2048})\))|(\*\*([^*]+)\*\*)|(~~([^~]+)~~)|(\*([^*\n]+)\*)|(\b_([^_\n]+)_\b)|((?:^|(?<=[\s(]))#([a-z0-9][a-z0-9_-]{0,47})\b)/gim;
|
|
30
|
+
const ESCAPED = /\\([\\`*_{}[\]()#+\-.!>~|])/g;
|
|
31
|
+
/** The editor's serialiser backslash-escapes Markdown punctuation in literal text (`\#`, `\*`). */
|
|
32
|
+
function unescapeMarkdown(text) {
|
|
33
|
+
return text.replace(ESCAPED, "$1");
|
|
34
|
+
}
|
|
35
|
+
/** Only hrefs safe to hand a browser; anything else renders as plain text. */
|
|
36
|
+
export function safeHref(href) {
|
|
37
|
+
if (href.startsWith("/")) {
|
|
38
|
+
// "Internal" must mean same-origin after every normalisation a browser
|
|
39
|
+
// applies — `//evil.com` is protocol-relative and `/\evil.com` becomes
|
|
40
|
+
// `https://evil.com/` because browsers treat `\` as `/` in special-scheme
|
|
41
|
+
// URLs. Resolving against a sentinel origin catches all of these at once.
|
|
42
|
+
try {
|
|
43
|
+
return new URL(href, "https://internal.invalid").origin === "https://internal.invalid" ? href : null;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
return ["http:", "https:", "mailto:"].includes(new URL(href).protocol) ? href : null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function renderInline(text, keyPrefix) {
|
|
57
|
+
const nodes = [];
|
|
58
|
+
let last = 0;
|
|
59
|
+
let n = 0;
|
|
60
|
+
INLINE.lastIndex = 0;
|
|
61
|
+
for (const match of text.matchAll(INLINE)) {
|
|
62
|
+
const index = match.index ?? 0;
|
|
63
|
+
if (index > last)
|
|
64
|
+
nodes.push(unescapeMarkdown(text.slice(last, index)));
|
|
65
|
+
const key = `${keyPrefix}-${n++}`;
|
|
66
|
+
if (match[1]) {
|
|
67
|
+
nodes.push(_jsx("code", { children: match[2] }, key));
|
|
68
|
+
}
|
|
69
|
+
else if (match[3]) {
|
|
70
|
+
const href = safeHref(match[5] ?? "");
|
|
71
|
+
const label = renderInline(match[4] ?? "", key);
|
|
72
|
+
if (!href) {
|
|
73
|
+
nodes.push(_jsx("span", { children: label }, key));
|
|
74
|
+
}
|
|
75
|
+
else if (href.startsWith("/")) {
|
|
76
|
+
// Internal — an `@`-reference from the editor, or a hand-written app
|
|
77
|
+
// link. Marked so the navigation trail carries the way back across the
|
|
78
|
+
// jump: the trail provider listens for clicks on the attribute, which
|
|
79
|
+
// is what lets this renderer stay hook-free.
|
|
80
|
+
nodes.push(_jsx(Link, { href: href, "data-trail-carry": "", children: label }, key));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
nodes.push(_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", children: label }, key));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if (match[6]) {
|
|
87
|
+
nodes.push(_jsx("strong", { children: renderInline(match[7] ?? "", key) }, key));
|
|
88
|
+
}
|
|
89
|
+
else if (match[8]) {
|
|
90
|
+
nodes.push(_jsx("s", { children: renderInline(match[9] ?? "", key) }, key));
|
|
91
|
+
}
|
|
92
|
+
else if (match[10]) {
|
|
93
|
+
nodes.push(_jsx("em", { children: renderInline(match[11] ?? "", key) }, key));
|
|
94
|
+
}
|
|
95
|
+
else if (match[12]) {
|
|
96
|
+
nodes.push(_jsx("em", { children: renderInline(match[13] ?? "", key) }, key));
|
|
97
|
+
}
|
|
98
|
+
else if (match[14]) {
|
|
99
|
+
nodes.push(_jsxs("span", { className: "house-hashtag", children: ["#", match[15]] }, key));
|
|
100
|
+
}
|
|
101
|
+
last = index + match[0].length;
|
|
102
|
+
}
|
|
103
|
+
if (last < text.length)
|
|
104
|
+
nodes.push(unescapeMarkdown(text.slice(last)));
|
|
105
|
+
return nodes;
|
|
106
|
+
}
|
|
107
|
+
/** Paragraph text where a bare newline is a visible break. */
|
|
108
|
+
function renderWithBreaks(lines, keyPrefix) {
|
|
109
|
+
return lines.flatMap((line, index) => {
|
|
110
|
+
const rendered = renderInline(line, `${keyPrefix}-l${index}`);
|
|
111
|
+
return index === 0 ? rendered : [_jsx("br", {}, `${keyPrefix}-b${index}`), ...rendered];
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const LIST_LINE = /^(\s*)(?:([-*+])|(\d+)[.)])\s+(?:\[([ xX])\]\s+)?(.*)$/;
|
|
115
|
+
function parseListLine(line) {
|
|
116
|
+
const match = line.match(LIST_LINE);
|
|
117
|
+
if (!match)
|
|
118
|
+
return null;
|
|
119
|
+
return {
|
|
120
|
+
indent: match[1]?.length ?? 0,
|
|
121
|
+
ordered: match[3] !== undefined,
|
|
122
|
+
task: match[4] === undefined ? null : match[4] !== " ",
|
|
123
|
+
text: match[5] ?? "",
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** Build a (possibly nested) list from consecutive list lines. */
|
|
127
|
+
function renderList(items, keyPrefix) {
|
|
128
|
+
const render = (from, to, key) => {
|
|
129
|
+
const first = items[from];
|
|
130
|
+
if (!first)
|
|
131
|
+
return null;
|
|
132
|
+
const rows = [];
|
|
133
|
+
let i = from;
|
|
134
|
+
let n = 0;
|
|
135
|
+
while (i < to) {
|
|
136
|
+
const item = items[i];
|
|
137
|
+
if (!item)
|
|
138
|
+
break;
|
|
139
|
+
// Deeper lines nest under the previous row.
|
|
140
|
+
let childEnd = i + 1;
|
|
141
|
+
while (childEnd < to && (items[childEnd]?.indent ?? 0) > first.indent)
|
|
142
|
+
childEnd++;
|
|
143
|
+
const children = childEnd > i + 1 ? render(i + 1, childEnd, `${key}-c${n}`) : null;
|
|
144
|
+
rows.push(item.task !== null ? (_jsxs("li", { className: cx(item.task && "house-task-done"), children: [_jsx("input", { type: "checkbox", checked: item.task, readOnly: true, disabled: true, "aria-label": item.text }), _jsxs("span", { children: [renderInline(item.text, `${key}-i${n}`), children] })] }, n)) : (_jsxs("li", { children: [renderInline(item.text, `${key}-i${n}`), children] }, n)));
|
|
145
|
+
i = childEnd;
|
|
146
|
+
n++;
|
|
147
|
+
}
|
|
148
|
+
if (first.task !== null) {
|
|
149
|
+
return (_jsx("ul", { className: "house-task-list", children: rows }, key));
|
|
150
|
+
}
|
|
151
|
+
return first.ordered ? _jsx("ol", { children: rows }, key) : _jsx("ul", { children: rows }, key);
|
|
152
|
+
};
|
|
153
|
+
return render(0, items.length, keyPrefix);
|
|
154
|
+
}
|
|
155
|
+
/* ── Blocks ───────────────────────────────────────────────────────────── */
|
|
156
|
+
const RULE = /^(-{3,}|\*{3,}|_{3,})$/;
|
|
157
|
+
const HEADING = /^(#{1,6})\s+(.*)$/;
|
|
158
|
+
function renderBlocks(content) {
|
|
159
|
+
const lines = content.replace(/\r\n/g, "\n").split("\n");
|
|
160
|
+
const at = (index) => lines[index] ?? "";
|
|
161
|
+
const blocks = [];
|
|
162
|
+
let i = 0;
|
|
163
|
+
let key = 0;
|
|
164
|
+
while (i < lines.length) {
|
|
165
|
+
const line = at(i);
|
|
166
|
+
const trimmed = line.trim();
|
|
167
|
+
if (trimmed === "") {
|
|
168
|
+
i++;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
// Code fence — verbatim until the closing fence (or the end).
|
|
172
|
+
if (trimmed.startsWith("```")) {
|
|
173
|
+
const body = [];
|
|
174
|
+
i++;
|
|
175
|
+
while (i < lines.length && !at(i).trim().startsWith("```")) {
|
|
176
|
+
body.push(at(i));
|
|
177
|
+
i++;
|
|
178
|
+
}
|
|
179
|
+
i++; // closing fence
|
|
180
|
+
blocks.push(_jsx("pre", { children: _jsx("code", { children: body.join("\n") }) }, key++));
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (RULE.test(trimmed)) {
|
|
184
|
+
blocks.push(_jsx("hr", {}, key++));
|
|
185
|
+
i++;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const heading = trimmed.match(HEADING);
|
|
189
|
+
if (heading) {
|
|
190
|
+
const level = Math.min(heading[1]?.length ?? 1, 3);
|
|
191
|
+
const nodes = renderInline(heading[2] ?? "", `h${key}`);
|
|
192
|
+
blocks.push(level === 1 ? (_jsx("h1", { children: nodes }, key++)) : level === 2 ? (_jsx("h2", { children: nodes }, key++)) : (_jsx("h3", { children: nodes }, key++)));
|
|
193
|
+
i++;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (trimmed.startsWith(">")) {
|
|
197
|
+
const quote = [];
|
|
198
|
+
while (i < lines.length && at(i).trim().startsWith(">")) {
|
|
199
|
+
quote.push(at(i).trim().replace(/^>\s?/, ""));
|
|
200
|
+
i++;
|
|
201
|
+
}
|
|
202
|
+
blocks.push(_jsx("blockquote", { children: renderWithBreaks(quote, `q${key}`) }, key++));
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (parseListLine(line)) {
|
|
206
|
+
const items = [];
|
|
207
|
+
while (i < lines.length) {
|
|
208
|
+
const item = parseListLine(at(i));
|
|
209
|
+
if (!item)
|
|
210
|
+
break;
|
|
211
|
+
items.push(item);
|
|
212
|
+
i++;
|
|
213
|
+
}
|
|
214
|
+
blocks.push(_jsx("div", { children: renderList(items, `list${key}`) }, key++));
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// Paragraph — consecutive plain lines, each newline a visible break.
|
|
218
|
+
const para = [];
|
|
219
|
+
while (i < lines.length) {
|
|
220
|
+
const next = at(i);
|
|
221
|
+
const t = next.trim();
|
|
222
|
+
if (t === "" ||
|
|
223
|
+
t.startsWith("```") ||
|
|
224
|
+
t.startsWith(">") ||
|
|
225
|
+
HEADING.test(t) ||
|
|
226
|
+
RULE.test(t) ||
|
|
227
|
+
LIST_LINE.test(next)) {
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
para.push(next);
|
|
231
|
+
i++;
|
|
232
|
+
}
|
|
233
|
+
blocks.push(_jsx("p", { children: renderWithBreaks(para, `p${key}`) }, key++));
|
|
234
|
+
}
|
|
235
|
+
return blocks;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* A plain-text preview of a Markdown body — for list cards and search rows.
|
|
239
|
+
* Strips block and inline syntax rather than rendering it.
|
|
240
|
+
*/
|
|
241
|
+
export function richTextPreview(content, max = 160) {
|
|
242
|
+
// A preview needs the start of the note, not all 100 KB of it.
|
|
243
|
+
const text = content
|
|
244
|
+
.slice(0, Math.max(2000, max * 12))
|
|
245
|
+
.replace(/```[\s\S]*?(```|$)/g, " ")
|
|
246
|
+
.replace(/^#{1,6}\s+/gm, "")
|
|
247
|
+
.replace(/^\s*(?:[-*+]|\d+[.)])\s+(?:\[[ xX]\]\s+)?/gm, "")
|
|
248
|
+
.replace(/^>\s?/gm, "")
|
|
249
|
+
.replace(/\[([^[\]\n]{1,500})\]\([^)\s]{1,2048}\)/g, "$1")
|
|
250
|
+
.replace(/(\*\*|~~|`|\*|_)/g, "")
|
|
251
|
+
.replace(ESCAPED, "$1")
|
|
252
|
+
.replace(/\s+/g, " ")
|
|
253
|
+
.trim();
|
|
254
|
+
return text.length > max ? `${text.slice(0, max - 1)}…` : text;
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/editor/content.tsx"],"names":[],"mappings":"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"}
|