dishui 0.0.77 → 0.0.79
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/dist/components/pro/RichTextEditor/RichTextEditor.js +62 -62
- package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.d.ts +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js +21 -15
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.d.ts +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js +28 -26
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js +10 -7
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/ResizableImage.d.ts +2 -0
- package/dist/components/pro/RichTextEditor/extensions/ResizableImage.js +94 -0
- package/dist/components/pro/RichTextEditor/extensions/ResizableImage.js.map +1 -0
- package/dist/components/pro/RichTextEditor/index.d.ts +1 -0
- package/dist/dishui.css +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useEffect as e, useRef as t, useState as n } from "react";
|
|
2
2
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
3
|
+
import { flushSync as a } from "react-dom";
|
|
3
4
|
//#region src/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.tsx
|
|
4
|
-
var
|
|
5
|
+
var o = [
|
|
5
6
|
{
|
|
6
7
|
key: "flowchart",
|
|
7
8
|
labelKey: "mdTplFlowchart",
|
|
@@ -62,21 +63,28 @@ var a = [
|
|
|
62
63
|
icon: "🎨",
|
|
63
64
|
content: "## Mixed Content Example\n\n### Architecture Overview\n\n```mermaid\ngraph LR\n Client[Client App] --> Gateway[API Gateway]\n Gateway --> Auth[Auth Service]\n Gateway --> Core[Core Service]\n Core --> DB[(PostgreSQL)]\n Core --> Cache[(Redis)]\n Auth --> DB\n```\n\n### Performance Formula\n\nThe response time $T$ is calculated as:\n\n$$\nT = T_{network} + T_{processing} + T_{db}\n$$\n\nwhere $T_{db} = O(\\log n)$ with proper indexing.\n\n### Implementation\n\n```python\nfrom fastapi import FastAPI, Depends\nfrom functools import lru_cache\n\napp = FastAPI()\n\n@lru_cache(maxsize=256)\ndef compute_heavy(n: int) -> float:\n \"\"\"Cached computation: O(log n) amortized.\"\"\"\n return sum(1.0 / i for i in range(1, n + 1))\n\n@app.get(\"/api/harmonic/{n}\")\nasync def harmonic(n: int):\n result = compute_heavy(n)\n return {\"n\": n, \"H_n\": round(result, 6)}\n```\n\n### Project Status\n\n```mermaid\npie title Sprint Progress\n \"Completed\" : 65\n \"In Progress\" : 20\n \"Blocked\" : 10\n \"Not Started\" : 5\n```\n"
|
|
64
65
|
}
|
|
65
|
-
],
|
|
66
|
-
let [
|
|
66
|
+
], s = ({ labels: s, onSelect: c }) => {
|
|
67
|
+
let [l, u] = n(!1), d = t(null), f = t(""), p = (e, t) => {
|
|
68
|
+
let n = e.detail === 0 || f.current !== "touch";
|
|
69
|
+
a(() => u(!1)), c(t, n);
|
|
70
|
+
};
|
|
67
71
|
return e(() => {
|
|
68
72
|
let e = (e) => {
|
|
69
|
-
|
|
73
|
+
d.current && !d.current.contains(e.target) && u(!1);
|
|
70
74
|
};
|
|
71
|
-
return document.addEventListener("
|
|
75
|
+
return document.addEventListener("pointerdown", e), () => document.removeEventListener("pointerdown", e);
|
|
72
76
|
}, []), /* @__PURE__ */ i("div", {
|
|
73
|
-
ref:
|
|
77
|
+
ref: d,
|
|
74
78
|
className: "rte-toolbar__template-menu",
|
|
79
|
+
onPointerDown: (e) => {
|
|
80
|
+
f.current = e.pointerType;
|
|
81
|
+
},
|
|
75
82
|
children: [/* @__PURE__ */ i("button", {
|
|
76
83
|
type: "button",
|
|
77
|
-
className: `rte-toolbar__btn ${
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
className: `rte-toolbar__btn ${l ? "rte-toolbar__btn--active" : ""}`,
|
|
85
|
+
"aria-expanded": l,
|
|
86
|
+
onClick: () => u(!l),
|
|
87
|
+
title: s.mdTemplates || "Markdown Templates",
|
|
80
88
|
style: {
|
|
81
89
|
width: "auto",
|
|
82
90
|
padding: "0 6px",
|
|
@@ -126,14 +134,14 @@ var a = [
|
|
|
126
134
|
strokeWidth: "2.5",
|
|
127
135
|
children: /* @__PURE__ */ r("polyline", { points: "6 9 12 15 18 9" })
|
|
128
136
|
})]
|
|
129
|
-
}),
|
|
137
|
+
}), l && /* @__PURE__ */ i("div", {
|
|
130
138
|
className: "rte-toolbar__template-dropdown",
|
|
131
139
|
children: [
|
|
132
140
|
/* @__PURE__ */ r("div", {
|
|
133
141
|
className: "rte-toolbar__template-group-label",
|
|
134
142
|
children: "Mermaid"
|
|
135
143
|
}),
|
|
136
|
-
|
|
144
|
+
o.filter((e) => [
|
|
137
145
|
"flowchart",
|
|
138
146
|
"sequence",
|
|
139
147
|
"pie",
|
|
@@ -142,53 +150,47 @@ var a = [
|
|
|
142
150
|
].includes(e.key)).map((e) => /* @__PURE__ */ i("button", {
|
|
143
151
|
type: "button",
|
|
144
152
|
className: "rte-toolbar__template-item",
|
|
145
|
-
onClick: () =>
|
|
146
|
-
s(e.content), l(!1);
|
|
147
|
-
},
|
|
153
|
+
onClick: (t) => p(t, e.content),
|
|
148
154
|
children: [/* @__PURE__ */ r("span", {
|
|
149
155
|
className: "rte-toolbar__template-icon",
|
|
150
156
|
children: e.icon
|
|
151
|
-
}), /* @__PURE__ */ r("span", { children:
|
|
157
|
+
}), /* @__PURE__ */ r("span", { children: s[e.labelKey] || e.labelKey })]
|
|
152
158
|
}, e.key)),
|
|
153
159
|
/* @__PURE__ */ r("div", {
|
|
154
160
|
className: "rte-toolbar__template-group-label",
|
|
155
161
|
children: "Code"
|
|
156
162
|
}),
|
|
157
|
-
|
|
163
|
+
o.filter((e) => [
|
|
158
164
|
"python",
|
|
159
165
|
"typescript",
|
|
160
166
|
"rust"
|
|
161
167
|
].includes(e.key)).map((e) => /* @__PURE__ */ i("button", {
|
|
162
168
|
type: "button",
|
|
163
169
|
className: "rte-toolbar__template-item",
|
|
164
|
-
onClick: () =>
|
|
165
|
-
s(e.content), l(!1);
|
|
166
|
-
},
|
|
170
|
+
onClick: (t) => p(t, e.content),
|
|
167
171
|
children: [/* @__PURE__ */ r("span", {
|
|
168
172
|
className: "rte-toolbar__template-icon",
|
|
169
173
|
children: e.icon
|
|
170
|
-
}), /* @__PURE__ */ r("span", { children:
|
|
174
|
+
}), /* @__PURE__ */ r("span", { children: s[e.labelKey] || e.labelKey })]
|
|
171
175
|
}, e.key)),
|
|
172
176
|
/* @__PURE__ */ r("div", {
|
|
173
177
|
className: "rte-toolbar__template-group-label",
|
|
174
178
|
children: "Math / Mixed"
|
|
175
179
|
}),
|
|
176
|
-
|
|
180
|
+
o.filter((e) => ["math", "mixed"].includes(e.key)).map((e) => /* @__PURE__ */ i("button", {
|
|
177
181
|
type: "button",
|
|
178
182
|
className: "rte-toolbar__template-item",
|
|
179
|
-
onClick: () =>
|
|
180
|
-
s(e.content), l(!1);
|
|
181
|
-
},
|
|
183
|
+
onClick: (t) => p(t, e.content),
|
|
182
184
|
children: [/* @__PURE__ */ r("span", {
|
|
183
185
|
className: "rte-toolbar__template-icon",
|
|
184
186
|
children: e.icon
|
|
185
|
-
}), /* @__PURE__ */ r("span", { children:
|
|
187
|
+
}), /* @__PURE__ */ r("span", { children: s[e.labelKey] || e.labelKey })]
|
|
186
188
|
}, e.key))
|
|
187
189
|
]
|
|
188
190
|
})]
|
|
189
191
|
});
|
|
190
192
|
};
|
|
191
193
|
//#endregion
|
|
192
|
-
export {
|
|
194
|
+
export { o as MD_TEMPLATES, s as MarkdownTemplateMenu };
|
|
193
195
|
|
|
194
196
|
//# sourceMappingURL=MarkdownTemplates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownTemplates.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport type { RichTextEditorLabels } from '../types';\n\nexport const MD_TEMPLATES: { key: string; labelKey: keyof RichTextEditorLabels; icon: string; content: string }[] = [\n {\n key: 'flowchart', labelKey: 'mdTplFlowchart', icon: '🔀',\n content: `## Flowchart\n\n\\`\\`\\`mermaid\ngraph TD\n A[Start] --> B{Is it valid?}\n B -->|Yes| C[Process Data]\n B -->|No| D[Show Error]\n C --> E[Save to DB]\n E --> F[Send Response]\n D --> G[Log Warning]\n G --> A\n F --> H[End]\n\\`\\`\\`\n`,\n },\n {\n key: 'sequence', labelKey: 'mdTplSequence', icon: '🔄',\n content: `## Sequence Diagram\n\n\\`\\`\\`mermaid\nsequenceDiagram\n participant Browser\n participant Server\n participant Database\n participant Cache\n\n Browser->>Server: POST /api/login\n Server->>Database: Query user\n Database-->>Server: User record\n Server->>Cache: Store session\n Cache-->>Server: OK\n Server-->>Browser: 200 JWT Token\n Browser->>Server: GET /api/data (Bearer token)\n Server->>Cache: Validate session\n Cache-->>Server: Valid\n Server->>Database: Fetch data\n Database-->>Server: Result set\n Server-->>Browser: 200 JSON data\n\\`\\`\\`\n`,\n },\n {\n key: 'pie', labelKey: 'mdTplPieChart', icon: '🥧',\n content: `## Pie Chart\n\n\\`\\`\\`mermaid\npie title Tech Stack Usage 2025\n \"TypeScript\" : 35\n \"Python\" : 25\n \"Rust\" : 15\n \"Go\" : 12\n \"Java\" : 8\n \"Others\" : 5\n\\`\\`\\`\n`,\n },\n {\n key: 'gantt', labelKey: 'mdTplGantt', icon: '📊',\n content: `## Gantt Chart\n\n\\`\\`\\`mermaid\ngantt\n title Project Development Timeline\n dateFormat YYYY-MM-DD\n section Design\n UI/UX Design :a1, 2025-01-01, 20d\n API Design :a2, after a1, 10d\n section Frontend\n Component Library :b1, after a2, 25d\n Page Integration :b2, after b1, 15d\n Testing & Bug Fix :b3, after b2, 10d\n section Backend\n Core API Development :c1, after a2, 30d\n Database Optimization :c2, after c1, 10d\n section Deployment\n Staging Deploy :d1, after b3, 5d\n Production Release :milestone, after d1, 0d\n\\`\\`\\`\n`,\n },\n {\n key: 'xychart', labelKey: 'mdTplBarChart', icon: '📈',\n content: `## Bar Chart (xychart)\n\n\\`\\`\\`mermaid\nxychart-beta\n title \"Monthly Revenue (in thousands)\"\n x-axis [Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]\n y-axis \"Revenue (USD)\" 0 --> 120\n bar [52, 48, 61, 55, 72, 68, 85, 90, 78, 95, 102, 110]\n line [52, 48, 61, 55, 72, 68, 85, 90, 78, 95, 102, 110]\n\\`\\`\\`\n`,\n },\n {\n key: 'python', labelKey: 'mdTplPython', icon: '🐍',\n content: `## Python Example\n\n\\`\\`\\`python\nimport asyncio\nfrom dataclasses import dataclass, field\nfrom typing import AsyncIterator\n\n\n@dataclass\nclass DataPipeline:\n \"\"\"Async data processing pipeline.\"\"\"\n name: str\n buffer_size: int = 100\n _queue: asyncio.Queue = field(init=False)\n\n def __post_init__(self):\n self._queue = asyncio.Queue(maxsize=self.buffer_size)\n\n async def produce(self, items: list[int]) -> None:\n for item in items:\n transformed = item ** 2 + 2 * item + 1\n await self._queue.put(transformed)\n await self._queue.put(None) # sentinel\n\n async def consume(self) -> AsyncIterator[int]:\n while True:\n item = await self._queue.get()\n if item is None:\n break\n yield item\n\n async def run(self, data: list[int]) -> list[int]:\n results: list[int] = []\n producer = asyncio.create_task(self.produce(data))\n async for value in self.consume():\n results.append(value)\n await producer\n return results\n\n\nasync def main():\n pipeline = DataPipeline(name=\"squares\", buffer_size=50)\n data = list(range(1, 21))\n results = await pipeline.run(data)\n print(f\"Processed {len(results)} items: {results[:5]}...\")\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n\\`\\`\\`\n`,\n },\n {\n key: 'typescript', labelKey: 'mdTplTypeScript', icon: '🟦',\n content: `## TypeScript Example\n\n\\`\\`\\`typescript\ninterface APIResponse<T> {\n data: T;\n status: number;\n message: string;\n timestamp: Date;\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\nclass TypedFetcher {\n private baseUrl: string;\n private headers: Record<string, string>;\n\n constructor(baseUrl: string, token?: string) {\n this.baseUrl = baseUrl;\n this.headers = {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: \\\\\\`Bearer \\\\\\${token}\\\\\\` } : {}),\n };\n }\n\n async request<T>(\n method: HttpMethod,\n path: string,\n body?: unknown,\n ): Promise<APIResponse<T>> {\n const response = await fetch(\\\\\\`\\\\\\${this.baseUrl}\\\\\\${path}\\\\\\`, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n throw new Error(\\\\\\`HTTP \\\\\\${response.status}: \\\\\\${response.statusText}\\\\\\`);\n }\n\n return response.json() as Promise<APIResponse<T>>;\n }\n\n get<T>(path: string) { return this.request<T>('GET', path); }\n post<T>(path: string, body: unknown) { return this.request<T>('POST', path, body); }\n put<T>(path: string, body: unknown) { return this.request<T>('PUT', path, body); }\n delete<T>(path: string) { return this.request<T>('DELETE', path); }\n}\n\n// Usage\ninterface User {\n id: number;\n name: string;\n email: string;\n}\n\nconst api = new TypedFetcher('https://api.example.com', 'my-token');\nconst users = await api.get<User[]>('/users');\nconsole.log(users.data);\n\\`\\`\\`\n`,\n },\n {\n key: 'rust', labelKey: 'mdTplRust', icon: '🦀',\n content: `## Rust Example\n\n\\`\\`\\`rust\nuse std::collections::HashMap;\nuse std::sync::Arc;\nuse tokio::sync::RwLock;\n\n#[derive(Debug, Clone)]\nstruct CacheEntry<V: Clone> {\n value: V,\n expires_at: std::time::Instant,\n}\n\n#[derive(Clone)]\nstruct AsyncCache<V: Clone + Send + Sync + 'static> {\n store: Arc<RwLock<HashMap<String, CacheEntry<V>>>>,\n ttl: std::time::Duration,\n}\n\nimpl<V: Clone + Send + Sync + 'static> AsyncCache<V> {\n fn new(ttl_secs: u64) -> Self {\n Self {\n store: Arc::new(RwLock::new(HashMap::new())),\n ttl: std::time::Duration::from_secs(ttl_secs),\n }\n }\n\n async fn get(&self, key: &str) -> Option<V> {\n let store = self.store.read().await;\n store.get(key).and_then(|entry| {\n if entry.expires_at > std::time::Instant::now() {\n Some(entry.value.clone())\n } else {\n None\n }\n })\n }\n\n async fn set(&self, key: String, value: V) {\n let mut store = self.store.write().await;\n store.insert(key, CacheEntry {\n value,\n expires_at: std::time::Instant::now() + self.ttl,\n });\n }\n\n async fn cleanup(&self) -> usize {\n let mut store = self.store.write().await;\n let now = std::time::Instant::now();\n let before = store.len();\n store.retain(|_, entry| entry.expires_at > now);\n before - store.len()\n }\n}\n\n#[tokio::main]\nasync fn main() {\n let cache = AsyncCache::<String>::new(60);\n cache.set(\"hello\".into(), \"world\".into()).await;\n\n if let Some(val) = cache.get(\"hello\").await {\n println!(\"Got: {val}\");\n }\n}\n\\`\\`\\`\n`,\n },\n {\n key: 'math', labelKey: 'mdTplMath', icon: '🔢',\n content: `## Math Formulas (TeX)\n\n### Euler's Identity\n\n$$\ne^{i\\\\pi} + 1 = 0\n$$\n\n### Quadratic Formula\n\n$$\nx = \\\\frac{-b \\\\pm \\\\sqrt{b^2 - 4ac}}{2a}\n$$\n\n### Gaussian Integral\n\n$$\n\\\\int_{-\\\\infty}^{\\\\infty} e^{-x^2} \\\\, dx = \\\\sqrt{\\\\pi}\n$$\n\n### Maxwell's Equations\n\n$$\n\\\\nabla \\\\cdot \\\\mathbf{E} = \\\\frac{\\\\rho}{\\\\epsilon_0}\n$$\n\n$$\n\\\\nabla \\\\cdot \\\\mathbf{B} = 0\n$$\n\n$$\n\\\\nabla \\\\times \\\\mathbf{E} = -\\\\frac{\\\\partial \\\\mathbf{B}}{\\\\partial t}\n$$\n\n$$\n\\\\nabla \\\\times \\\\mathbf{B} = \\\\mu_0 \\\\mathbf{J} + \\\\mu_0 \\\\epsilon_0 \\\\frac{\\\\partial \\\\mathbf{E}}{\\\\partial t}\n$$\n\n### Taylor Series Expansion\n\n$$\nf(x) = \\\\sum_{n=0}^{\\\\infty} \\\\frac{f^{(n)}(a)}{n!}(x-a)^n\n$$\n\n### Matrix Notation\n\n$$\n\\\\mathbf{A} = \\\\begin{pmatrix} a_{11} & a_{12} & \\\\cdots & a_{1n} \\\\\\\\ a_{21} & a_{22} & \\\\cdots & a_{2n} \\\\\\\\ \\\\vdots & \\\\vdots & \\\\ddots & \\\\vdots \\\\\\\\ a_{m1} & a_{m2} & \\\\cdots & a_{mn} \\\\end{pmatrix}\n$$\n\n### Inline math: The identity $e^{i\\\\theta} = \\\\cos\\\\theta + i\\\\sin\\\\theta$ is known as Euler's formula.\n`,\n },\n {\n key: 'mixed', labelKey: 'mdTplMixed', icon: '🎨',\n content: `## Mixed Content Example\n\n### Architecture Overview\n\n\\`\\`\\`mermaid\ngraph LR\n Client[Client App] --> Gateway[API Gateway]\n Gateway --> Auth[Auth Service]\n Gateway --> Core[Core Service]\n Core --> DB[(PostgreSQL)]\n Core --> Cache[(Redis)]\n Auth --> DB\n\\`\\`\\`\n\n### Performance Formula\n\nThe response time $T$ is calculated as:\n\n$$\nT = T_{network} + T_{processing} + T_{db}\n$$\n\nwhere $T_{db} = O(\\\\log n)$ with proper indexing.\n\n### Implementation\n\n\\`\\`\\`python\nfrom fastapi import FastAPI, Depends\nfrom functools import lru_cache\n\napp = FastAPI()\n\n@lru_cache(maxsize=256)\ndef compute_heavy(n: int) -> float:\n \"\"\"Cached computation: O(log n) amortized.\"\"\"\n return sum(1.0 / i for i in range(1, n + 1))\n\n@app.get(\"/api/harmonic/{n}\")\nasync def harmonic(n: int):\n result = compute_heavy(n)\n return {\"n\": n, \"H_n\": round(result, 6)}\n\\`\\`\\`\n\n### Project Status\n\n\\`\\`\\`mermaid\npie title Sprint Progress\n \"Completed\" : 65\n \"In Progress\" : 20\n \"Blocked\" : 10\n \"Not Started\" : 5\n\\`\\`\\`\n`,\n },\n];\n\ninterface MarkdownTemplateMenuProps {\n labels: RichTextEditorLabels;\n onSelect: (content: string) => void;\n}\n\nexport const MarkdownTemplateMenu: React.FC<MarkdownTemplateMenuProps> = ({ labels, onSelect }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__template-menu\">\n <button\n type=\"button\"\n className={`rte-toolbar__btn ${isOpen ? 'rte-toolbar__btn--active' : ''}`}\n onClick={() => setIsOpen(!isOpen)}\n title={labels.mdTemplates || 'Markdown Templates'}\n style={{ width: 'auto', padding: '0 6px', gap: '2px', display: 'inline-flex', alignItems: 'center' }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <rect x=\"13\" y=\"3\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <rect x=\"3\" y=\"13\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <path d=\"M17 14v6M14 17h6\" />\n </svg>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isOpen && (\n <div className=\"rte-toolbar__template-dropdown\">\n <div className=\"rte-toolbar__template-group-label\">Mermaid</div>\n {MD_TEMPLATES.filter(t => ['flowchart', 'sequence', 'pie', 'gantt', 'xychart'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={() => { onSelect(t.content); setIsOpen(false); }}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n <div className=\"rte-toolbar__template-group-label\">Code</div>\n {MD_TEMPLATES.filter(t => ['python', 'typescript', 'rust'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={() => { onSelect(t.content); setIsOpen(false); }}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n <div className=\"rte-toolbar__template-group-label\">Math / Mixed</div>\n {MD_TEMPLATES.filter(t => ['math', 'mixed'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={() => { onSelect(t.content); setIsOpen(false); }}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MarkdownTemplates.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { flushSync } from 'react-dom';\nimport type { RichTextEditorLabels } from '../types';\n\nexport const MD_TEMPLATES: { key: string; labelKey: keyof RichTextEditorLabels; icon: string; content: string }[] = [\n {\n key: 'flowchart', labelKey: 'mdTplFlowchart', icon: '🔀',\n content: `## Flowchart\n\n\\`\\`\\`mermaid\ngraph TD\n A[Start] --> B{Is it valid?}\n B -->|Yes| C[Process Data]\n B -->|No| D[Show Error]\n C --> E[Save to DB]\n E --> F[Send Response]\n D --> G[Log Warning]\n G --> A\n F --> H[End]\n\\`\\`\\`\n`,\n },\n {\n key: 'sequence', labelKey: 'mdTplSequence', icon: '🔄',\n content: `## Sequence Diagram\n\n\\`\\`\\`mermaid\nsequenceDiagram\n participant Browser\n participant Server\n participant Database\n participant Cache\n\n Browser->>Server: POST /api/login\n Server->>Database: Query user\n Database-->>Server: User record\n Server->>Cache: Store session\n Cache-->>Server: OK\n Server-->>Browser: 200 JWT Token\n Browser->>Server: GET /api/data (Bearer token)\n Server->>Cache: Validate session\n Cache-->>Server: Valid\n Server->>Database: Fetch data\n Database-->>Server: Result set\n Server-->>Browser: 200 JSON data\n\\`\\`\\`\n`,\n },\n {\n key: 'pie', labelKey: 'mdTplPieChart', icon: '🥧',\n content: `## Pie Chart\n\n\\`\\`\\`mermaid\npie title Tech Stack Usage 2025\n \"TypeScript\" : 35\n \"Python\" : 25\n \"Rust\" : 15\n \"Go\" : 12\n \"Java\" : 8\n \"Others\" : 5\n\\`\\`\\`\n`,\n },\n {\n key: 'gantt', labelKey: 'mdTplGantt', icon: '📊',\n content: `## Gantt Chart\n\n\\`\\`\\`mermaid\ngantt\n title Project Development Timeline\n dateFormat YYYY-MM-DD\n section Design\n UI/UX Design :a1, 2025-01-01, 20d\n API Design :a2, after a1, 10d\n section Frontend\n Component Library :b1, after a2, 25d\n Page Integration :b2, after b1, 15d\n Testing & Bug Fix :b3, after b2, 10d\n section Backend\n Core API Development :c1, after a2, 30d\n Database Optimization :c2, after c1, 10d\n section Deployment\n Staging Deploy :d1, after b3, 5d\n Production Release :milestone, after d1, 0d\n\\`\\`\\`\n`,\n },\n {\n key: 'xychart', labelKey: 'mdTplBarChart', icon: '📈',\n content: `## Bar Chart (xychart)\n\n\\`\\`\\`mermaid\nxychart-beta\n title \"Monthly Revenue (in thousands)\"\n x-axis [Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]\n y-axis \"Revenue (USD)\" 0 --> 120\n bar [52, 48, 61, 55, 72, 68, 85, 90, 78, 95, 102, 110]\n line [52, 48, 61, 55, 72, 68, 85, 90, 78, 95, 102, 110]\n\\`\\`\\`\n`,\n },\n {\n key: 'python', labelKey: 'mdTplPython', icon: '🐍',\n content: `## Python Example\n\n\\`\\`\\`python\nimport asyncio\nfrom dataclasses import dataclass, field\nfrom typing import AsyncIterator\n\n\n@dataclass\nclass DataPipeline:\n \"\"\"Async data processing pipeline.\"\"\"\n name: str\n buffer_size: int = 100\n _queue: asyncio.Queue = field(init=False)\n\n def __post_init__(self):\n self._queue = asyncio.Queue(maxsize=self.buffer_size)\n\n async def produce(self, items: list[int]) -> None:\n for item in items:\n transformed = item ** 2 + 2 * item + 1\n await self._queue.put(transformed)\n await self._queue.put(None) # sentinel\n\n async def consume(self) -> AsyncIterator[int]:\n while True:\n item = await self._queue.get()\n if item is None:\n break\n yield item\n\n async def run(self, data: list[int]) -> list[int]:\n results: list[int] = []\n producer = asyncio.create_task(self.produce(data))\n async for value in self.consume():\n results.append(value)\n await producer\n return results\n\n\nasync def main():\n pipeline = DataPipeline(name=\"squares\", buffer_size=50)\n data = list(range(1, 21))\n results = await pipeline.run(data)\n print(f\"Processed {len(results)} items: {results[:5]}...\")\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n\\`\\`\\`\n`,\n },\n {\n key: 'typescript', labelKey: 'mdTplTypeScript', icon: '🟦',\n content: `## TypeScript Example\n\n\\`\\`\\`typescript\ninterface APIResponse<T> {\n data: T;\n status: number;\n message: string;\n timestamp: Date;\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\nclass TypedFetcher {\n private baseUrl: string;\n private headers: Record<string, string>;\n\n constructor(baseUrl: string, token?: string) {\n this.baseUrl = baseUrl;\n this.headers = {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: \\\\\\`Bearer \\\\\\${token}\\\\\\` } : {}),\n };\n }\n\n async request<T>(\n method: HttpMethod,\n path: string,\n body?: unknown,\n ): Promise<APIResponse<T>> {\n const response = await fetch(\\\\\\`\\\\\\${this.baseUrl}\\\\\\${path}\\\\\\`, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n throw new Error(\\\\\\`HTTP \\\\\\${response.status}: \\\\\\${response.statusText}\\\\\\`);\n }\n\n return response.json() as Promise<APIResponse<T>>;\n }\n\n get<T>(path: string) { return this.request<T>('GET', path); }\n post<T>(path: string, body: unknown) { return this.request<T>('POST', path, body); }\n put<T>(path: string, body: unknown) { return this.request<T>('PUT', path, body); }\n delete<T>(path: string) { return this.request<T>('DELETE', path); }\n}\n\n// Usage\ninterface User {\n id: number;\n name: string;\n email: string;\n}\n\nconst api = new TypedFetcher('https://api.example.com', 'my-token');\nconst users = await api.get<User[]>('/users');\nconsole.log(users.data);\n\\`\\`\\`\n`,\n },\n {\n key: 'rust', labelKey: 'mdTplRust', icon: '🦀',\n content: `## Rust Example\n\n\\`\\`\\`rust\nuse std::collections::HashMap;\nuse std::sync::Arc;\nuse tokio::sync::RwLock;\n\n#[derive(Debug, Clone)]\nstruct CacheEntry<V: Clone> {\n value: V,\n expires_at: std::time::Instant,\n}\n\n#[derive(Clone)]\nstruct AsyncCache<V: Clone + Send + Sync + 'static> {\n store: Arc<RwLock<HashMap<String, CacheEntry<V>>>>,\n ttl: std::time::Duration,\n}\n\nimpl<V: Clone + Send + Sync + 'static> AsyncCache<V> {\n fn new(ttl_secs: u64) -> Self {\n Self {\n store: Arc::new(RwLock::new(HashMap::new())),\n ttl: std::time::Duration::from_secs(ttl_secs),\n }\n }\n\n async fn get(&self, key: &str) -> Option<V> {\n let store = self.store.read().await;\n store.get(key).and_then(|entry| {\n if entry.expires_at > std::time::Instant::now() {\n Some(entry.value.clone())\n } else {\n None\n }\n })\n }\n\n async fn set(&self, key: String, value: V) {\n let mut store = self.store.write().await;\n store.insert(key, CacheEntry {\n value,\n expires_at: std::time::Instant::now() + self.ttl,\n });\n }\n\n async fn cleanup(&self) -> usize {\n let mut store = self.store.write().await;\n let now = std::time::Instant::now();\n let before = store.len();\n store.retain(|_, entry| entry.expires_at > now);\n before - store.len()\n }\n}\n\n#[tokio::main]\nasync fn main() {\n let cache = AsyncCache::<String>::new(60);\n cache.set(\"hello\".into(), \"world\".into()).await;\n\n if let Some(val) = cache.get(\"hello\").await {\n println!(\"Got: {val}\");\n }\n}\n\\`\\`\\`\n`,\n },\n {\n key: 'math', labelKey: 'mdTplMath', icon: '🔢',\n content: `## Math Formulas (TeX)\n\n### Euler's Identity\n\n$$\ne^{i\\\\pi} + 1 = 0\n$$\n\n### Quadratic Formula\n\n$$\nx = \\\\frac{-b \\\\pm \\\\sqrt{b^2 - 4ac}}{2a}\n$$\n\n### Gaussian Integral\n\n$$\n\\\\int_{-\\\\infty}^{\\\\infty} e^{-x^2} \\\\, dx = \\\\sqrt{\\\\pi}\n$$\n\n### Maxwell's Equations\n\n$$\n\\\\nabla \\\\cdot \\\\mathbf{E} = \\\\frac{\\\\rho}{\\\\epsilon_0}\n$$\n\n$$\n\\\\nabla \\\\cdot \\\\mathbf{B} = 0\n$$\n\n$$\n\\\\nabla \\\\times \\\\mathbf{E} = -\\\\frac{\\\\partial \\\\mathbf{B}}{\\\\partial t}\n$$\n\n$$\n\\\\nabla \\\\times \\\\mathbf{B} = \\\\mu_0 \\\\mathbf{J} + \\\\mu_0 \\\\epsilon_0 \\\\frac{\\\\partial \\\\mathbf{E}}{\\\\partial t}\n$$\n\n### Taylor Series Expansion\n\n$$\nf(x) = \\\\sum_{n=0}^{\\\\infty} \\\\frac{f^{(n)}(a)}{n!}(x-a)^n\n$$\n\n### Matrix Notation\n\n$$\n\\\\mathbf{A} = \\\\begin{pmatrix} a_{11} & a_{12} & \\\\cdots & a_{1n} \\\\\\\\ a_{21} & a_{22} & \\\\cdots & a_{2n} \\\\\\\\ \\\\vdots & \\\\vdots & \\\\ddots & \\\\vdots \\\\\\\\ a_{m1} & a_{m2} & \\\\cdots & a_{mn} \\\\end{pmatrix}\n$$\n\n### Inline math: The identity $e^{i\\\\theta} = \\\\cos\\\\theta + i\\\\sin\\\\theta$ is known as Euler's formula.\n`,\n },\n {\n key: 'mixed', labelKey: 'mdTplMixed', icon: '🎨',\n content: `## Mixed Content Example\n\n### Architecture Overview\n\n\\`\\`\\`mermaid\ngraph LR\n Client[Client App] --> Gateway[API Gateway]\n Gateway --> Auth[Auth Service]\n Gateway --> Core[Core Service]\n Core --> DB[(PostgreSQL)]\n Core --> Cache[(Redis)]\n Auth --> DB\n\\`\\`\\`\n\n### Performance Formula\n\nThe response time $T$ is calculated as:\n\n$$\nT = T_{network} + T_{processing} + T_{db}\n$$\n\nwhere $T_{db} = O(\\\\log n)$ with proper indexing.\n\n### Implementation\n\n\\`\\`\\`python\nfrom fastapi import FastAPI, Depends\nfrom functools import lru_cache\n\napp = FastAPI()\n\n@lru_cache(maxsize=256)\ndef compute_heavy(n: int) -> float:\n \"\"\"Cached computation: O(log n) amortized.\"\"\"\n return sum(1.0 / i for i in range(1, n + 1))\n\n@app.get(\"/api/harmonic/{n}\")\nasync def harmonic(n: int):\n result = compute_heavy(n)\n return {\"n\": n, \"H_n\": round(result, 6)}\n\\`\\`\\`\n\n### Project Status\n\n\\`\\`\\`mermaid\npie title Sprint Progress\n \"Completed\" : 65\n \"In Progress\" : 20\n \"Blocked\" : 10\n \"Not Started\" : 5\n\\`\\`\\`\n`,\n },\n];\n\ninterface MarkdownTemplateMenuProps {\n labels: RichTextEditorLabels;\n onSelect: (content: string, focusEditor?: boolean) => void;\n}\n\nexport const MarkdownTemplateMenu: React.FC<MarkdownTemplateMenuProps> = ({ labels, onSelect }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const pointerType = useRef('');\n const select = (event: React.MouseEvent, content: string) => {\n // Touch insertion must not enter Android's native editing/IME focus path.\n const focusEditor = event.detail === 0 || pointerType.current !== 'touch';\n flushSync(() => setIsOpen(false));\n onSelect(content, focusEditor);\n };\n\n useEffect(() => {\n const handler = (e: PointerEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('pointerdown', handler);\n return () => document.removeEventListener('pointerdown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__template-menu\" onPointerDown={(event) => { pointerType.current = event.pointerType; }}>\n <button\n type=\"button\"\n className={`rte-toolbar__btn ${isOpen ? 'rte-toolbar__btn--active' : ''}`}\n aria-expanded={isOpen}\n onClick={() => setIsOpen(!isOpen)}\n title={labels.mdTemplates || 'Markdown Templates'}\n style={{ width: 'auto', padding: '0 6px', gap: '2px', display: 'inline-flex', alignItems: 'center' }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <rect x=\"13\" y=\"3\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <rect x=\"3\" y=\"13\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <path d=\"M17 14v6M14 17h6\" />\n </svg>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isOpen && (\n <div className=\"rte-toolbar__template-dropdown\">\n <div className=\"rte-toolbar__template-group-label\">Mermaid</div>\n {MD_TEMPLATES.filter(t => ['flowchart', 'sequence', 'pie', 'gantt', 'xychart'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n <div className=\"rte-toolbar__template-group-label\">Code</div>\n {MD_TEMPLATES.filter(t => ['python', 'typescript', 'rust'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n <div className=\"rte-toolbar__template-group-label\">Math / Mixed</div>\n {MD_TEMPLATES.filter(t => ['math', 'mixed'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -72,8 +72,10 @@ var y = /* @__PURE__ */ new Set([
|
|
|
72
72
|
text: "# Markdown\n\nWrite your **markdown** here."
|
|
73
73
|
}]
|
|
74
74
|
}).run();
|
|
75
|
-
}, [b]), I = d((e) => {
|
|
76
|
-
b.
|
|
75
|
+
}, [b]), I = d((e, t = !0) => {
|
|
76
|
+
if (b.isDestroyed || !b.isEditable) return;
|
|
77
|
+
let n = b.chain();
|
|
78
|
+
t && n.focus(), n.insertContent({
|
|
77
79
|
type: "codeBlock",
|
|
78
80
|
attrs: { language: "r-markdown" },
|
|
79
81
|
content: [{
|
|
@@ -81,18 +83,19 @@ var y = /* @__PURE__ */ new Set([
|
|
|
81
83
|
text: e
|
|
82
84
|
}]
|
|
83
85
|
}).run();
|
|
84
|
-
}, [b]), L = d((e = "block") => {
|
|
85
|
-
|
|
86
|
+
}, [b]), L = d((e = "block", n = !0) => {
|
|
87
|
+
if (b.isDestroyed || !b.isEditable) return;
|
|
88
|
+
let r = e === "float" ? {
|
|
86
89
|
x: 40,
|
|
87
90
|
y: 40,
|
|
88
91
|
zIndex: t(b)
|
|
89
|
-
} : e === "block" ? {} : { width: 240 };
|
|
90
|
-
|
|
92
|
+
} : e === "block" ? {} : { width: 240 }, i = b.chain();
|
|
93
|
+
n && i.focus(), i.insertContent({
|
|
91
94
|
type: "floatingDialog",
|
|
92
95
|
attrs: {
|
|
93
96
|
title: "Note",
|
|
94
97
|
layout: e,
|
|
95
|
-
...
|
|
98
|
+
...r
|
|
96
99
|
},
|
|
97
100
|
content: [{ type: "paragraph" }]
|
|
98
101
|
}).run();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/Toolbar.tsx"],"sourcesContent":["import React, { useCallback, useState, useEffect, useRef } from 'react';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport type { Mark } from '@tiptap/pm/model';\nimport type { ToolbarSection, RichTextEditorLabels } from '../types';\nimport { defaultLabels } from '../types';\nimport { getNextFloatZIndex } from '../extensions/FloatingDialog';\nimport { ToolbarButton, ToolbarDivider } from './ToolbarButton';\nimport { ColorPicker } from './ColorPicker';\nimport { SelectDropdown, FONT_FAMILIES, FONT_SIZES } from './SelectDropdown';\nimport { MarkdownTemplateMenu } from './MarkdownTemplates';\nimport { FloatingDialogMenu } from './FloatingDialogMenu';\nimport { TableOpsMenu } from './TableOpsMenu';\n\n// Only visual formatting belongs to the painter, never links or comment IDs.\nconst PAINT_MARKS = new Set(['bold', 'italic', 'underline', 'strike', 'code', 'subscript', 'superscript', 'textStyle', 'highlight']);\n\ninterface ToolbarProps {\n editor: Editor;\n config?: ToolbarSection;\n labels?: RichTextEditorLabels;\n hasAI?: boolean;\n onAIClick?: () => void;\n onFormatPainterChange?: (active: boolean) => void;\n children?: React.ReactNode;\n}\n\nconst Toolbar: React.FC<ToolbarProps> = ({\n editor,\n config,\n labels: propsLabels,\n hasAI,\n onAIClick,\n onFormatPainterChange,\n children,\n}) => {\n const labels = { ...defaultLabels, ...propsLabels };\n useEditorState({ editor, selector: ({ transactionNumber }) => transactionNumber });\n const [formatPainterMarks, setFormatPainterMarks] = useState<readonly Mark[] | null>(null);\n const painterChange = useRef(onFormatPainterChange);\n useEffect(() => {\n painterChange.current = onFormatPainterChange;\n }, [onFormatPainterChange]);\n\n const cfg: Required<ToolbarSection> = {\n textFormat: config?.textFormat ?? true,\n heading: config?.heading ?? true,\n alignment: config?.alignment ?? true,\n list: config?.list ?? true,\n insert: config?.insert ?? true,\n color: config?.color ?? true,\n history: config?.history ?? true,\n ai: config?.ai ?? true,\n tableOps: config?.tableOps ?? true,\n fontStyle: config?.fontStyle ?? true,\n formatPainter: config?.formatPainter ?? true,\n };\n\n const setLink = useCallback(() => {\n const previousUrl = editor.getAttributes('link').href;\n const url = window.prompt(labels.insertLinkUrl, previousUrl);\n if (url === null) return;\n if (editor.isDestroyed || !editor.isEditable) return;\n if (url.trim() === '') {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n return;\n }\n editor.chain().focus().extendMarkRange('link').setLink({ href: url.trim() }).run();\n }, [editor, labels.insertLinkUrl]);\n\n const addImage = useCallback(() => {\n const url = window.prompt(labels.insertImageUrl);\n if (url) {\n editor.chain().focus().setImage({ src: url }).run();\n }\n }, [editor, labels.insertImageUrl]);\n\n const insertTable = useCallback(() => {\n editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();\n }, [editor]);\n\n const insertMarkdownBlock = useCallback(() => {\n editor.chain().focus().insertContent({\n type: 'codeBlock',\n attrs: { language: 'r-markdown' },\n content: [{ type: 'text', text: '# Markdown\\n\\nWrite your **markdown** here.' }],\n }).run();\n }, [editor]);\n\n const insertMarkdownTemplate = useCallback((content: string) => {\n editor.chain().focus().insertContent({\n type: 'codeBlock',\n attrs: { language: 'r-markdown' },\n content: [{ type: 'text', text: content }],\n }).run();\n }, [editor]);\n\n const insertFloatingDialog = useCallback((layout: 'block' | 'wrap-left' | 'wrap-right' | 'float' = 'block') => {\n const extraAttrs = layout === 'float'\n ? { x: 40, y: 40, zIndex: getNextFloatZIndex(editor) }\n : layout === 'block'\n ? {}\n : { width: 240 };\n editor.chain().focus().insertContent({\n type: 'floatingDialog',\n attrs: { title: 'Note', layout, ...extraAttrs },\n content: [{ type: 'paragraph' }],\n }).run();\n }, [editor]);\n\n const handleFormatPainter = useCallback(() => {\n if (formatPainterMarks) {\n setFormatPainterMarks(null);\n return;\n }\n if (editor.isDestroyed || !editor.isEditable) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n\n let marks: readonly Mark[] | undefined;\n editor.state.doc.nodesBetween(from, to, (node) => {\n if (!node.isText) return;\n const formatting = node.marks.filter((mark) => PAINT_MARKS.has(mark.type.name));\n marks = marks === undefined ? formatting : marks.filter((mark) => formatting.some((other) => mark.eq(other)));\n });\n if (marks === undefined) return;\n setFormatPainterMarks(marks);\n }, [editor, formatPainterMarks]);\n\n useEffect(() => {\n if (!formatPainterMarks) return;\n if (editor.isDestroyed || !editor.isEditable || !cfg.formatPainter || !cfg.textFormat) {\n setFormatPainterMarks(null);\n return;\n }\n\n painterChange.current?.(true);\n const editorEl = editor.view.dom;\n let frame: number | null = null;\n let cancelled = false;\n const cancel = () => {\n cancelled = true;\n if (frame !== null) cancelAnimationFrame(frame);\n frame = null;\n setFormatPainterMarks(null);\n };\n const onTransaction = () => {\n if (!editor.isEditable) cancel();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') cancel();\n };\n\n const applyMarks = () => {\n frame = null;\n if (cancelled || editor.isDestroyed || !editor.isEditable) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n\n const { tr } = editor.state;\n for (const name of PAINT_MARKS) {\n const type = editor.schema.marks[name];\n if (type) tr.removeMark(from, to, type);\n }\n editor.state.doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isText) return;\n const semantic = node.marks.filter((mark) => !PAINT_MARKS.has(mark.type.name));\n for (const mark of formatPainterMarks) {\n // Code and custom exclusions must not implicitly remove semantic marks.\n if (semantic.some((other) => mark.type.excludes(other.type) || other.type.excludes(mark.type))) continue;\n tr.addMark(Math.max(from, pos), Math.min(to, pos + node.nodeSize), mark);\n }\n });\n cancelled = true;\n editor.view.dispatch(tr);\n setFormatPainterMarks(null);\n };\n\n const onMouseUp = () => {\n if (cancelled) return;\n if (frame !== null) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(applyMarks);\n };\n\n editorEl.addEventListener('mouseup', onMouseUp);\n editorEl.ownerDocument.addEventListener('keydown', onKeyDown);\n editor.on('transaction', onTransaction);\n editor.on('destroy', cancel);\n return () => {\n cancelled = true;\n if (frame !== null) cancelAnimationFrame(frame);\n editorEl.removeEventListener('mouseup', onMouseUp);\n editorEl.ownerDocument.removeEventListener('keydown', onKeyDown);\n editor.off('transaction', onTransaction);\n editor.off('destroy', cancel);\n painterChange.current?.(false);\n };\n }, [editor, formatPainterMarks, cfg.formatPainter, cfg.textFormat]);\n\n const currentFontFamily = editor.getAttributes('textStyle').fontFamily || '';\n const currentFontSize = editor.getAttributes('textStyle').fontSize || '';\n\n return (\n <div className=\"rte-toolbar\" role=\"group\" aria-label=\"Text formatting\">\n {cfg.history && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().undo().run()}\n disabled={!editor.can().undo()}\n title={labels.undo}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"1 4 1 10 7 10\" />\n <path d=\"M3.51 15a9 9 0 102.13-9.36L1 10\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().redo().run()}\n disabled={!editor.can().redo()}\n title={labels.redo}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"23 4 23 10 17 10\" />\n <path d=\"M20.49 15a9 9 0 11-2.13-9.36L23 10\" />\n </svg>\n </ToolbarButton>\n <ToolbarDivider />\n </>\n )}\n\n {cfg.fontStyle && (\n <>\n <SelectDropdown\n value={currentFontFamily}\n options={FONT_FAMILIES}\n onChange={(val) => {\n if (val) {\n editor.chain().focus().setFontFamily(val).run();\n } else {\n editor.chain().focus().unsetFontFamily().run();\n }\n }}\n title={labels.fontFamily}\n width={120}\n />\n <SelectDropdown\n value={currentFontSize}\n options={FONT_SIZES}\n onChange={(val) => {\n if (val) {\n (editor.chain().focus() as any).setFontSize(val).run();\n } else {\n (editor.chain().focus() as any).unsetFontSize().run();\n }\n }}\n title={labels.fontSize}\n width={80}\n />\n <ToolbarDivider />\n </>\n )}\n\n {cfg.textFormat && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n isActive={editor.isActive('bold')}\n title={labels.bold}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M6 4h8a4 4 0 014 4 4 4 0 01-4 4H6z\" />\n <path d=\"M6 12h9a4 4 0 014 4 4 4 0 01-4 4H6z\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n isActive={editor.isActive('italic')}\n title={labels.italic}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\" />\n <line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\" />\n <line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n isActive={editor.isActive('underline')}\n title={labels.underline}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M6 3v7a6 6 0 006 6 6 6 0 006-6V3\" />\n <line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleStrike().run()}\n isActive={editor.isActive('strike')}\n title={labels.strikethrough}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M17.3 4.9c-2.3-.6-4.4-1-6.2-.9-2.7 0-5.3.7-5.3 3.6 0 1.5 1.8 3.3 7.2 3.3\" />\n <path d=\"M13 15.1c0 2.8-2.6 3.6-5.3 3.6-1.8-.1-3.9-.5-6.2-.9\" />\n <line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleSubscript().run()}\n isActive={editor.isActive('subscript')}\n title={labels.subscript}\n >\n <span style={{ fontSize: '13px', fontWeight: 600 }}>X<sub style={{ fontSize: '9px' }}>2</sub></span>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleSuperscript().run()}\n isActive={editor.isActive('superscript')}\n title={labels.superscript}\n >\n <span style={{ fontSize: '13px', fontWeight: 600 }}>X<sup style={{ fontSize: '9px' }}>2</sup></span>\n </ToolbarButton>\n {cfg.formatPainter && (\n <ToolbarButton\n onClick={handleFormatPainter}\n disabled={!editor.isEditable || (!formatPainterMarks && editor.state.selection.empty)}\n isActive={!!formatPainterMarks}\n title={formatPainterMarks ? labels.formatPainterActive : labels.formatPainter}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M19 3H5a2 2 0 00-2 2v2a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2z\" />\n <path d=\"M10 7v4a2 2 0 01-2 2H7\" />\n <path d=\"M7 13l-3 8\" />\n <path d=\"M4 21h6\" />\n </svg>\n </ToolbarButton>\n )}\n <ToolbarDivider />\n </>\n )}\n\n {cfg.heading && (\n <>\n {([1, 2, 3, 4, 5, 6] as const).map((level) => (\n <ToolbarButton\n key={level}\n onClick={() => editor.chain().focus().toggleHeading({ level }).run()}\n isActive={editor.isActive('heading', { level })}\n title={`${labels.heading} ${level}`}\n >\n <span style={{ fontSize: '12px', fontWeight: 700 }}>H{level}</span>\n </ToolbarButton>\n ))}\n <ToolbarDivider />\n </>\n )}\n\n {cfg.alignment && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().setTextAlign('left').run()}\n isActive={editor.isActive({ textAlign: 'left' })}\n title={labels.alignLeft}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"17\" y1=\"10\" x2=\"3\" y2=\"10\" /><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\" />\n <line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\" /><line x1=\"17\" y1=\"18\" x2=\"3\" y2=\"18\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().setTextAlign('center').run()}\n isActive={editor.isActive({ textAlign: 'center' })}\n title={labels.alignCenter}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"10\" x2=\"6\" y2=\"10\" /><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\" />\n <line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\" /><line x1=\"18\" y1=\"18\" x2=\"6\" y2=\"18\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().setTextAlign('right').run()}\n isActive={editor.isActive({ textAlign: 'right' })}\n title={labels.alignRight}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"21\" y1=\"10\" x2=\"7\" y2=\"10\" /><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\" />\n <line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\" /><line x1=\"21\" y1=\"18\" x2=\"7\" y2=\"18\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().setTextAlign('justify').run()}\n isActive={editor.isActive({ textAlign: 'justify' })}\n title={labels.alignJustify}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"21\" y1=\"10\" x2=\"3\" y2=\"10\" /><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\" />\n <line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\" /><line x1=\"21\" y1=\"18\" x2=\"3\" y2=\"18\" />\n </svg>\n </ToolbarButton>\n <ToolbarDivider />\n </>\n )}\n\n {cfg.list && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n isActive={editor.isActive('bulletList')}\n title={labels.bulletList}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\" /><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <circle cx=\"4\" cy=\"6\" r=\"1\" fill=\"currentColor\" /><circle cx=\"4\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\n <circle cx=\"4\" cy=\"18\" r=\"1\" fill=\"currentColor\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n isActive={editor.isActive('orderedList')}\n title={labels.orderedList}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\" /><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <text x=\"2\" y=\"8\" fontSize=\"8\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">1</text>\n <text x=\"2\" y=\"14\" fontSize=\"8\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">2</text>\n <text x=\"2\" y=\"20\" fontSize=\"8\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">3</text>\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleTaskList().run()}\n isActive={editor.isActive('taskList')}\n title={labels.taskList}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"5\" width=\"6\" height=\"6\" rx=\"1\" /><path d=\"M5 8l1.5 1.5L9 6.5\" />\n <line x1=\"12\" y1=\"8\" x2=\"21\" y2=\"8\" />\n <rect x=\"3\" y=\"14\" width=\"6\" height=\"6\" rx=\"1\" />\n <line x1=\"12\" y1=\"17\" x2=\"21\" y2=\"17\" />\n </svg>\n </ToolbarButton>\n <ToolbarDivider />\n </>\n )}\n\n {cfg.insert && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBlockquote().run()}\n isActive={editor.isActive('blockquote')}\n title={labels.blockquote}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V21z\" />\n <path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3z\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleNode('codeBlock', 'paragraph').run()}\n isActive={editor.isActive('codeBlock')}\n title={labels.codeBlock}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"16 18 22 12 16 6\" /><polyline points=\"8 6 2 12 8 18\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => {\n editor.chain().focus().insertContent({\n type: 'codeBlock',\n attrs: { language: 'r-mermaid' },\n content: [{ type: 'text', text: 'graph TD\\n A[Start] --> B[End]' }],\n }).run();\n }}\n title={labels.mermaidBlock}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"6\" cy=\"6\" r=\"3\" /><circle cx=\"18\" cy=\"6\" r=\"3\" />\n <circle cx=\"12\" cy=\"18\" r=\"3\" />\n <line x1=\"6\" y1=\"9\" x2=\"12\" y2=\"15\" /><line x1=\"18\" y1=\"9\" x2=\"12\" y2=\"15\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton onClick={setLink} isActive={editor.isActive('link')} title={labels.link}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton onClick={addImage} title={labels.image}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" /><polyline points=\"21 15 16 10 5 21\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton onClick={insertTable} title={labels.table}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\" /><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\" />\n <line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\" /><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\" />\n </svg>\n </ToolbarButton>\n {cfg.tableOps && <TableOpsMenu editor={editor} labels={labels} />}\n <ToolbarButton\n onClick={() => editor.chain().focus().setHorizontalRule().run()}\n title={labels.horizontalRule}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton onClick={insertMarkdownBlock} title={labels.markdownBlock}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M2 3h20v18H2z\" />\n <path d=\"M5 15V9l3 3.5L11 9v6\" />\n <path d=\"M17 9l-2.5 3H17v3\" />\n </svg>\n </ToolbarButton>\n <MarkdownTemplateMenu labels={labels} onSelect={insertMarkdownTemplate} />\n <FloatingDialogMenu labels={labels} onInsert={insertFloatingDialog} />\n <ToolbarDivider />\n </>\n )}\n\n {cfg.color && (\n <>\n <ColorPicker\n value={editor.getAttributes('textStyle').color || ''}\n onChange={(color) => {\n if (color) {\n editor.chain().focus().setColor(color).run();\n } else {\n editor.chain().focus().unsetColor().run();\n }\n }}\n title={labels.color}\n kind=\"text\"\n />\n <ColorPicker\n value={editor.getAttributes('highlight').color || ''}\n onChange={(color) => {\n if (color) {\n editor.chain().focus().toggleHighlight({ color }).run();\n } else {\n editor.chain().focus().unsetHighlight().run();\n }\n }}\n title={labels.highlight}\n kind=\"highlight\"\n />\n <ToolbarDivider />\n </>\n )}\n\n {cfg.ai && hasAI && onAIClick && (\n <ToolbarButton onClick={onAIClick} title={labels.ai}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M9.5 2A2.5 2.5 0 0112 4.5v15a2.5 2.5 0 01-4.96.44 2.5 2.5 0 01-2.96-3.08 3 3 0 01-.34-5.58 2.5 2.5 0 011.32-4.24 2.5 2.5 0 011.98-3A2.5 2.5 0 019.5 2z\" />\n <path d=\"M14.5 2A2.5 2.5 0 0012 4.5v15a2.5 2.5 0 004.96.44 2.5 2.5 0 002.96-3.08 3 3 0 00.34-5.58 2.5 2.5 0 00-1.32-4.24 2.5 2.5 0 00-1.98-3A2.5 2.5 0 0014.5 2z\" />\n </svg>\n </ToolbarButton>\n )}\n\n {children}\n </div>\n );\n};\n\nexport default Toolbar;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Toolbar.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/Toolbar.tsx"],"sourcesContent":["import React, { useCallback, useState, useEffect, useRef } from 'react';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport type { Mark } from '@tiptap/pm/model';\nimport type { ToolbarSection, RichTextEditorLabels } from '../types';\nimport { defaultLabels } from '../types';\nimport { getNextFloatZIndex } from '../extensions/FloatingDialog';\nimport { ToolbarButton, ToolbarDivider } from './ToolbarButton';\nimport { ColorPicker } from './ColorPicker';\nimport { SelectDropdown, FONT_FAMILIES, FONT_SIZES } from './SelectDropdown';\nimport { MarkdownTemplateMenu } from './MarkdownTemplates';\nimport { FloatingDialogMenu } from './FloatingDialogMenu';\nimport { TableOpsMenu } from './TableOpsMenu';\n\n// Only visual formatting belongs to the painter, never links or comment IDs.\nconst PAINT_MARKS = new Set(['bold', 'italic', 'underline', 'strike', 'code', 'subscript', 'superscript', 'textStyle', 'highlight']);\n\ninterface ToolbarProps {\n editor: Editor;\n config?: ToolbarSection;\n labels?: RichTextEditorLabels;\n hasAI?: boolean;\n onAIClick?: () => void;\n onFormatPainterChange?: (active: boolean) => void;\n children?: React.ReactNode;\n}\n\nconst Toolbar: React.FC<ToolbarProps> = ({\n editor,\n config,\n labels: propsLabels,\n hasAI,\n onAIClick,\n onFormatPainterChange,\n children,\n}) => {\n const labels = { ...defaultLabels, ...propsLabels };\n useEditorState({ editor, selector: ({ transactionNumber }) => transactionNumber });\n const [formatPainterMarks, setFormatPainterMarks] = useState<readonly Mark[] | null>(null);\n const painterChange = useRef(onFormatPainterChange);\n useEffect(() => {\n painterChange.current = onFormatPainterChange;\n }, [onFormatPainterChange]);\n\n const cfg: Required<ToolbarSection> = {\n textFormat: config?.textFormat ?? true,\n heading: config?.heading ?? true,\n alignment: config?.alignment ?? true,\n list: config?.list ?? true,\n insert: config?.insert ?? true,\n color: config?.color ?? true,\n history: config?.history ?? true,\n ai: config?.ai ?? true,\n tableOps: config?.tableOps ?? true,\n fontStyle: config?.fontStyle ?? true,\n formatPainter: config?.formatPainter ?? true,\n };\n\n const setLink = useCallback(() => {\n const previousUrl = editor.getAttributes('link').href;\n const url = window.prompt(labels.insertLinkUrl, previousUrl);\n if (url === null) return;\n if (editor.isDestroyed || !editor.isEditable) return;\n if (url.trim() === '') {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n return;\n }\n editor.chain().focus().extendMarkRange('link').setLink({ href: url.trim() }).run();\n }, [editor, labels.insertLinkUrl]);\n\n const addImage = useCallback(() => {\n const url = window.prompt(labels.insertImageUrl);\n if (url) {\n editor.chain().focus().setImage({ src: url }).run();\n }\n }, [editor, labels.insertImageUrl]);\n\n const insertTable = useCallback(() => {\n editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();\n }, [editor]);\n\n const insertMarkdownBlock = useCallback(() => {\n editor.chain().focus().insertContent({\n type: 'codeBlock',\n attrs: { language: 'r-markdown' },\n content: [{ type: 'text', text: '# Markdown\\n\\nWrite your **markdown** here.' }],\n }).run();\n }, [editor]);\n\n const insertMarkdownTemplate = useCallback((content: string, focusEditor = true) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n const chain = editor.chain();\n if (focusEditor) chain.focus();\n chain.insertContent({\n type: 'codeBlock',\n attrs: { language: 'r-markdown' },\n content: [{ type: 'text', text: content }],\n }).run();\n }, [editor]);\n\n const insertFloatingDialog = useCallback((layout: 'block' | 'wrap-left' | 'wrap-right' | 'float' = 'block', focusEditor = true) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n const extraAttrs = layout === 'float'\n ? { x: 40, y: 40, zIndex: getNextFloatZIndex(editor) }\n : layout === 'block'\n ? {}\n : { width: 240 };\n const chain = editor.chain();\n if (focusEditor) chain.focus();\n chain.insertContent({\n type: 'floatingDialog',\n attrs: { title: 'Note', layout, ...extraAttrs },\n content: [{ type: 'paragraph' }],\n }).run();\n }, [editor]);\n\n const handleFormatPainter = useCallback(() => {\n if (formatPainterMarks) {\n setFormatPainterMarks(null);\n return;\n }\n if (editor.isDestroyed || !editor.isEditable) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n\n let marks: readonly Mark[] | undefined;\n editor.state.doc.nodesBetween(from, to, (node) => {\n if (!node.isText) return;\n const formatting = node.marks.filter((mark) => PAINT_MARKS.has(mark.type.name));\n marks = marks === undefined ? formatting : marks.filter((mark) => formatting.some((other) => mark.eq(other)));\n });\n if (marks === undefined) return;\n setFormatPainterMarks(marks);\n }, [editor, formatPainterMarks]);\n\n useEffect(() => {\n if (!formatPainterMarks) return;\n if (editor.isDestroyed || !editor.isEditable || !cfg.formatPainter || !cfg.textFormat) {\n setFormatPainterMarks(null);\n return;\n }\n\n painterChange.current?.(true);\n const editorEl = editor.view.dom;\n let frame: number | null = null;\n let cancelled = false;\n const cancel = () => {\n cancelled = true;\n if (frame !== null) cancelAnimationFrame(frame);\n frame = null;\n setFormatPainterMarks(null);\n };\n const onTransaction = () => {\n if (!editor.isEditable) cancel();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') cancel();\n };\n\n const applyMarks = () => {\n frame = null;\n if (cancelled || editor.isDestroyed || !editor.isEditable) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n\n const { tr } = editor.state;\n for (const name of PAINT_MARKS) {\n const type = editor.schema.marks[name];\n if (type) tr.removeMark(from, to, type);\n }\n editor.state.doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isText) return;\n const semantic = node.marks.filter((mark) => !PAINT_MARKS.has(mark.type.name));\n for (const mark of formatPainterMarks) {\n // Code and custom exclusions must not implicitly remove semantic marks.\n if (semantic.some((other) => mark.type.excludes(other.type) || other.type.excludes(mark.type))) continue;\n tr.addMark(Math.max(from, pos), Math.min(to, pos + node.nodeSize), mark);\n }\n });\n cancelled = true;\n editor.view.dispatch(tr);\n setFormatPainterMarks(null);\n };\n\n const onMouseUp = () => {\n if (cancelled) return;\n if (frame !== null) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(applyMarks);\n };\n\n editorEl.addEventListener('mouseup', onMouseUp);\n editorEl.ownerDocument.addEventListener('keydown', onKeyDown);\n editor.on('transaction', onTransaction);\n editor.on('destroy', cancel);\n return () => {\n cancelled = true;\n if (frame !== null) cancelAnimationFrame(frame);\n editorEl.removeEventListener('mouseup', onMouseUp);\n editorEl.ownerDocument.removeEventListener('keydown', onKeyDown);\n editor.off('transaction', onTransaction);\n editor.off('destroy', cancel);\n painterChange.current?.(false);\n };\n }, [editor, formatPainterMarks, cfg.formatPainter, cfg.textFormat]);\n\n const currentFontFamily = editor.getAttributes('textStyle').fontFamily || '';\n const currentFontSize = editor.getAttributes('textStyle').fontSize || '';\n\n return (\n <div className=\"rte-toolbar\" role=\"group\" aria-label=\"Text formatting\">\n {cfg.history && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().undo().run()}\n disabled={!editor.can().undo()}\n title={labels.undo}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"1 4 1 10 7 10\" />\n <path d=\"M3.51 15a9 9 0 102.13-9.36L1 10\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().redo().run()}\n disabled={!editor.can().redo()}\n title={labels.redo}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"23 4 23 10 17 10\" />\n <path d=\"M20.49 15a9 9 0 11-2.13-9.36L23 10\" />\n </svg>\n </ToolbarButton>\n <ToolbarDivider />\n </>\n )}\n\n {cfg.fontStyle && (\n <>\n <SelectDropdown\n value={currentFontFamily}\n options={FONT_FAMILIES}\n onChange={(val) => {\n if (val) {\n editor.chain().focus().setFontFamily(val).run();\n } else {\n editor.chain().focus().unsetFontFamily().run();\n }\n }}\n title={labels.fontFamily}\n width={120}\n />\n <SelectDropdown\n value={currentFontSize}\n options={FONT_SIZES}\n onChange={(val) => {\n if (val) {\n (editor.chain().focus() as any).setFontSize(val).run();\n } else {\n (editor.chain().focus() as any).unsetFontSize().run();\n }\n }}\n title={labels.fontSize}\n width={80}\n />\n <ToolbarDivider />\n </>\n )}\n\n {cfg.textFormat && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n isActive={editor.isActive('bold')}\n title={labels.bold}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M6 4h8a4 4 0 014 4 4 4 0 01-4 4H6z\" />\n <path d=\"M6 12h9a4 4 0 014 4 4 4 0 01-4 4H6z\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n isActive={editor.isActive('italic')}\n title={labels.italic}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\" />\n <line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\" />\n <line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n isActive={editor.isActive('underline')}\n title={labels.underline}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M6 3v7a6 6 0 006 6 6 6 0 006-6V3\" />\n <line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleStrike().run()}\n isActive={editor.isActive('strike')}\n title={labels.strikethrough}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M17.3 4.9c-2.3-.6-4.4-1-6.2-.9-2.7 0-5.3.7-5.3 3.6 0 1.5 1.8 3.3 7.2 3.3\" />\n <path d=\"M13 15.1c0 2.8-2.6 3.6-5.3 3.6-1.8-.1-3.9-.5-6.2-.9\" />\n <line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleSubscript().run()}\n isActive={editor.isActive('subscript')}\n title={labels.subscript}\n >\n <span style={{ fontSize: '13px', fontWeight: 600 }}>X<sub style={{ fontSize: '9px' }}>2</sub></span>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleSuperscript().run()}\n isActive={editor.isActive('superscript')}\n title={labels.superscript}\n >\n <span style={{ fontSize: '13px', fontWeight: 600 }}>X<sup style={{ fontSize: '9px' }}>2</sup></span>\n </ToolbarButton>\n {cfg.formatPainter && (\n <ToolbarButton\n onClick={handleFormatPainter}\n disabled={!editor.isEditable || (!formatPainterMarks && editor.state.selection.empty)}\n isActive={!!formatPainterMarks}\n title={formatPainterMarks ? labels.formatPainterActive : labels.formatPainter}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M19 3H5a2 2 0 00-2 2v2a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2z\" />\n <path d=\"M10 7v4a2 2 0 01-2 2H7\" />\n <path d=\"M7 13l-3 8\" />\n <path d=\"M4 21h6\" />\n </svg>\n </ToolbarButton>\n )}\n <ToolbarDivider />\n </>\n )}\n\n {cfg.heading && (\n <>\n {([1, 2, 3, 4, 5, 6] as const).map((level) => (\n <ToolbarButton\n key={level}\n onClick={() => editor.chain().focus().toggleHeading({ level }).run()}\n isActive={editor.isActive('heading', { level })}\n title={`${labels.heading} ${level}`}\n >\n <span style={{ fontSize: '12px', fontWeight: 700 }}>H{level}</span>\n </ToolbarButton>\n ))}\n <ToolbarDivider />\n </>\n )}\n\n {cfg.alignment && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().setTextAlign('left').run()}\n isActive={editor.isActive({ textAlign: 'left' })}\n title={labels.alignLeft}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"17\" y1=\"10\" x2=\"3\" y2=\"10\" /><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\" />\n <line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\" /><line x1=\"17\" y1=\"18\" x2=\"3\" y2=\"18\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().setTextAlign('center').run()}\n isActive={editor.isActive({ textAlign: 'center' })}\n title={labels.alignCenter}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"10\" x2=\"6\" y2=\"10\" /><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\" />\n <line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\" /><line x1=\"18\" y1=\"18\" x2=\"6\" y2=\"18\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().setTextAlign('right').run()}\n isActive={editor.isActive({ textAlign: 'right' })}\n title={labels.alignRight}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"21\" y1=\"10\" x2=\"7\" y2=\"10\" /><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\" />\n <line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\" /><line x1=\"21\" y1=\"18\" x2=\"7\" y2=\"18\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().setTextAlign('justify').run()}\n isActive={editor.isActive({ textAlign: 'justify' })}\n title={labels.alignJustify}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"21\" y1=\"10\" x2=\"3\" y2=\"10\" /><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\" />\n <line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\" /><line x1=\"21\" y1=\"18\" x2=\"3\" y2=\"18\" />\n </svg>\n </ToolbarButton>\n <ToolbarDivider />\n </>\n )}\n\n {cfg.list && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n isActive={editor.isActive('bulletList')}\n title={labels.bulletList}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\" /><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <circle cx=\"4\" cy=\"6\" r=\"1\" fill=\"currentColor\" /><circle cx=\"4\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\n <circle cx=\"4\" cy=\"18\" r=\"1\" fill=\"currentColor\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n isActive={editor.isActive('orderedList')}\n title={labels.orderedList}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\" /><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <text x=\"2\" y=\"8\" fontSize=\"8\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">1</text>\n <text x=\"2\" y=\"14\" fontSize=\"8\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">2</text>\n <text x=\"2\" y=\"20\" fontSize=\"8\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">3</text>\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleTaskList().run()}\n isActive={editor.isActive('taskList')}\n title={labels.taskList}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"5\" width=\"6\" height=\"6\" rx=\"1\" /><path d=\"M5 8l1.5 1.5L9 6.5\" />\n <line x1=\"12\" y1=\"8\" x2=\"21\" y2=\"8\" />\n <rect x=\"3\" y=\"14\" width=\"6\" height=\"6\" rx=\"1\" />\n <line x1=\"12\" y1=\"17\" x2=\"21\" y2=\"17\" />\n </svg>\n </ToolbarButton>\n <ToolbarDivider />\n </>\n )}\n\n {cfg.insert && (\n <>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBlockquote().run()}\n isActive={editor.isActive('blockquote')}\n title={labels.blockquote}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V21z\" />\n <path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3z\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleNode('codeBlock', 'paragraph').run()}\n isActive={editor.isActive('codeBlock')}\n title={labels.codeBlock}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"16 18 22 12 16 6\" /><polyline points=\"8 6 2 12 8 18\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => {\n editor.chain().focus().insertContent({\n type: 'codeBlock',\n attrs: { language: 'r-mermaid' },\n content: [{ type: 'text', text: 'graph TD\\n A[Start] --> B[End]' }],\n }).run();\n }}\n title={labels.mermaidBlock}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"6\" cy=\"6\" r=\"3\" /><circle cx=\"18\" cy=\"6\" r=\"3\" />\n <circle cx=\"12\" cy=\"18\" r=\"3\" />\n <line x1=\"6\" y1=\"9\" x2=\"12\" y2=\"15\" /><line x1=\"18\" y1=\"9\" x2=\"12\" y2=\"15\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton onClick={setLink} isActive={editor.isActive('link')} title={labels.link}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton onClick={addImage} title={labels.image}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" /><polyline points=\"21 15 16 10 5 21\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton onClick={insertTable} title={labels.table}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\" /><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\" />\n <line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\" /><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\" />\n </svg>\n </ToolbarButton>\n {cfg.tableOps && <TableOpsMenu editor={editor} labels={labels} />}\n <ToolbarButton\n onClick={() => editor.chain().focus().setHorizontalRule().run()}\n title={labels.horizontalRule}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n </svg>\n </ToolbarButton>\n <ToolbarButton onClick={insertMarkdownBlock} title={labels.markdownBlock}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M2 3h20v18H2z\" />\n <path d=\"M5 15V9l3 3.5L11 9v6\" />\n <path d=\"M17 9l-2.5 3H17v3\" />\n </svg>\n </ToolbarButton>\n <MarkdownTemplateMenu labels={labels} onSelect={insertMarkdownTemplate} />\n <FloatingDialogMenu labels={labels} onInsert={insertFloatingDialog} />\n <ToolbarDivider />\n </>\n )}\n\n {cfg.color && (\n <>\n <ColorPicker\n value={editor.getAttributes('textStyle').color || ''}\n onChange={(color) => {\n if (color) {\n editor.chain().focus().setColor(color).run();\n } else {\n editor.chain().focus().unsetColor().run();\n }\n }}\n title={labels.color}\n kind=\"text\"\n />\n <ColorPicker\n value={editor.getAttributes('highlight').color || ''}\n onChange={(color) => {\n if (color) {\n editor.chain().focus().toggleHighlight({ color }).run();\n } else {\n editor.chain().focus().unsetHighlight().run();\n }\n }}\n title={labels.highlight}\n kind=\"highlight\"\n />\n <ToolbarDivider />\n </>\n )}\n\n {cfg.ai && hasAI && onAIClick && (\n <ToolbarButton onClick={onAIClick} title={labels.ai}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M9.5 2A2.5 2.5 0 0112 4.5v15a2.5 2.5 0 01-4.96.44 2.5 2.5 0 01-2.96-3.08 3 3 0 01-.34-5.58 2.5 2.5 0 011.32-4.24 2.5 2.5 0 011.98-3A2.5 2.5 0 019.5 2z\" />\n <path d=\"M14.5 2A2.5 2.5 0 0012 4.5v15a2.5 2.5 0 004.96.44 2.5 2.5 0 002.96-3.08 3 3 0 00.34-5.58 2.5 2.5 0 00-1.32-4.24 2.5 2.5 0 00-1.98-3A2.5 2.5 0 0014.5 2z\" />\n </svg>\n </ToolbarButton>\n )}\n\n {children}\n </div>\n );\n};\n\nexport default Toolbar;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useNodeEditable as e } from "./MarkdownBlock.js";
|
|
2
|
+
import { useCallback as t, useRef as n, useState as r } from "react";
|
|
3
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
|
+
import { NodeViewWrapper as o, ReactNodeViewRenderer as s } from "@tiptap/react";
|
|
5
|
+
import c from "@tiptap/extension-image";
|
|
6
|
+
//#region src/components/pro/RichTextEditor/extensions/ResizableImage.tsx
|
|
7
|
+
var l = 40, u = ({ node: s, updateAttributes: c, selected: u, editor: d }) => {
|
|
8
|
+
let f = e(d), p = n(null), [m, h] = r(!1), { src: g, alt: _, title: v, width: y, align: b } = s.attrs, x = t((e) => (t) => {
|
|
9
|
+
if (!f) return;
|
|
10
|
+
t.preventDefault(), t.stopPropagation();
|
|
11
|
+
let n = p.current;
|
|
12
|
+
if (!n) return;
|
|
13
|
+
let r = "touches" in t ? t.touches[0].clientX : t.clientX, i = n.getBoundingClientRect().width, a = n.naturalHeight && n.naturalWidth ? n.naturalHeight / n.naturalWidth : 0, o = e === "nw" || e === "sw" ? -1 : 1, s = n.parentElement?.parentElement?.getBoundingClientRect().width ?? Infinity;
|
|
14
|
+
h(!0);
|
|
15
|
+
let u = (e) => {
|
|
16
|
+
let t = (e - r) * o, n = Math.round(Math.min(s, Math.max(l, i + t)));
|
|
17
|
+
c({
|
|
18
|
+
width: n,
|
|
19
|
+
height: a ? Math.round(n * a) : null
|
|
20
|
+
});
|
|
21
|
+
}, d = (e) => u(e.clientX), m = (e) => {
|
|
22
|
+
e.cancelable && e.preventDefault(), u(e.touches[0].clientX);
|
|
23
|
+
}, g = () => {
|
|
24
|
+
h(!1), window.removeEventListener("mousemove", d), window.removeEventListener("mouseup", g), window.removeEventListener("touchmove", m), window.removeEventListener("touchend", g), window.removeEventListener("touchcancel", g);
|
|
25
|
+
};
|
|
26
|
+
window.addEventListener("mousemove", d), window.addEventListener("mouseup", g), window.addEventListener("touchmove", m, { passive: !1 }), window.addEventListener("touchend", g), window.addEventListener("touchcancel", g);
|
|
27
|
+
}, [f, c]), S = f && (u || m);
|
|
28
|
+
return /* @__PURE__ */ i(o, {
|
|
29
|
+
className: "rte-resizable-image",
|
|
30
|
+
"data-align": b || "left",
|
|
31
|
+
"data-active": S ? "true" : void 0,
|
|
32
|
+
children: /* @__PURE__ */ a("span", {
|
|
33
|
+
className: "rte-resizable-image__frame",
|
|
34
|
+
style: { width: y ? `${y}px` : void 0 },
|
|
35
|
+
children: [/* @__PURE__ */ i("img", {
|
|
36
|
+
ref: p,
|
|
37
|
+
src: g,
|
|
38
|
+
alt: _ || "",
|
|
39
|
+
title: v || void 0,
|
|
40
|
+
draggable: !1,
|
|
41
|
+
style: { width: y ? `${y}px` : void 0 }
|
|
42
|
+
}), S && [
|
|
43
|
+
"nw",
|
|
44
|
+
"ne",
|
|
45
|
+
"sw",
|
|
46
|
+
"se"
|
|
47
|
+
].map((e) => /* @__PURE__ */ i("span", {
|
|
48
|
+
className: `rte-resizable-image__handle rte-resizable-image__handle--${e}`,
|
|
49
|
+
onMouseDown: x(e),
|
|
50
|
+
onTouchStart: x(e),
|
|
51
|
+
role: "presentation"
|
|
52
|
+
}, e))]
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
}, d = c.extend({
|
|
56
|
+
addAttributes() {
|
|
57
|
+
return {
|
|
58
|
+
...this.parent?.(),
|
|
59
|
+
width: {
|
|
60
|
+
default: null,
|
|
61
|
+
parseHTML: (e) => {
|
|
62
|
+
let t = e.getAttribute("width");
|
|
63
|
+
if (t) return parseInt(t, 10) || null;
|
|
64
|
+
let n = e.style.width;
|
|
65
|
+
return n && parseInt(n, 10) || null;
|
|
66
|
+
},
|
|
67
|
+
renderHTML: (e) => e.width ? {
|
|
68
|
+
width: e.width,
|
|
69
|
+
style: `width: ${e.width}px`
|
|
70
|
+
} : {}
|
|
71
|
+
},
|
|
72
|
+
height: {
|
|
73
|
+
default: null,
|
|
74
|
+
parseHTML: (e) => {
|
|
75
|
+
let t = e.getAttribute("height");
|
|
76
|
+
return t && parseInt(t, 10) || null;
|
|
77
|
+
},
|
|
78
|
+
renderHTML: (e) => e.height ? { height: e.height } : {}
|
|
79
|
+
},
|
|
80
|
+
align: {
|
|
81
|
+
default: "left",
|
|
82
|
+
parseHTML: (e) => e.getAttribute("data-align") || "left",
|
|
83
|
+
renderHTML: (e) => e.align ? { "data-align": e.align } : {}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
addNodeView() {
|
|
88
|
+
return s(u);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
//#endregion
|
|
92
|
+
export { d as ResizableImage, d as default };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=ResizableImage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResizableImage.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/extensions/ResizableImage.tsx"],"sourcesContent":["import React, { useCallback, useRef, useState } from 'react';\nimport Image from '@tiptap/extension-image';\nimport { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react';\nimport type { NodeViewProps } from '@tiptap/react';\nimport { useNodeEditable } from './MarkdownBlock';\n\n/**\n * ResizableImage extends the stock Tiptap Image node with:\n * - persisted `width` / `height` / `align` attributes (serialized to HTML)\n * - a React NodeView that renders drag handles on the four corners so users can\n * resize the image by dragging (mouse + touch), keeping the aspect ratio.\n *\n * The public API is unchanged: `editor.chain().setImage({ src })` still works,\n * and existing documents (plain `<img>`) upgrade transparently.\n */\n\nconst MIN_WIDTH = 40;\n\ntype Corner = 'nw' | 'ne' | 'sw' | 'se';\n\nconst ResizableImageNodeView: React.FC<NodeViewProps> = ({ node, updateAttributes, selected, editor }) => {\n const editable = useNodeEditable(editor);\n const imgRef = useRef<HTMLImageElement>(null);\n const [resizing, setResizing] = useState(false);\n\n const { src, alt, title, width, align } = node.attrs as {\n src: string;\n alt?: string;\n title?: string;\n width?: number | null;\n height?: number | null;\n align?: 'left' | 'center' | 'right' | null;\n };\n\n const startResize = useCallback(\n (corner: Corner) => (event: React.MouseEvent | React.TouchEvent) => {\n if (!editable) return;\n event.preventDefault();\n event.stopPropagation();\n\n const img = imgRef.current;\n if (!img) return;\n\n const isTouch = 'touches' in event;\n const startX = isTouch ? event.touches[0].clientX : (event as React.MouseEvent).clientX;\n const startWidth = img.getBoundingClientRect().width;\n const ratio = img.naturalHeight && img.naturalWidth ? img.naturalHeight / img.naturalWidth : 0;\n // Left-side handles grow the image when dragged leftwards.\n const dir = corner === 'nw' || corner === 'sw' ? -1 : 1;\n const maxWidth = img.parentElement?.parentElement?.getBoundingClientRect().width ?? Infinity;\n\n setResizing(true);\n\n const move = (clientX: number) => {\n const delta = (clientX - startX) * dir;\n const next = Math.round(Math.min(maxWidth, Math.max(MIN_WIDTH, startWidth + delta)));\n updateAttributes({ width: next, height: ratio ? Math.round(next * ratio) : null });\n };\n\n const onMouseMove = (e: MouseEvent) => move(e.clientX);\n const onTouchMove = (e: TouchEvent) => {\n if (e.cancelable) e.preventDefault();\n move(e.touches[0].clientX);\n };\n const stop = () => {\n setResizing(false);\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('mouseup', stop);\n window.removeEventListener('touchmove', onTouchMove);\n window.removeEventListener('touchend', stop);\n window.removeEventListener('touchcancel', stop);\n };\n\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('mouseup', stop);\n window.addEventListener('touchmove', onTouchMove, { passive: false });\n window.addEventListener('touchend', stop);\n window.addEventListener('touchcancel', stop);\n },\n [editable, updateAttributes],\n );\n\n const active = editable && (selected || resizing);\n const corners: Corner[] = ['nw', 'ne', 'sw', 'se'];\n\n return (\n <NodeViewWrapper\n className=\"rte-resizable-image\"\n data-align={align || 'left'}\n data-active={active ? 'true' : undefined}\n >\n <span className=\"rte-resizable-image__frame\" style={{ width: width ? `${width}px` : undefined }}>\n <img\n ref={imgRef}\n src={src}\n alt={alt || ''}\n title={title || undefined}\n draggable={false}\n style={{ width: width ? `${width}px` : undefined }}\n />\n {active &&\n corners.map((corner) => (\n <span\n key={corner}\n className={`rte-resizable-image__handle rte-resizable-image__handle--${corner}`}\n onMouseDown={startResize(corner)}\n onTouchStart={startResize(corner)}\n role=\"presentation\"\n />\n ))}\n </span>\n </NodeViewWrapper>\n );\n};\n\nexport const ResizableImage = Image.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n width: {\n default: null,\n parseHTML: (element) => {\n const attr = element.getAttribute('width');\n if (attr) return parseInt(attr, 10) || null;\n const style = element.style.width;\n return style ? parseInt(style, 10) || null : null;\n },\n renderHTML: (attributes) =>\n attributes.width ? { width: attributes.width, style: `width: ${attributes.width}px` } : {},\n },\n height: {\n default: null,\n parseHTML: (element) => {\n const attr = element.getAttribute('height');\n return attr ? parseInt(attr, 10) || null : null;\n },\n renderHTML: (attributes) => (attributes.height ? { height: attributes.height } : {}),\n },\n align: {\n default: 'left',\n parseHTML: (element) => element.getAttribute('data-align') || 'left',\n renderHTML: (attributes) => (attributes.align ? { 'data-align': attributes.align } : {}),\n },\n };\n },\n addNodeView() {\n return ReactNodeViewRenderer(ResizableImageNodeView);\n },\n});\n\nexport default ResizableImage;\n"],"mappings":"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"}
|