dishui 0.0.106 → 0.0.108

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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.0.106",
2
+ "version": "0.0.108",
3
3
  "full": false,
4
4
  "node": "v22.13.1",
5
- "verifiedAt": "2026-09-24T14:14:24.880Z"
5
+ "verifiedAt": "2026-09-26T14:47:10.114Z"
6
6
  }
@@ -10,6 +10,7 @@ interface AIRewriteProps {
10
10
  from: number;
11
11
  to: number;
12
12
  };
13
+ followSelection?: boolean;
13
14
  onClose: () => void;
14
15
  }
15
16
  declare const AIRewrite: React.FC<AIRewriteProps>;
@@ -169,80 +169,101 @@ function h(e, t, n, r, i, a) {
169
169
  }
170
170
  return e.protocol === "anthropic" ? m(e, t, n, i) : p(e, t, n, i);
171
171
  }
172
- var g = ({ editor: f, aiConfig: p, labels: m, initialSelection: g, selectionRange: _, onClose: v }) => {
173
- let y = {
172
+ var g = ({ editor: f, aiConfig: p, labels: m, initialSelection: g, selectionRange: _, followSelection: v = !1, onClose: y }) => {
173
+ let b = {
174
174
  ...e,
175
175
  ...m
176
- }, b = a(), [x, S] = s(""), [C, w] = s(!1), [T, E] = s(""), [D, O] = s(null), k = o(null), A = o(null), [j, M] = s(() => !f.isDestroyed && f.isEditable), [N, P] = s(!1), F = o(f.state.doc), I = o(!1), L = r(() => {
177
- let e = k.current;
178
- k.current = null, e?.abort();
176
+ }, x = a(), [S, C] = s(""), [w, T] = s(!1), [E, D] = s(""), [O, k] = s(null), A = o(null), j = o(null), [M, N] = s(() => !f.isDestroyed && f.isEditable), [P, F] = s(!1), I = o(f.state.doc), L = o(!1), [R, z] = s(() => ({
177
+ from: _.from,
178
+ to: _.to,
179
+ text: g
180
+ })), B = o(R), V = r(() => {
181
+ let e = A.current;
182
+ A.current = null, e?.abort();
179
183
  }, []);
180
184
  i(() => {
181
- F.current = f.state.doc, I.current = !1, P(!1), E(""), w(!1), O(null);
185
+ B.current = {
186
+ from: _.from,
187
+ to: _.to,
188
+ text: g
189
+ }, z(B.current);
190
+ }, [
191
+ g,
192
+ _.from,
193
+ _.to
194
+ ]), i(() => {
195
+ I.current = f.state.doc, L.current = !1, F(!1), D(""), T(!1), k(null);
182
196
  let e = () => {
183
- M(!f.isDestroyed && f.isEditable), (f.isDestroyed || !f.isEditable || f.state.doc !== F.current) && (I.current = !0, P(!0), L(), w(!1), E(""), O("The document or editing permissions changed. Close and reopen AI Assistant."));
197
+ N(!f.isDestroyed && f.isEditable), (f.isDestroyed || !f.isEditable || f.state.doc !== I.current) && (L.current = !0, F(!0), V(), T(!1), D(""), k("The document or editing permissions changed. Close and reopen AI Assistant."));
198
+ }, t = () => {
199
+ if (!v || f.isDestroyed || !f.isEditable || f.state.doc !== I.current || L.current) return;
200
+ let { from: e, to: t } = f.state.selection, n = B.current;
201
+ if (e === t || e === n.from && t === n.to) return;
202
+ let r = {
203
+ from: e,
204
+ to: t,
205
+ text: f.state.doc.textBetween(e, t, " ")
206
+ };
207
+ B.current = r, z(r), V(), T(!1), D(""), k(null);
184
208
  };
185
- return e(), f.on("update", e), f.on("transaction", e), f.on("destroy", e), () => {
186
- L(), f.off("update", e), f.off("transaction", e), f.off("destroy", e);
209
+ return e(), f.on("update", e), f.on("transaction", e), f.on("selectionUpdate", t), f.on("destroy", e), () => {
210
+ V(), f.off("update", e), f.off("transaction", e), f.off("selectionUpdate", t), f.off("destroy", e);
187
211
  };
188
212
  }, [
189
213
  f,
190
- g,
191
- _.from,
192
- _.to,
193
- L
214
+ V,
215
+ v
194
216
  ]);
195
- let R = g;
217
+ let H = R.text;
196
218
  i(() => {
197
- A.current && A.current.focus();
219
+ j.current && j.current.focus();
198
220
  }, []);
199
- let z = r(async (e = "custom", t) => {
200
- if (f.isDestroyed || !f.isEditable || I.current || k.current) return;
201
- let n = R ? "replace" : "insert";
202
- if (n === "insert" && !x.trim()) return;
203
- let r = e === "custom" ? n === "replace" ? "Edit the selected text according to the user instruction. Return only the replacement text." : "Generate text according to the user instruction. Return only the text to insert." : d(e, t), i = [p.systemPrompt, r].filter(Boolean).join("\n\n"), a = n === "replace" ? x.trim() ? `Instruction:\n${x.trim()}\n\nSelected text:\n${R}` : R : x.trim();
204
- w(!0), E(""), O(null);
221
+ let U = r(async (e = "custom", t) => {
222
+ if (f.isDestroyed || !f.isEditable || L.current || A.current) return;
223
+ let n = H ? "replace" : "insert";
224
+ if (n === "insert" && !S.trim()) return;
225
+ let r = e === "custom" ? n === "replace" ? "Edit the selected text according to the user instruction. Return only the replacement text." : "Generate text according to the user instruction. Return only the text to insert." : d(e, t), i = [p.systemPrompt, r].filter(Boolean).join("\n\n"), a = n === "replace" ? S.trim() ? `Instruction:\n${S.trim()}\n\nSelected text:\n${H}` : H : S.trim();
226
+ T(!0), D(""), k(null);
205
227
  let o = new AbortController();
206
- k.current = o;
228
+ A.current = o;
207
229
  try {
208
230
  let t = "";
209
231
  for await (let r of h(p, a, i, e, o.signal, {
210
- prompt: x.trim(),
211
- selectedText: R,
232
+ prompt: S.trim(),
233
+ selectedText: H,
212
234
  mode: n
213
235
  })) {
214
- if (o.signal.aborted || k.current !== o) break;
215
- t += r, E(t);
236
+ if (o.signal.aborted || A.current !== o) break;
237
+ t += r, D(t);
216
238
  }
217
239
  } catch (e) {
218
- if (o.signal.aborted || k.current !== o) return;
219
- E(""), O(String(e instanceof Error ? e.message : e));
240
+ if (o.signal.aborted || A.current !== o) return;
241
+ D(""), k(String(e instanceof Error ? e.message : e));
220
242
  } finally {
221
- k.current === o && (k.current = null, w(!1));
243
+ A.current === o && (A.current = null, T(!1));
222
244
  }
223
245
  }, [
224
246
  f,
225
247
  p,
226
- R,
227
- x
228
- ]), B = r(() => {
229
- if (!T || k.current || f.isDestroyed || !f.isEditable || I.current) return;
230
- let { from: e, to: t } = _;
231
- if (f.state.doc !== F.current || !Number.isInteger(e) || !Number.isInteger(t) || e < 0 || t < e || t > f.state.doc.content.size) {
232
- O("The original selection is no longer valid. Close and reopen AI Assistant.");
248
+ H,
249
+ S
250
+ ]), W = r(() => {
251
+ if (!E || A.current || f.isDestroyed || !f.isEditable || L.current) return;
252
+ let { from: e, to: t } = B.current;
253
+ if (f.state.doc !== I.current || !Number.isInteger(e) || !Number.isInteger(t) || e < 0 || t < e || t > f.state.doc.content.size) {
254
+ k("The original selection is no longer valid. Close and reopen AI Assistant.");
233
255
  return;
234
256
  }
235
- f.view.dispatch(f.state.tr.insertText(T, e, t)), E(""), S(""), v();
257
+ f.view.dispatch(f.state.tr.insertText(E, e, t)), D(""), C(""), y();
236
258
  }, [
237
259
  f,
238
- T,
239
- _,
240
- v
241
- ]), V = r(() => {
242
- L(), E(""), w(!1), O(null);
243
- }, [L]), H = r((e) => {
244
- e.key === "Enter" && (e.metaKey || e.ctrlKey) && (e.preventDefault(), z());
245
- }, [z]);
260
+ E,
261
+ y
262
+ ]), G = r(() => {
263
+ V(), D(""), T(!1), k(null);
264
+ }, [V]), K = r((e) => {
265
+ e.key === "Enter" && (e.metaKey || e.ctrlKey) && (e.preventDefault(), U());
266
+ }, [U]);
246
267
  return /* @__PURE__ */ l("div", {
247
268
  className: "rte-ai-panel-v2",
248
269
  children: [
@@ -250,15 +271,15 @@ var g = ({ editor: f, aiConfig: p, labels: m, initialSelection: g, selectionRang
250
271
  className: "rte-ai-panel-v2__header",
251
272
  children: [/* @__PURE__ */ l("span", {
252
273
  className: "rte-ai-panel-v2__title",
253
- children: ["✨ ", y.ai || "AI Assistant"]
274
+ children: ["✨ ", b.ai || "AI Assistant"]
254
275
  }), /* @__PURE__ */ c("button", {
255
276
  type: "button",
256
277
  className: "rte-ai-panel-v2__close-btn",
257
278
  onClick: () => {
258
- L(), v();
279
+ V(), y();
259
280
  },
260
- title: y.aiClose,
261
- "aria-label": y.aiClose,
281
+ title: b.aiClose,
282
+ "aria-label": b.aiClose,
262
283
  children: /* @__PURE__ */ l("svg", {
263
284
  width: "14",
264
285
  height: "14",
@@ -286,30 +307,30 @@ var g = ({ editor: f, aiConfig: p, labels: m, initialSelection: g, selectionRang
286
307
  className: "rte-ai-panel-v2__prompt-section",
287
308
  children: [/* @__PURE__ */ c("label", {
288
309
  className: "rte-ai-panel-v2__label",
289
- htmlFor: b,
290
- children: y.aiPromptLabel
310
+ htmlFor: x,
311
+ children: b.aiPromptLabel
291
312
  }), /* @__PURE__ */ c("textarea", {
292
- id: b,
293
- ref: A,
313
+ id: x,
314
+ ref: j,
294
315
  className: "rte-ai-panel-v2__prompt-input",
295
- value: x,
296
- onChange: (e) => S(e.target.value),
297
- onKeyDown: H,
298
- placeholder: y.aiPromptPlaceholder,
316
+ value: S,
317
+ onChange: (e) => C(e.target.value),
318
+ onKeyDown: K,
319
+ placeholder: b.aiPromptPlaceholder,
299
320
  rows: 3,
300
- disabled: C || !j || N
321
+ disabled: w || !M || P
301
322
  })]
302
323
  }),
303
324
  /* @__PURE__ */ l("div", {
304
325
  className: "rte-ai-panel-v2__selection-section",
305
326
  children: [/* @__PURE__ */ c("span", {
306
327
  className: "rte-ai-panel-v2__label",
307
- children: y.aiSelectedText
328
+ children: b.aiSelectedText
308
329
  }), /* @__PURE__ */ c("div", {
309
330
  className: "rte-ai-panel-v2__selection-box",
310
- children: R ? /* @__PURE__ */ c("span", { children: R.length > 300 ? R.slice(0, 300) + "..." : R }) : /* @__PURE__ */ c("span", {
331
+ children: H ? /* @__PURE__ */ c("span", { children: H.length > 300 ? H.slice(0, 300) + "..." : H }) : /* @__PURE__ */ c("span", {
311
332
  className: "rte-ai-panel-v2__empty",
312
- children: y.aiInsertHint
333
+ children: b.aiInsertHint
313
334
  })
314
335
  })]
315
336
  }),
@@ -318,10 +339,10 @@ var g = ({ editor: f, aiConfig: p, labels: m, initialSelection: g, selectionRang
318
339
  children: u.map(({ key: e, labelKey: t, icon: n }) => /* @__PURE__ */ l("button", {
319
340
  type: "button",
320
341
  className: "rte-ai-panel-v2__quick-btn",
321
- onClick: () => z(e),
322
- disabled: C || !j || N || !R.trim(),
323
- title: R ? y[t] : y.aiInsertHint,
324
- children: [/* @__PURE__ */ c("span", { children: n }), /* @__PURE__ */ c("span", { children: y[t] })]
342
+ onClick: () => U(e),
343
+ disabled: w || !M || P || !H.trim(),
344
+ title: H ? b[t] : b.aiInsertHint,
345
+ children: [/* @__PURE__ */ c("span", { children: n }), /* @__PURE__ */ c("span", { children: b[t] })]
325
346
  }, e))
326
347
  }),
327
348
  /* @__PURE__ */ l("div", {
@@ -329,45 +350,45 @@ var g = ({ editor: f, aiConfig: p, labels: m, initialSelection: g, selectionRang
329
350
  children: [/* @__PURE__ */ c("button", {
330
351
  type: "button",
331
352
  className: "rte-ai-panel-v2__generate-btn",
332
- onClick: () => z(),
333
- disabled: C || !j || N || !x.trim() && !R.trim(),
334
- children: C ? y.aiProcessing : `✨ ${y.aiGenerate}`
335
- }), C && /* @__PURE__ */ c("button", {
353
+ onClick: () => U(),
354
+ disabled: w || !M || P || !S.trim() && !H.trim(),
355
+ children: w ? b.aiProcessing : `✨ ${b.aiGenerate}`
356
+ }), w && /* @__PURE__ */ c("button", {
336
357
  type: "button",
337
358
  className: "rte-ai-panel-v2__cancel-btn",
338
- onClick: V,
339
- children: y.aiCancel
359
+ onClick: G,
360
+ children: b.aiCancel
340
361
  })]
341
362
  }),
342
- C && !T && /* @__PURE__ */ c(n, {
363
+ w && !E && /* @__PURE__ */ c(n, {
343
364
  className: "rte-ai-panel-v2__loading",
344
- label: y.aiProcessing,
365
+ label: b.aiProcessing,
345
366
  variant: "dots",
346
367
  layout: "block",
347
368
  size: "sm"
348
369
  }),
349
- T && /* @__PURE__ */ l("div", {
370
+ E && /* @__PURE__ */ l("div", {
350
371
  className: "rte-ai-panel-v2__result",
351
372
  children: [
352
373
  /* @__PURE__ */ l("div", {
353
374
  className: "rte-ai-panel-v2__result-header",
354
375
  children: [/* @__PURE__ */ c("span", {
355
376
  className: "rte-ai-panel-v2__label",
356
- children: y.aiResult
377
+ children: b.aiResult
357
378
  }), /* @__PURE__ */ l("span", {
358
- className: `rte-ai-panel-v2__stream-status ${C ? "rte-ai-panel-v2__stream-status--live" : ""}`,
379
+ className: `rte-ai-panel-v2__stream-status ${w ? "rte-ai-panel-v2__stream-status--live" : ""}`,
359
380
  role: "status",
360
381
  children: [/* @__PURE__ */ c("span", {
361
382
  className: "rte-ai-panel-v2__stream-dot",
362
383
  "aria-hidden": "true"
363
- }), C ? y.aiProcessing : `${T.length} chars`]
384
+ }), w ? b.aiProcessing : `${E.length} chars`]
364
385
  })]
365
386
  }),
366
387
  /* @__PURE__ */ c("div", {
367
388
  className: "rte-ai-panel-v2__result-text",
368
389
  children: /* @__PURE__ */ c(t, {
369
- text: T,
370
- streaming: C
390
+ text: E,
391
+ streaming: w
371
392
  })
372
393
  }),
373
394
  /* @__PURE__ */ l("div", {
@@ -375,24 +396,24 @@ var g = ({ editor: f, aiConfig: p, labels: m, initialSelection: g, selectionRang
375
396
  children: [/* @__PURE__ */ c("button", {
376
397
  type: "button",
377
398
  className: "rte-ai-panel-v2__accept-btn",
378
- disabled: C || !j || N,
379
- onClick: B,
380
- children: y.aiAccept
399
+ disabled: w || !M || P,
400
+ onClick: W,
401
+ children: b.aiAccept
381
402
  }), /* @__PURE__ */ c("button", {
382
403
  type: "button",
383
404
  className: "rte-ai-panel-v2__reject-btn",
384
- onClick: V,
385
- children: y.aiReject
405
+ onClick: G,
406
+ children: b.aiReject
386
407
  })]
387
408
  })
388
409
  ]
389
410
  }),
390
- D && /* @__PURE__ */ l("div", {
411
+ O && /* @__PURE__ */ l("div", {
391
412
  className: "rte-ai-panel-v2__error",
392
- children: [/* @__PURE__ */ c("span", { children: D }), /* @__PURE__ */ c("button", {
413
+ children: [/* @__PURE__ */ c("span", { children: O }), /* @__PURE__ */ c("button", {
393
414
  type: "button",
394
- onClick: () => O(null),
395
- children: y.aiDismiss
415
+ onClick: () => k(null),
416
+ children: b.aiDismiss
396
417
  })]
397
418
  })
398
419
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"AIRewrite.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/AIRewrite.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect, useId } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { AIConfig, AIAction, RichTextEditorLabels } from './types';\nimport { defaultLabels } from './types';\nimport StreamingText from '../../ai/StreamingText';\nimport LoadingState from '../../ai/LoadingState';\n\ninterface AIRewriteProps {\n editor: Editor;\n aiConfig: AIConfig;\n labels?: RichTextEditorLabels;\n initialSelection: string;\n selectionRange: { from: number; to: number };\n onClose: () => void;\n}\n\nconst QUICK_ACTIONS: { key: AIAction; labelKey: keyof RichTextEditorLabels; icon: string }[] = [\n { key: 'rewrite', labelKey: 'aiRewrite', icon: '✏' },\n { key: 'shorten', labelKey: 'aiShorten', icon: '📝' },\n { key: 'expand', labelKey: 'aiExpand', icon: '📄' },\n { key: 'fix_grammar', labelKey: 'aiFixGrammar', icon: '✓' },\n { key: 'translate_en', labelKey: 'aiTranslateEn', icon: 'EN' },\n { key: 'translate_zh', labelKey: 'aiTranslateZh', icon: '中' },\n { key: 'professional', labelKey: 'aiProfessional', icon: '💼' },\n { key: 'casual', labelKey: 'aiCasual', icon: '💬' },\n];\n\nfunction getSystemPrompt(action: AIAction | 'custom', customPrompt?: string): string {\n if (action === 'custom') return customPrompt || 'Follow the user instructions.';\n const prompts: Record<AIAction, string> = {\n rewrite: 'Rewrite the following text to improve clarity and readability. Keep the same meaning and tone. Return only the rewritten text.',\n shorten: 'Shorten the following text while preserving its key meaning. Be concise. Return only the shortened text.',\n expand: 'Expand the following text with more details and examples while keeping the same tone. Return only the expanded text.',\n fix_grammar: 'Fix any grammar, spelling, and punctuation errors in the following text. Return only the corrected text.',\n translate_en: 'Translate the following text to English. Return only the translated text.',\n translate_zh: 'Translate the following text to Chinese. Return only the translated text.',\n professional: 'Rewrite the following text in a professional, formal tone. Return only the rewritten text.',\n casual: 'Rewrite the following text in a casual, friendly tone. Return only the rewritten text.',\n };\n return customPrompt || prompts[action];\n}\n\nasync function* readSSE(response: Response): AsyncGenerator<string> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No response body');\n const decoder = new TextDecoder();\n let buffer = '';\n let data: string[] = [];\n try {\n while (true) {\n const { done, value } = await reader.read();\n buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });\n // Normalize CRLF only when the complete line is available (chunks may split it).\n let newline: number;\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).replace(/\\r$/, '');\n buffer = buffer.slice(newline + 1);\n if (!line) {\n if (data.length) yield data.join('\\n');\n data = [];\n } else if (line.startsWith('data:')) {\n data.push(line.slice(5).replace(/^ /, ''));\n }\n }\n if (done) {\n if (buffer.startsWith('data:')) data.push(buffer.slice(5).replace(/^ /, '').replace(/\\r$/, ''));\n if (data.length) yield data.join('\\n');\n return;\n }\n }\n } finally {\n try { await reader.cancel(); } catch { /* The request may already be aborted. */ }\n reader.releaseLock();\n }\n}\n\nasync function* streamOpenAI(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n if (!config.gateway || !config.model) throw new Error('OpenAI protocol requires gateway and model');\n const body = JSON.stringify({\n model: config.model,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: text },\n ],\n stream: true,\n });\n\n const response = await fetch(config.gateway, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}),\n ...config.headers,\n },\n body,\n signal,\n });\n\n if (!response.ok) throw new Error(`AI API error: ${response.status} ${response.statusText}`);\n for await (const payload of readSSE(response)) {\n if (payload.trim() === '[DONE]') return;\n let data;\n try { data = JSON.parse(payload); } catch { continue; }\n if (data?.error) throw new Error(data.error.message || 'AI stream error');\n const content = data?.choices?.[0]?.delta?.content;\n if (typeof content === 'string') yield content;\n }\n}\n\nasync function* streamAnthropic(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n if (!config.gateway || !config.model) throw new Error('Anthropic protocol requires gateway and model');\n const body = JSON.stringify({\n model: config.model,\n max_tokens: 4096,\n system: systemPrompt,\n messages: [{ role: 'user', content: text }],\n stream: true,\n });\n\n const response = await fetch(config.gateway, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { 'x-api-key': config.apiKey } : {}),\n 'anthropic-version': '2023-06-01',\n ...config.headers,\n },\n body,\n signal,\n });\n\n if (!response.ok) throw new Error(`AI API error: ${response.status} ${response.statusText}`);\n for await (const payload of readSSE(response)) {\n let data;\n try { data = JSON.parse(payload); } catch { continue; }\n if (data?.type === 'error') throw new Error(data.error?.message || 'AI stream error');\n if (data?.type === 'message_stop') return;\n if (data?.type === 'content_block_delta' && typeof data.delta?.text === 'string') yield data.delta.text;\n }\n}\n\nfunction getStream(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n action: AIAction | 'custom',\n signal: AbortSignal,\n request?: { prompt: string; selectedText: string; mode: 'replace' | 'insert' },\n): AsyncIterable<string> {\n if (config.protocol === 'custom') {\n if (!config.customHandler) throw new Error('Custom AI protocol requires customHandler');\n return config.customHandler({\n text,\n action: action === 'custom' ? 'rewrite' : action,\n systemPrompt,\n signal,\n prompt: request?.prompt ?? '',\n selectedText: request?.selectedText ?? text,\n mode: request?.mode ?? 'replace',\n });\n }\n if (config.protocol === 'anthropic') return streamAnthropic(config, text, systemPrompt, signal);\n return streamOpenAI(config, text, systemPrompt, signal);\n}\n\nconst AIRewrite: React.FC<AIRewriteProps> = ({ editor, aiConfig, labels: propsLabels, initialSelection, selectionRange, onClose }) => {\n const labels = { ...defaultLabels, ...propsLabels };\n const promptId = useId();\n const [prompt, setPrompt] = useState('');\n const [isProcessing, setIsProcessing] = useState(false);\n const [streamedText, setStreamedText] = useState('');\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const promptRef = useRef<HTMLTextAreaElement>(null);\n const [editable, setEditable] = useState(() => !editor.isDestroyed && editor.isEditable);\n const [invalid, setInvalid] = useState(false);\n const sourceDoc = useRef(editor.state.doc);\n const invalidRef = useRef(false);\n\n const cancelRequest = useCallback(() => {\n const request = abortRef.current;\n abortRef.current = null;\n request?.abort();\n }, []);\n\n useEffect(() => {\n sourceDoc.current = editor.state.doc;\n invalidRef.current = false;\n setInvalid(false);\n setStreamedText('');\n setIsProcessing(false);\n setError(null);\n const invalidate = () => {\n setEditable(!editor.isDestroyed && editor.isEditable);\n if (editor.isDestroyed || !editor.isEditable || editor.state.doc !== sourceDoc.current) {\n invalidRef.current = true;\n setInvalid(true);\n cancelRequest();\n setIsProcessing(false);\n setStreamedText('');\n setError('The document or editing permissions changed. Close and reopen AI Assistant.');\n }\n };\n invalidate();\n editor.on('update', invalidate);\n editor.on('transaction', invalidate);\n editor.on('destroy', invalidate);\n return () => {\n cancelRequest();\n editor.off('update', invalidate);\n editor.off('transaction', invalidate);\n editor.off('destroy', invalidate);\n };\n }, [editor, initialSelection, selectionRange.from, selectionRange.to, cancelRequest]);\n\n const selectedText = initialSelection;\n\n useEffect(() => {\n if (promptRef.current) promptRef.current.focus();\n }, []);\n\n const handleGenerate = useCallback(async (action: AIAction | 'custom' = 'custom', customPromptOverride?: string) => {\n if (editor.isDestroyed || !editor.isEditable || invalidRef.current || abortRef.current) return;\n const mode = selectedText ? 'replace' : 'insert';\n if (mode === 'insert' && !prompt.trim()) return;\n\n const actionPrompt = action === 'custom'\n ? (mode === 'replace'\n ? 'Edit the selected text according to the user instruction. Return only the replacement text.'\n : 'Generate text according to the user instruction. Return only the text to insert.')\n : getSystemPrompt(action, customPromptOverride);\n const systemPrompt = [aiConfig.systemPrompt, actionPrompt].filter(Boolean).join('\\n\\n');\n const userText = mode === 'replace'\n ? (prompt.trim()\n ? `Instruction:\\n${prompt.trim()}\\n\\nSelected text:\\n${selectedText}`\n : selectedText)\n : prompt.trim();\n\n setIsProcessing(true);\n setStreamedText('');\n setError(null);\n\n const abort = new AbortController();\n abortRef.current = abort;\n\n try {\n let result = '';\n for await (const chunk of getStream(aiConfig, userText, systemPrompt, action, abort.signal, {\n prompt: prompt.trim(),\n selectedText,\n mode,\n })) {\n if (abort.signal.aborted || abortRef.current !== abort) break;\n result += chunk;\n setStreamedText(result);\n }\n } catch (err: unknown) {\n if (abort.signal.aborted || abortRef.current !== abort) return;\n setStreamedText('');\n setError(String(err instanceof Error ? err.message : err));\n } finally {\n if (abortRef.current === abort) {\n abortRef.current = null;\n setIsProcessing(false);\n }\n }\n }, [editor, aiConfig, selectedText, prompt]);\n\n const handleAccept = useCallback(() => {\n if (!streamedText || abortRef.current || editor.isDestroyed || !editor.isEditable || invalidRef.current) return;\n const { from, to } = selectionRange;\n if (editor.state.doc !== sourceDoc.current || !Number.isInteger(from) || !Number.isInteger(to) || from < 0 || to < from || to > editor.state.doc.content.size) {\n setError('The original selection is no longer valid. Close and reopen AI Assistant.');\n return;\n }\n // AI output is plain text, never HTML. Use the captured range even if the cursor moved.\n editor.view.dispatch(editor.state.tr.insertText(streamedText, from, to));\n setStreamedText('');\n setPrompt('');\n onClose();\n }, [editor, streamedText, selectionRange, onClose]);\n\n const handleReject = useCallback(() => {\n cancelRequest();\n setStreamedText('');\n setIsProcessing(false);\n setError(null);\n }, [cancelRequest]);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleGenerate();\n }\n }, [handleGenerate]);\n\n return (\n <div className=\"rte-ai-panel-v2\">\n <div className=\"rte-ai-panel-v2__header\">\n <span className=\"rte-ai-panel-v2__title\">✨ {labels.ai || 'AI Assistant'}</span>\n <button type=\"button\" className=\"rte-ai-panel-v2__close-btn\" onClick={() => { cancelRequest(); onClose(); }} title={labels.aiClose} aria-label={labels.aiClose}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n {/* Prompt input */}\n <div className=\"rte-ai-panel-v2__prompt-section\">\n <label className=\"rte-ai-panel-v2__label\" htmlFor={promptId}>{labels.aiPromptLabel}</label>\n <textarea\n id={promptId}\n ref={promptRef}\n className=\"rte-ai-panel-v2__prompt-input\"\n value={prompt}\n onChange={(e) => setPrompt(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={labels.aiPromptPlaceholder}\n rows={3}\n disabled={isProcessing || !editable || invalid}\n />\n </div>\n\n {/* Selected text display */}\n <div className=\"rte-ai-panel-v2__selection-section\">\n <span className=\"rte-ai-panel-v2__label\">{labels.aiSelectedText}</span>\n <div className=\"rte-ai-panel-v2__selection-box\">\n {selectedText ? (\n <span>{selectedText.length > 300 ? selectedText.slice(0, 300) + '...' : selectedText}</span>\n ) : (\n <span className=\"rte-ai-panel-v2__empty\">{labels.aiInsertHint}</span>\n )}\n </div>\n </div>\n\n {/* Quick actions */}\n <div className=\"rte-ai-panel-v2__quick-actions\">\n {QUICK_ACTIONS.map(({ key, labelKey, icon }) => (\n <button\n key={key}\n type=\"button\"\n className=\"rte-ai-panel-v2__quick-btn\"\n onClick={() => handleGenerate(key)}\n disabled={isProcessing || !editable || invalid || !selectedText.trim()}\n title={selectedText ? labels[labelKey] : labels.aiInsertHint}\n >\n <span>{icon}</span>\n <span>{labels[labelKey]}</span>\n </button>\n ))}\n </div>\n\n {/* Generate button */}\n <div className=\"rte-ai-panel-v2__actions\">\n <button\n type=\"button\"\n className=\"rte-ai-panel-v2__generate-btn\"\n onClick={() => handleGenerate()}\n disabled={isProcessing || !editable || invalid || (!prompt.trim() && !selectedText.trim())}\n >\n {isProcessing ? labels.aiProcessing : `✨ ${labels.aiGenerate}`}\n </button>\n {isProcessing && (\n <button type=\"button\" className=\"rte-ai-panel-v2__cancel-btn\" onClick={handleReject}>\n {labels.aiCancel}\n </button>\n )}\n </div>\n\n {/* Streaming result */}\n {isProcessing && !streamedText && (\n <LoadingState\n className=\"rte-ai-panel-v2__loading\"\n label={labels.aiProcessing}\n variant=\"dots\"\n layout=\"block\"\n size=\"sm\"\n />\n )}\n {streamedText && (\n <div className=\"rte-ai-panel-v2__result\">\n <div className=\"rte-ai-panel-v2__result-header\">\n <span className=\"rte-ai-panel-v2__label\">{labels.aiResult}</span>\n <span className={`rte-ai-panel-v2__stream-status ${isProcessing ? 'rte-ai-panel-v2__stream-status--live' : ''}`} role=\"status\">\n <span className=\"rte-ai-panel-v2__stream-dot\" aria-hidden=\"true\" />\n {isProcessing ? labels.aiProcessing : `${streamedText.length} chars`}\n </span>\n </div>\n <div className=\"rte-ai-panel-v2__result-text\">\n <StreamingText text={streamedText} streaming={isProcessing} />\n </div>\n <div className=\"rte-ai-panel-v2__result-actions\">\n <button type=\"button\" className=\"rte-ai-panel-v2__accept-btn\" disabled={isProcessing || !editable || invalid} onClick={handleAccept}>\n {labels.aiAccept}\n </button>\n <button type=\"button\" className=\"rte-ai-panel-v2__reject-btn\" onClick={handleReject}>\n {labels.aiReject}\n </button>\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div className=\"rte-ai-panel-v2__error\">\n <span>{error}</span>\n <button type=\"button\" onClick={() => setError(null)}>{labels.aiDismiss}</button>\n </div>\n )}\n </div>\n );\n};\n\nexport default AIRewrite;\n"],"mappings":"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"}
1
+ {"version":3,"file":"AIRewrite.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/AIRewrite.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect, useId } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { AIConfig, AIAction, RichTextEditorLabels } from './types';\nimport { defaultLabels } from './types';\nimport StreamingText from '../../ai/StreamingText';\nimport LoadingState from '../../ai/LoadingState';\n\ninterface AIRewriteProps {\n editor: Editor;\n aiConfig: AIConfig;\n labels?: RichTextEditorLabels;\n initialSelection: string;\n selectionRange: { from: number; to: number };\n followSelection?: boolean;\n onClose: () => void;\n}\n\nconst QUICK_ACTIONS: { key: AIAction; labelKey: keyof RichTextEditorLabels; icon: string }[] = [\n { key: 'rewrite', labelKey: 'aiRewrite', icon: '✏' },\n { key: 'shorten', labelKey: 'aiShorten', icon: '📝' },\n { key: 'expand', labelKey: 'aiExpand', icon: '📄' },\n { key: 'fix_grammar', labelKey: 'aiFixGrammar', icon: '✓' },\n { key: 'translate_en', labelKey: 'aiTranslateEn', icon: 'EN' },\n { key: 'translate_zh', labelKey: 'aiTranslateZh', icon: '中' },\n { key: 'professional', labelKey: 'aiProfessional', icon: '💼' },\n { key: 'casual', labelKey: 'aiCasual', icon: '💬' },\n];\n\nfunction getSystemPrompt(action: AIAction | 'custom', customPrompt?: string): string {\n if (action === 'custom') return customPrompt || 'Follow the user instructions.';\n const prompts: Record<AIAction, string> = {\n rewrite: 'Rewrite the following text to improve clarity and readability. Keep the same meaning and tone. Return only the rewritten text.',\n shorten: 'Shorten the following text while preserving its key meaning. Be concise. Return only the shortened text.',\n expand: 'Expand the following text with more details and examples while keeping the same tone. Return only the expanded text.',\n fix_grammar: 'Fix any grammar, spelling, and punctuation errors in the following text. Return only the corrected text.',\n translate_en: 'Translate the following text to English. Return only the translated text.',\n translate_zh: 'Translate the following text to Chinese. Return only the translated text.',\n professional: 'Rewrite the following text in a professional, formal tone. Return only the rewritten text.',\n casual: 'Rewrite the following text in a casual, friendly tone. Return only the rewritten text.',\n };\n return customPrompt || prompts[action];\n}\n\nasync function* readSSE(response: Response): AsyncGenerator<string> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No response body');\n const decoder = new TextDecoder();\n let buffer = '';\n let data: string[] = [];\n try {\n while (true) {\n const { done, value } = await reader.read();\n buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });\n // Normalize CRLF only when the complete line is available (chunks may split it).\n let newline: number;\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).replace(/\\r$/, '');\n buffer = buffer.slice(newline + 1);\n if (!line) {\n if (data.length) yield data.join('\\n');\n data = [];\n } else if (line.startsWith('data:')) {\n data.push(line.slice(5).replace(/^ /, ''));\n }\n }\n if (done) {\n if (buffer.startsWith('data:')) data.push(buffer.slice(5).replace(/^ /, '').replace(/\\r$/, ''));\n if (data.length) yield data.join('\\n');\n return;\n }\n }\n } finally {\n try { await reader.cancel(); } catch { /* The request may already be aborted. */ }\n reader.releaseLock();\n }\n}\n\nasync function* streamOpenAI(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n if (!config.gateway || !config.model) throw new Error('OpenAI protocol requires gateway and model');\n const body = JSON.stringify({\n model: config.model,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: text },\n ],\n stream: true,\n });\n\n const response = await fetch(config.gateway, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}),\n ...config.headers,\n },\n body,\n signal,\n });\n\n if (!response.ok) throw new Error(`AI API error: ${response.status} ${response.statusText}`);\n for await (const payload of readSSE(response)) {\n if (payload.trim() === '[DONE]') return;\n let data;\n try { data = JSON.parse(payload); } catch { continue; }\n if (data?.error) throw new Error(data.error.message || 'AI stream error');\n const content = data?.choices?.[0]?.delta?.content;\n if (typeof content === 'string') yield content;\n }\n}\n\nasync function* streamAnthropic(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n if (!config.gateway || !config.model) throw new Error('Anthropic protocol requires gateway and model');\n const body = JSON.stringify({\n model: config.model,\n max_tokens: 4096,\n system: systemPrompt,\n messages: [{ role: 'user', content: text }],\n stream: true,\n });\n\n const response = await fetch(config.gateway, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { 'x-api-key': config.apiKey } : {}),\n 'anthropic-version': '2023-06-01',\n ...config.headers,\n },\n body,\n signal,\n });\n\n if (!response.ok) throw new Error(`AI API error: ${response.status} ${response.statusText}`);\n for await (const payload of readSSE(response)) {\n let data;\n try { data = JSON.parse(payload); } catch { continue; }\n if (data?.type === 'error') throw new Error(data.error?.message || 'AI stream error');\n if (data?.type === 'message_stop') return;\n if (data?.type === 'content_block_delta' && typeof data.delta?.text === 'string') yield data.delta.text;\n }\n}\n\nfunction getStream(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n action: AIAction | 'custom',\n signal: AbortSignal,\n request?: { prompt: string; selectedText: string; mode: 'replace' | 'insert' },\n): AsyncIterable<string> {\n if (config.protocol === 'custom') {\n if (!config.customHandler) throw new Error('Custom AI protocol requires customHandler');\n return config.customHandler({\n text,\n action: action === 'custom' ? 'rewrite' : action,\n systemPrompt,\n signal,\n prompt: request?.prompt ?? '',\n selectedText: request?.selectedText ?? text,\n mode: request?.mode ?? 'replace',\n });\n }\n if (config.protocol === 'anthropic') return streamAnthropic(config, text, systemPrompt, signal);\n return streamOpenAI(config, text, systemPrompt, signal);\n}\n\nconst AIRewrite: React.FC<AIRewriteProps> = ({ editor, aiConfig, labels: propsLabels, initialSelection, selectionRange, followSelection = false, onClose }) => {\n const labels = { ...defaultLabels, ...propsLabels };\n const promptId = useId();\n const [prompt, setPrompt] = useState('');\n const [isProcessing, setIsProcessing] = useState(false);\n const [streamedText, setStreamedText] = useState('');\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const promptRef = useRef<HTMLTextAreaElement>(null);\n const [editable, setEditable] = useState(() => !editor.isDestroyed && editor.isEditable);\n const [invalid, setInvalid] = useState(false);\n const sourceDoc = useRef(editor.state.doc);\n const invalidRef = useRef(false);\n const [selectionSnapshot, setSelectionSnapshot] = useState(() => ({ from: selectionRange.from, to: selectionRange.to, text: initialSelection }));\n const snapshotRef = useRef(selectionSnapshot);\n\n const cancelRequest = useCallback(() => {\n const request = abortRef.current;\n abortRef.current = null;\n request?.abort();\n }, []);\n\n useEffect(() => {\n snapshotRef.current = { from: selectionRange.from, to: selectionRange.to, text: initialSelection };\n setSelectionSnapshot(snapshotRef.current);\n }, [initialSelection, selectionRange.from, selectionRange.to]);\n\n useEffect(() => {\n sourceDoc.current = editor.state.doc;\n invalidRef.current = false;\n setInvalid(false);\n setStreamedText('');\n setIsProcessing(false);\n setError(null);\n const invalidate = () => {\n setEditable(!editor.isDestroyed && editor.isEditable);\n if (editor.isDestroyed || !editor.isEditable || editor.state.doc !== sourceDoc.current) {\n invalidRef.current = true;\n setInvalid(true);\n cancelRequest();\n setIsProcessing(false);\n setStreamedText('');\n setError('The document or editing permissions changed. Close and reopen AI Assistant.');\n }\n };\n const onSelection = () => {\n if (!followSelection || editor.isDestroyed || !editor.isEditable || editor.state.doc !== sourceDoc.current || invalidRef.current) return;\n const { from, to } = editor.state.selection;\n const previous = snapshotRef.current;\n // Ignore collapsed selections caused by focusing the AI prompt or toolbar.\n if (from === to || (from === previous.from && to === previous.to)) return;\n const next = { from, to, text: editor.state.doc.textBetween(from, to, ' ') };\n snapshotRef.current = next;\n setSelectionSnapshot(next);\n cancelRequest();\n setIsProcessing(false);\n setStreamedText('');\n setError(null);\n };\n invalidate();\n editor.on('update', invalidate);\n editor.on('transaction', invalidate);\n editor.on('selectionUpdate', onSelection);\n editor.on('destroy', invalidate);\n return () => {\n cancelRequest();\n editor.off('update', invalidate);\n editor.off('transaction', invalidate);\n editor.off('selectionUpdate', onSelection);\n editor.off('destroy', invalidate);\n };\n }, [editor, cancelRequest, followSelection]);\n\n const selectedText = selectionSnapshot.text;\n\n useEffect(() => {\n if (promptRef.current) promptRef.current.focus();\n }, []);\n\n const handleGenerate = useCallback(async (action: AIAction | 'custom' = 'custom', customPromptOverride?: string) => {\n if (editor.isDestroyed || !editor.isEditable || invalidRef.current || abortRef.current) return;\n const mode = selectedText ? 'replace' : 'insert';\n if (mode === 'insert' && !prompt.trim()) return;\n\n const actionPrompt = action === 'custom'\n ? (mode === 'replace'\n ? 'Edit the selected text according to the user instruction. Return only the replacement text.'\n : 'Generate text according to the user instruction. Return only the text to insert.')\n : getSystemPrompt(action, customPromptOverride);\n const systemPrompt = [aiConfig.systemPrompt, actionPrompt].filter(Boolean).join('\\n\\n');\n const userText = mode === 'replace'\n ? (prompt.trim()\n ? `Instruction:\\n${prompt.trim()}\\n\\nSelected text:\\n${selectedText}`\n : selectedText)\n : prompt.trim();\n\n setIsProcessing(true);\n setStreamedText('');\n setError(null);\n\n const abort = new AbortController();\n abortRef.current = abort;\n\n try {\n let result = '';\n for await (const chunk of getStream(aiConfig, userText, systemPrompt, action, abort.signal, {\n prompt: prompt.trim(),\n selectedText,\n mode,\n })) {\n if (abort.signal.aborted || abortRef.current !== abort) break;\n result += chunk;\n setStreamedText(result);\n }\n } catch (err: unknown) {\n if (abort.signal.aborted || abortRef.current !== abort) return;\n setStreamedText('');\n setError(String(err instanceof Error ? err.message : err));\n } finally {\n if (abortRef.current === abort) {\n abortRef.current = null;\n setIsProcessing(false);\n }\n }\n }, [editor, aiConfig, selectedText, prompt]);\n\n const handleAccept = useCallback(() => {\n if (!streamedText || abortRef.current || editor.isDestroyed || !editor.isEditable || invalidRef.current) return;\n const { from, to } = snapshotRef.current;\n if (editor.state.doc !== sourceDoc.current || !Number.isInteger(from) || !Number.isInteger(to) || from < 0 || to < from || to > editor.state.doc.content.size) {\n setError('The original selection is no longer valid. Close and reopen AI Assistant.');\n return;\n }\n // AI output is plain text, never HTML. Use the captured range even if the cursor moved.\n editor.view.dispatch(editor.state.tr.insertText(streamedText, from, to));\n setStreamedText('');\n setPrompt('');\n onClose();\n }, [editor, streamedText, onClose]);\n\n const handleReject = useCallback(() => {\n cancelRequest();\n setStreamedText('');\n setIsProcessing(false);\n setError(null);\n }, [cancelRequest]);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleGenerate();\n }\n }, [handleGenerate]);\n\n return (\n <div className=\"rte-ai-panel-v2\">\n <div className=\"rte-ai-panel-v2__header\">\n <span className=\"rte-ai-panel-v2__title\">✨ {labels.ai || 'AI Assistant'}</span>\n <button type=\"button\" className=\"rte-ai-panel-v2__close-btn\" onClick={() => { cancelRequest(); onClose(); }} title={labels.aiClose} aria-label={labels.aiClose}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n {/* Prompt input */}\n <div className=\"rte-ai-panel-v2__prompt-section\">\n <label className=\"rte-ai-panel-v2__label\" htmlFor={promptId}>{labels.aiPromptLabel}</label>\n <textarea\n id={promptId}\n ref={promptRef}\n className=\"rte-ai-panel-v2__prompt-input\"\n value={prompt}\n onChange={(e) => setPrompt(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={labels.aiPromptPlaceholder}\n rows={3}\n disabled={isProcessing || !editable || invalid}\n />\n </div>\n\n {/* Selected text display */}\n <div className=\"rte-ai-panel-v2__selection-section\">\n <span className=\"rte-ai-panel-v2__label\">{labels.aiSelectedText}</span>\n <div className=\"rte-ai-panel-v2__selection-box\">\n {selectedText ? (\n <span>{selectedText.length > 300 ? selectedText.slice(0, 300) + '...' : selectedText}</span>\n ) : (\n <span className=\"rte-ai-panel-v2__empty\">{labels.aiInsertHint}</span>\n )}\n </div>\n </div>\n\n {/* Quick actions */}\n <div className=\"rte-ai-panel-v2__quick-actions\">\n {QUICK_ACTIONS.map(({ key, labelKey, icon }) => (\n <button\n key={key}\n type=\"button\"\n className=\"rte-ai-panel-v2__quick-btn\"\n onClick={() => handleGenerate(key)}\n disabled={isProcessing || !editable || invalid || !selectedText.trim()}\n title={selectedText ? labels[labelKey] : labels.aiInsertHint}\n >\n <span>{icon}</span>\n <span>{labels[labelKey]}</span>\n </button>\n ))}\n </div>\n\n {/* Generate button */}\n <div className=\"rte-ai-panel-v2__actions\">\n <button\n type=\"button\"\n className=\"rte-ai-panel-v2__generate-btn\"\n onClick={() => handleGenerate()}\n disabled={isProcessing || !editable || invalid || (!prompt.trim() && !selectedText.trim())}\n >\n {isProcessing ? labels.aiProcessing : `✨ ${labels.aiGenerate}`}\n </button>\n {isProcessing && (\n <button type=\"button\" className=\"rte-ai-panel-v2__cancel-btn\" onClick={handleReject}>\n {labels.aiCancel}\n </button>\n )}\n </div>\n\n {/* Streaming result */}\n {isProcessing && !streamedText && (\n <LoadingState\n className=\"rte-ai-panel-v2__loading\"\n label={labels.aiProcessing}\n variant=\"dots\"\n layout=\"block\"\n size=\"sm\"\n />\n )}\n {streamedText && (\n <div className=\"rte-ai-panel-v2__result\">\n <div className=\"rte-ai-panel-v2__result-header\">\n <span className=\"rte-ai-panel-v2__label\">{labels.aiResult}</span>\n <span className={`rte-ai-panel-v2__stream-status ${isProcessing ? 'rte-ai-panel-v2__stream-status--live' : ''}`} role=\"status\">\n <span className=\"rte-ai-panel-v2__stream-dot\" aria-hidden=\"true\" />\n {isProcessing ? labels.aiProcessing : `${streamedText.length} chars`}\n </span>\n </div>\n <div className=\"rte-ai-panel-v2__result-text\">\n <StreamingText text={streamedText} streaming={isProcessing} />\n </div>\n <div className=\"rte-ai-panel-v2__result-actions\">\n <button type=\"button\" className=\"rte-ai-panel-v2__accept-btn\" disabled={isProcessing || !editable || invalid} onClick={handleAccept}>\n {labels.aiAccept}\n </button>\n <button type=\"button\" className=\"rte-ai-panel-v2__reject-btn\" onClick={handleReject}>\n {labels.aiReject}\n </button>\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div className=\"rte-ai-panel-v2__error\">\n <span>{error}</span>\n <button type=\"button\" onClick={() => setError(null)}>{labels.aiDismiss}</button>\n </div>\n )}\n </div>\n );\n};\n\nexport default AIRewrite;\n"],"mappings":"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"}
@@ -11,45 +11,45 @@ import i from "./SlashMenu.js";
11
11
  import a from "./BubbleToolbar.js";
12
12
  import o from "./BlockHandle.js";
13
13
  import { CodeBlockExtension as s } from "./extensions/CodeBlockView.js";
14
- import c from "./extensions/FontSize.js";
15
- import { ResizableImage as l } from "./extensions/ResizableImage.js";
16
- import { CommentMark as u } from "./extensions/CommentMark.js";
14
+ import ae from "./extensions/FontSize.js";
15
+ import { ResizableImage as c } from "./extensions/ResizableImage.js";
16
+ import { CommentMark as oe } from "./extensions/CommentMark.js";
17
17
  /* empty css */
18
- import { useCallback as d, useEffect as f, useRef as ae, useState as p } from "react";
19
- import { jsx as m, jsxs as h } from "react/jsx-runtime";
20
- import { EditorContent as oe, useEditor as se } from "@tiptap/react";
21
- import ce from "@tiptap/starter-kit";
22
- import le from "@tiptap/extension-underline";
23
- import { TextStyle as ue } from "@tiptap/extension-text-style";
24
- import de from "@tiptap/extension-color";
25
- import fe from "@tiptap/extension-highlight";
26
- import pe from "@tiptap/extension-text-align";
27
- import me from "@tiptap/extension-link";
28
- import { Table as he } from "@tiptap/extension-table";
29
- import g from "@tiptap/extension-table-row";
30
- import _ from "@tiptap/extension-table-cell";
31
- import v from "@tiptap/extension-table-header";
32
- import y from "@tiptap/extension-placeholder";
33
- import b from "@tiptap/extension-task-list";
34
- import x from "@tiptap/extension-task-item";
35
- import S from "@tiptap/extension-subscript";
36
- import C from "@tiptap/extension-superscript";
37
- import w from "@tiptap/extension-typography";
38
- import T from "@tiptap/extension-font-family";
18
+ import { useCallback as l, useEffect as u, useRef as se, useState as d } from "react";
19
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
20
+ import { EditorContent as ce, useEditor as le } from "@tiptap/react";
21
+ import m from "@tiptap/starter-kit";
22
+ import h from "@tiptap/extension-underline";
23
+ import { TextStyle as g } from "@tiptap/extension-text-style";
24
+ import ue from "@tiptap/extension-color";
25
+ import de from "@tiptap/extension-highlight";
26
+ import fe from "@tiptap/extension-text-align";
27
+ import pe from "@tiptap/extension-link";
28
+ import { Table as me } from "@tiptap/extension-table";
29
+ import _ from "@tiptap/extension-table-row";
30
+ import v from "@tiptap/extension-table-cell";
31
+ import y from "@tiptap/extension-table-header";
32
+ import b from "@tiptap/extension-placeholder";
33
+ import x from "@tiptap/extension-task-list";
34
+ import S from "@tiptap/extension-task-item";
35
+ import C from "@tiptap/extension-subscript";
36
+ import w from "@tiptap/extension-superscript";
37
+ import T from "@tiptap/extension-typography";
38
+ import E from "@tiptap/extension-font-family";
39
39
  //#region src/components/pro/RichTextEditor/RichTextEditor.tsx
40
- function E() {
40
+ function D() {
41
41
  return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
42
42
  }
43
- var D = ({ content: D, value: O, onChange: k, onChangeJSON: A, placeholder: j = "Start writing...", editable: M = !0, aiConfig: N, onRequestAIConfig: P, toolbarConfig: F, minHeight: I = "200px", maxHeight: L, className: R = "", autofocus: ge = !1, labels: z, editorRef: B, showComments: _e = !1, commentThreads: ve, onCommentThreadsChange: ye, currentUser: V }) => {
44
- let [be, xe] = p(!1), [Se, H] = p(!1), [Ce, we] = p(""), [Te, Ee] = p({
43
+ var O = ({ content: O, value: k, onChange: A, onChangeJSON: j, placeholder: M = "Start writing...", editable: N = !0, aiConfig: P, onRequestAIConfig: F, toolbarConfig: I, aiSelectionFollowsEditor: L = !1, minHeight: R = "200px", maxHeight: z, className: he = "", autofocus: ge = !1, labels: B, editorRef: V, showComments: _e = !1, commentThreads: ve, onCommentThreadsChange: ye, currentUser: H }) => {
44
+ let [be, xe] = d(!1), [Se, U] = d(!1), [Ce, we] = d(""), [Te, Ee] = d({
45
45
  from: 0,
46
46
  to: 0
47
- }), [U, W] = p(_e), [De, Oe] = p([]), [ke, G] = p(!1), [K, Ae] = p({
47
+ }), [W, G] = d(_e), [De, Oe] = d([]), [ke, K] = d(!1), [q, Ae] = d({
48
48
  from: 0,
49
49
  to: 0
50
- }), q = ae(null), J = ve ?? De, Y = ye ?? Oe, X = se({
50
+ }), J = se(null), Y = ve ?? De, X = ye ?? Oe, Z = le({
51
51
  extensions: [
52
- ce.configure({
52
+ m.configure({
53
53
  codeBlock: !1,
54
54
  heading: { levels: [
55
55
  1,
@@ -62,97 +62,97 @@ var D = ({ content: D, value: O, onChange: k, onChangeJSON: A, placeholder: j =
62
62
  link: !1,
63
63
  underline: !1
64
64
  }),
65
- le,
65
+ h,
66
+ g,
66
67
  ue,
67
- de,
68
- fe.configure({ multicolor: !0 }),
69
- pe.configure({ types: ["heading", "paragraph"] }),
70
- me.configure({
68
+ de.configure({ multicolor: !0 }),
69
+ fe.configure({ types: ["heading", "paragraph"] }),
70
+ pe.configure({
71
71
  openOnClick: !1,
72
72
  autolink: !0,
73
73
  HTMLAttributes: { class: "rte-link" }
74
74
  }),
75
- l.configure({
75
+ c.configure({
76
76
  inline: !1,
77
77
  allowBase64: !0
78
78
  }),
79
- he.configure({ resizable: !0 }),
80
- g,
79
+ me.configure({ resizable: !0 }),
81
80
  _,
82
81
  v,
83
- y.configure({ placeholder: j }),
82
+ y,
83
+ b.configure({ placeholder: M }),
84
84
  s,
85
- b,
86
- x.configure({ nested: !0 }),
87
- S,
85
+ x,
86
+ S.configure({ nested: !0 }),
88
87
  C,
89
88
  w,
90
89
  T,
91
- c,
90
+ E,
91
+ ae,
92
92
  n,
93
93
  t,
94
- u
94
+ oe
95
95
  ],
96
- content: O || D || "",
97
- editable: M,
96
+ content: k || O || "",
97
+ editable: N,
98
98
  autofocus: ge ? "end" : !1,
99
99
  onUpdate: ({ editor: e }) => {
100
- k?.(e.getHTML()), A?.(e.getJSON());
100
+ A?.(e.getHTML()), j?.(e.getJSON());
101
101
  }
102
102
  });
103
- f(() => {
104
- B && X && (B.current = X);
105
- }, [X, B]), f(() => {
106
- X && O !== void 0 && O !== X.getHTML() && X.commands.setContent(O, { emitUpdate: !1 });
107
- }, [X, O]), f(() => {
108
- X && X.setEditable(M);
109
- }, [X, M]);
110
- let Z = d(() => {
111
- if (!X) return;
112
- let { from: e, to: t } = X.state.selection, n = e === t ? "" : X.state.doc.textBetween(e, t, " ");
103
+ u(() => {
104
+ V && Z && (V.current = Z);
105
+ }, [Z, V]), u(() => {
106
+ Z && k !== void 0 && k !== Z.getHTML() && Z.commands.setContent(k, { emitUpdate: !1 });
107
+ }, [Z, k]), u(() => {
108
+ Z && Z.setEditable(N);
109
+ }, [Z, N]);
110
+ let Q = l(() => {
111
+ if (!Z) return;
112
+ let { from: e, to: t } = Z.state.selection, n = e === t ? "" : Z.state.doc.textBetween(e, t, " ");
113
113
  we(n), Ee({
114
114
  from: e,
115
115
  to: t
116
- }), H(!0);
117
- }, [X]), Q = d(() => {
118
- if (!X) return;
119
- let { from: e, to: t } = X.state.selection;
116
+ }), U(!0);
117
+ }, [Z]), $ = l(() => {
118
+ if (!Z) return;
119
+ let { from: e, to: t } = Z.state.selection;
120
120
  e !== t && (Ae({
121
121
  from: e,
122
122
  to: t
123
- }), G(!0));
124
- }, [X]), $ = d((e) => {
125
- if (!X) return;
126
- let t = E(), n = {
123
+ }), K(!0));
124
+ }, [Z]), je = l((e) => {
125
+ if (!Z) return;
126
+ let t = D(), n = {
127
127
  id: t,
128
128
  resolved: !1,
129
129
  comments: [{
130
- id: E(),
131
- author: V || "User",
130
+ id: D(),
131
+ author: H || "User",
132
132
  text: e,
133
133
  createdAt: Date.now()
134
134
  }],
135
135
  createdAt: Date.now()
136
136
  };
137
- X.chain().focus().setTextSelection(K).setComment(t).run(), Y([...J, n]), G(!1);
137
+ Z.chain().focus().setTextSelection(q).setComment(t).run(), X([...Y, n]), K(!1);
138
138
  }, [
139
- X,
140
- K,
141
- J,
139
+ Z,
140
+ q,
142
141
  Y,
143
- V
144
- ]), je = d((e) => {
145
- q.current?.scrollToThread(e);
142
+ X,
143
+ H
144
+ ]), Me = l((e) => {
145
+ J.current?.scrollToThread(e);
146
146
  }, []);
147
- if (!X) return null;
148
- let Me = typeof I == "number" ? `${I}px` : I, Ne = L ? typeof L == "number" ? `${L}px` : L : void 0, Pe = e("rte-container", be && "rte-container--format-painter", R), Fe = J.filter((e) => !e.resolved).length, Ie = F?.buttons?.comments ?? !0 ? /* @__PURE__ */ m("div", {
147
+ if (!Z) return null;
148
+ let Ne = typeof R == "number" ? `${R}px` : R, Pe = z ? typeof z == "number" ? `${z}px` : z : void 0, Fe = e("rte-container", be && "rte-container--format-painter", he), Ie = Y.filter((e) => !e.resolved).length, Le = I?.buttons?.comments ?? !0 ? /* @__PURE__ */ f("div", {
149
149
  className: "rte-toolbar__end",
150
- children: /* @__PURE__ */ h("button", {
150
+ children: /* @__PURE__ */ p("button", {
151
151
  type: "button",
152
- className: `rte-toolbar__btn rte-toolbar__comment-btn ${U ? "rte-toolbar__btn--active" : ""}`,
153
- onClick: () => W(!U),
152
+ className: `rte-toolbar__btn rte-toolbar__comment-btn ${W ? "rte-toolbar__btn--active" : ""}`,
153
+ onClick: () => G(!W),
154
154
  title: "Toggle comments",
155
- children: [/* @__PURE__ */ m("svg", {
155
+ children: [/* @__PURE__ */ f("svg", {
156
156
  width: "16",
157
157
  height: "16",
158
158
  viewBox: "0 0 24 24",
@@ -161,91 +161,92 @@ var D = ({ content: D, value: O, onChange: k, onChangeJSON: A, placeholder: j =
161
161
  strokeWidth: "2",
162
162
  strokeLinecap: "round",
163
163
  strokeLinejoin: "round",
164
- children: /* @__PURE__ */ m("path", { d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" })
165
- }), Fe > 0 && /* @__PURE__ */ m("span", { className: "rte-toolbar__comment-badge" })]
164
+ children: /* @__PURE__ */ f("path", { d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" })
165
+ }), Ie > 0 && /* @__PURE__ */ f("span", { className: "rte-toolbar__comment-badge" })]
166
166
  })
167
167
  }) : null;
168
- return /* @__PURE__ */ h("div", {
169
- className: Pe,
168
+ return /* @__PURE__ */ p("div", {
169
+ className: Fe,
170
170
  style: {
171
- minHeight: Me,
172
- maxHeight: Ne
171
+ minHeight: Ne,
172
+ maxHeight: Pe
173
173
  },
174
174
  children: [
175
- M && /* @__PURE__ */ m(ee, {
176
- editor: X,
177
- config: F,
178
- labels: z,
179
- hasAI: !!N,
180
- onAIClick: Z,
181
- onRequestAIConfig: P,
175
+ N && /* @__PURE__ */ f(ee, {
176
+ editor: Z,
177
+ config: I,
178
+ labels: B,
179
+ hasAI: !!P,
180
+ onAIClick: Q,
181
+ onRequestAIConfig: F,
182
182
  onFormatPainterChange: xe,
183
- children: Ie
183
+ children: Le
184
184
  }),
185
- /* @__PURE__ */ h("div", {
185
+ /* @__PURE__ */ p("div", {
186
186
  style: {
187
187
  display: "flex",
188
188
  flex: 1,
189
189
  overflow: "hidden"
190
190
  },
191
- children: [/* @__PURE__ */ h("div", {
191
+ children: [/* @__PURE__ */ p("div", {
192
192
  className: "rte-editor-wrapper",
193
193
  style: { flex: 1 },
194
194
  children: [
195
- /* @__PURE__ */ m(oe, {
196
- editor: X,
195
+ /* @__PURE__ */ f(ce, {
196
+ editor: Z,
197
197
  className: "rte-editor-content"
198
198
  }),
199
- M && /* @__PURE__ */ m(ne, {
200
- editor: X,
201
- labels: z,
202
- onAIClick: N ? Z : void 0
199
+ N && /* @__PURE__ */ f(ne, {
200
+ editor: Z,
201
+ labels: B,
202
+ onAIClick: P ? Q : void 0
203
203
  }),
204
- M && /* @__PURE__ */ m(i, { editor: X }),
205
- M && /* @__PURE__ */ m(a, {
206
- editor: X,
207
- onAddComment: Q
204
+ N && /* @__PURE__ */ f(i, { editor: Z }),
205
+ N && /* @__PURE__ */ f(a, {
206
+ editor: Z,
207
+ onAddComment: $
208
208
  }),
209
- M && /* @__PURE__ */ m(o, {
210
- editor: X,
209
+ N && /* @__PURE__ */ f(o, {
210
+ editor: Z,
211
211
  persistent: !0
212
212
  }),
213
- /* @__PURE__ */ m(r, {
214
- editor: X,
215
- threads: J,
216
- onThreadsChange: Y,
217
- showPanel: U,
218
- onOpenPanel: () => W(!0),
219
- onScrollToThread: je,
220
- currentUser: V
213
+ /* @__PURE__ */ f(r, {
214
+ editor: Z,
215
+ threads: Y,
216
+ onThreadsChange: X,
217
+ showPanel: W,
218
+ onOpenPanel: () => G(!0),
219
+ onScrollToThread: Me,
220
+ currentUser: H
221
221
  })
222
222
  ]
223
- }), U && /* @__PURE__ */ m(re, {
224
- ref: q,
225
- editor: X,
226
- threads: J,
227
- onThreadsChange: Y,
228
- onRequestAddComment: Q,
229
- currentUser: V
223
+ }), W && /* @__PURE__ */ f(re, {
224
+ ref: J,
225
+ editor: Z,
226
+ threads: Y,
227
+ onThreadsChange: X,
228
+ onRequestAddComment: $,
229
+ currentUser: H
230
230
  })]
231
231
  }),
232
- N && Se && /* @__PURE__ */ m(te, {
233
- editor: X,
234
- aiConfig: N,
235
- labels: z,
232
+ P && Se && /* @__PURE__ */ f(te, {
233
+ editor: Z,
234
+ aiConfig: P,
235
+ labels: B,
236
236
  initialSelection: Ce,
237
237
  selectionRange: Te,
238
- onClose: () => H(!1)
238
+ followSelection: L,
239
+ onClose: () => U(!1)
239
240
  }),
240
- /* @__PURE__ */ m(ie, {
241
+ /* @__PURE__ */ f(ie, {
241
242
  open: ke,
242
- onSubmit: $,
243
- onClose: () => G(!1)
243
+ onSubmit: je,
244
+ onClose: () => K(!1)
244
245
  })
245
246
  ]
246
247
  });
247
248
  };
248
249
  //#endregion
249
- export { D as default };
250
+ export { O as default };
250
251
 
251
252
  //# sourceMappingURL=RichTextEditor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RichTextEditor.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/RichTextEditor.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useState, useRef } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Color from '@tiptap/extension-color';\nimport Highlight from '@tiptap/extension-highlight';\nimport TextAlign from '@tiptap/extension-text-align';\nimport Link from '@tiptap/extension-link';\nimport { Table } from '@tiptap/extension-table';\nimport TableRow from '@tiptap/extension-table-row';\nimport TableCell from '@tiptap/extension-table-cell';\nimport TableHeader from '@tiptap/extension-table-header';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport TaskList from '@tiptap/extension-task-list';\nimport TaskItem from '@tiptap/extension-task-item';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport Typography from '@tiptap/extension-typography';\nimport FontFamily from '@tiptap/extension-font-family';\n\nimport Toolbar from './Toolbar';\nimport AIRewrite from './AIRewrite';\nimport ContextMenu from './ContextMenu';\nimport CommentPanel from './CommentPanel';\nimport type { CommentPanelHandle } from './CommentPanel';\nimport CommentDialog from './CommentDialog';\nimport CommentPopover from './CommentPopover';\nimport SlashMenu from './SlashMenu';\nimport BubbleToolbar from './BubbleToolbar';\nimport BlockHandle from './BlockHandle';\nimport { MarkdownBlockExtension } from './extensions/MarkdownBlock';\nimport { CodeBlockExtension } from './extensions/CodeBlockView';\nimport FontSize from './extensions/FontSize';\nimport { ResizableImage } from './extensions/ResizableImage';\nimport { FloatingDialogExtension } from './extensions/FloatingDialog';\nimport { CommentMark } from './extensions/CommentMark';\nimport type { CommentThread } from './extensions/CommentMark';\nimport type { RichTextEditorProps } from './types';\nimport './styles.css';\n\nfunction generateId() {\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nconst RichTextEditor: React.FC<RichTextEditorProps> = ({\n content,\n value,\n onChange,\n onChangeJSON,\n placeholder = 'Start writing...',\n editable = true,\n aiConfig,\n onRequestAIConfig,\n toolbarConfig,\n minHeight = '200px',\n maxHeight,\n className = '',\n autofocus = false,\n labels,\n editorRef,\n showComments: initialShowComments = false,\n commentThreads: externalThreads,\n onCommentThreadsChange,\n currentUser,\n}) => {\n const [formatPainterActive, setFormatPainterActive] = useState(false);\n const [showAIPanel, setShowAIPanel] = useState(false);\n const [aiSelection, setAiSelection] = useState('');\n const [aiSelectionRange, setAiSelectionRange] = useState({ from: 0, to: 0 });\n const [showComments, setShowComments] = useState(initialShowComments);\n const [internalThreads, setInternalThreads] = useState<CommentThread[]>([]);\n const [commentDialogOpen, setCommentDialogOpen] = useState(false);\n const [commentSelectionRange, setCommentSelectionRange] = useState({ from: 0, to: 0 });\n const commentPanelRef = useRef<CommentPanelHandle>(null);\n\n const threads = externalThreads ?? internalThreads;\n const setThreads = onCommentThreadsChange ?? setInternalThreads;\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n codeBlock: false,\n heading: { levels: [1, 2, 3, 4, 5, 6] },\n // v3 StarterKit bundles these; explicit extensions below stay in charge.\n link: false,\n underline: false,\n }),\n Underline,\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n Link.configure({\n openOnClick: false,\n autolink: true,\n HTMLAttributes: { class: 'rte-link' },\n }),\n ResizableImage.configure({ inline: false, allowBase64: true }),\n Table.configure({ resizable: true }),\n TableRow,\n TableCell,\n TableHeader,\n Placeholder.configure({ placeholder }),\n CodeBlockExtension,\n TaskList,\n TaskItem.configure({ nested: true }),\n Subscript,\n Superscript,\n Typography,\n FontFamily,\n FontSize,\n FloatingDialogExtension,\n MarkdownBlockExtension,\n CommentMark,\n ],\n content: value || content || '',\n editable,\n autofocus: autofocus ? 'end' : false,\n onUpdate: ({ editor: e }) => {\n onChange?.(e.getHTML());\n onChangeJSON?.(e.getJSON() as Record<string, unknown>);\n },\n });\n\n useEffect(() => {\n if (editorRef && editor) {\n editorRef.current = editor;\n }\n }, [editor, editorRef]);\n\n useEffect(() => {\n if (editor && value !== undefined) {\n const currentHTML = editor.getHTML();\n if (value !== currentHTML) {\n editor.commands.setContent(value, { emitUpdate: false });\n }\n }\n }, [editor, value]);\n\n useEffect(() => {\n if (editor) {\n editor.setEditable(editable);\n }\n }, [editor, editable]);\n\n const handleAIClick = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n const text = from !== to\n ? editor.state.doc.textBetween(from, to, ' ')\n : '';\n setAiSelection(text);\n setAiSelectionRange({ from, to });\n setShowAIPanel(true);\n }, [editor]);\n\n const requestAddComment = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n setCommentSelectionRange({ from, to });\n setCommentDialogOpen(true);\n }, [editor]);\n\n const handleCommentSubmit = useCallback((text: string) => {\n if (!editor) return;\n const id = generateId();\n const thread: CommentThread = {\n id,\n resolved: false,\n comments: [{\n id: generateId(),\n author: currentUser || 'User',\n text,\n createdAt: Date.now(),\n }],\n createdAt: Date.now(),\n };\n editor.chain()\n .focus()\n .setTextSelection(commentSelectionRange)\n .setComment(id)\n .run();\n setThreads([...threads, thread]);\n setCommentDialogOpen(false);\n }, [editor, commentSelectionRange, threads, setThreads, currentUser]);\n\n const handleScrollToThread = useCallback((id: string) => {\n commentPanelRef.current?.scrollToThread(id);\n }, []);\n\n if (!editor) return null;\n\n const minH = typeof minHeight === 'number' ? `${minHeight}px` : minHeight;\n const maxH = maxHeight ? (typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight) : undefined;\n\n const containerClass = cn(\n 'rte-container',\n formatPainterActive && 'rte-container--format-painter',\n className,\n );\n\n const activeCommentCount = threads.filter((t) => !t.resolved).length;\n\n const showCommentButton = toolbarConfig?.buttons?.comments ?? true;\n const toolbarEnd = showCommentButton ? (\n <div className=\"rte-toolbar__end\">\n <button\n type=\"button\"\n className={`rte-toolbar__btn rte-toolbar__comment-btn ${showComments ? 'rte-toolbar__btn--active' : ''}`}\n onClick={() => setShowComments(!showComments)}\n title=\"Toggle comments\"\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=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" />\n </svg>\n {activeCommentCount > 0 && <span className=\"rte-toolbar__comment-badge\" />}\n </button>\n </div>\n ) : null;\n\n return (\n <div className={containerClass} style={{ minHeight: minH, maxHeight: maxH }}>\n {editable && (\n <Toolbar\n editor={editor}\n config={toolbarConfig}\n labels={labels}\n hasAI={!!aiConfig}\n onAIClick={handleAIClick}\n onRequestAIConfig={onRequestAIConfig}\n onFormatPainterChange={setFormatPainterActive}\n >\n {toolbarEnd}\n </Toolbar>\n )}\n\n\n <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>\n <div className=\"rte-editor-wrapper\" style={{ flex: 1 }}>\n <EditorContent editor={editor} className=\"rte-editor-content\" />\n {editable && <ContextMenu editor={editor} labels={labels} onAIClick={aiConfig ? handleAIClick : undefined} />}\n {editable && <SlashMenu editor={editor} />}\n {editable && <BubbleToolbar editor={editor} onAddComment={requestAddComment} />}\n {editable && <BlockHandle editor={editor} persistent />}\n <CommentPopover\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n showPanel={showComments}\n onOpenPanel={() => setShowComments(true)}\n onScrollToThread={handleScrollToThread}\n currentUser={currentUser}\n />\n </div>\n\n {showComments && (\n <CommentPanel\n ref={commentPanelRef}\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n onRequestAddComment={requestAddComment}\n currentUser={currentUser}\n />\n )}\n </div>\n\n {aiConfig && showAIPanel && (\n <AIRewrite\n editor={editor}\n aiConfig={aiConfig}\n labels={labels}\n initialSelection={aiSelection}\n selectionRange={aiSelectionRange}\n onClose={() => setShowAIPanel(false)}\n />\n )}\n\n <CommentDialog\n open={commentDialogOpen}\n onSubmit={handleCommentSubmit}\n onClose={() => setCommentDialogOpen(false)}\n />\n </div>\n );\n};\n\nexport default RichTextEditor;\n"],"mappings":"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"}
1
+ {"version":3,"file":"RichTextEditor.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/RichTextEditor.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useState, useRef } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Color from '@tiptap/extension-color';\nimport Highlight from '@tiptap/extension-highlight';\nimport TextAlign from '@tiptap/extension-text-align';\nimport Link from '@tiptap/extension-link';\nimport { Table } from '@tiptap/extension-table';\nimport TableRow from '@tiptap/extension-table-row';\nimport TableCell from '@tiptap/extension-table-cell';\nimport TableHeader from '@tiptap/extension-table-header';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport TaskList from '@tiptap/extension-task-list';\nimport TaskItem from '@tiptap/extension-task-item';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport Typography from '@tiptap/extension-typography';\nimport FontFamily from '@tiptap/extension-font-family';\n\nimport Toolbar from './Toolbar';\nimport AIRewrite from './AIRewrite';\nimport ContextMenu from './ContextMenu';\nimport CommentPanel from './CommentPanel';\nimport type { CommentPanelHandle } from './CommentPanel';\nimport CommentDialog from './CommentDialog';\nimport CommentPopover from './CommentPopover';\nimport SlashMenu from './SlashMenu';\nimport BubbleToolbar from './BubbleToolbar';\nimport BlockHandle from './BlockHandle';\nimport { MarkdownBlockExtension } from './extensions/MarkdownBlock';\nimport { CodeBlockExtension } from './extensions/CodeBlockView';\nimport FontSize from './extensions/FontSize';\nimport { ResizableImage } from './extensions/ResizableImage';\nimport { FloatingDialogExtension } from './extensions/FloatingDialog';\nimport { CommentMark } from './extensions/CommentMark';\nimport type { CommentThread } from './extensions/CommentMark';\nimport type { RichTextEditorProps } from './types';\nimport './styles.css';\n\nfunction generateId() {\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nconst RichTextEditor: React.FC<RichTextEditorProps> = ({\n content,\n value,\n onChange,\n onChangeJSON,\n placeholder = 'Start writing...',\n editable = true,\n aiConfig,\n onRequestAIConfig,\n toolbarConfig,\n aiSelectionFollowsEditor = false,\n minHeight = '200px',\n maxHeight,\n className = '',\n autofocus = false,\n labels,\n editorRef,\n showComments: initialShowComments = false,\n commentThreads: externalThreads,\n onCommentThreadsChange,\n currentUser,\n}) => {\n const [formatPainterActive, setFormatPainterActive] = useState(false);\n const [showAIPanel, setShowAIPanel] = useState(false);\n const [aiSelection, setAiSelection] = useState('');\n const [aiSelectionRange, setAiSelectionRange] = useState({ from: 0, to: 0 });\n const [showComments, setShowComments] = useState(initialShowComments);\n const [internalThreads, setInternalThreads] = useState<CommentThread[]>([]);\n const [commentDialogOpen, setCommentDialogOpen] = useState(false);\n const [commentSelectionRange, setCommentSelectionRange] = useState({ from: 0, to: 0 });\n const commentPanelRef = useRef<CommentPanelHandle>(null);\n\n const threads = externalThreads ?? internalThreads;\n const setThreads = onCommentThreadsChange ?? setInternalThreads;\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n codeBlock: false,\n heading: { levels: [1, 2, 3, 4, 5, 6] },\n // v3 StarterKit bundles these; explicit extensions below stay in charge.\n link: false,\n underline: false,\n }),\n Underline,\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n Link.configure({\n openOnClick: false,\n autolink: true,\n HTMLAttributes: { class: 'rte-link' },\n }),\n ResizableImage.configure({ inline: false, allowBase64: true }),\n Table.configure({ resizable: true }),\n TableRow,\n TableCell,\n TableHeader,\n Placeholder.configure({ placeholder }),\n CodeBlockExtension,\n TaskList,\n TaskItem.configure({ nested: true }),\n Subscript,\n Superscript,\n Typography,\n FontFamily,\n FontSize,\n FloatingDialogExtension,\n MarkdownBlockExtension,\n CommentMark,\n ],\n content: value || content || '',\n editable,\n autofocus: autofocus ? 'end' : false,\n onUpdate: ({ editor: e }) => {\n onChange?.(e.getHTML());\n onChangeJSON?.(e.getJSON() as Record<string, unknown>);\n },\n });\n\n useEffect(() => {\n if (editorRef && editor) {\n editorRef.current = editor;\n }\n }, [editor, editorRef]);\n\n useEffect(() => {\n if (editor && value !== undefined) {\n const currentHTML = editor.getHTML();\n if (value !== currentHTML) {\n editor.commands.setContent(value, { emitUpdate: false });\n }\n }\n }, [editor, value]);\n\n useEffect(() => {\n if (editor) {\n editor.setEditable(editable);\n }\n }, [editor, editable]);\n\n const handleAIClick = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n const text = from !== to\n ? editor.state.doc.textBetween(from, to, ' ')\n : '';\n setAiSelection(text);\n setAiSelectionRange({ from, to });\n setShowAIPanel(true);\n }, [editor]);\n\n const requestAddComment = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n setCommentSelectionRange({ from, to });\n setCommentDialogOpen(true);\n }, [editor]);\n\n const handleCommentSubmit = useCallback((text: string) => {\n if (!editor) return;\n const id = generateId();\n const thread: CommentThread = {\n id,\n resolved: false,\n comments: [{\n id: generateId(),\n author: currentUser || 'User',\n text,\n createdAt: Date.now(),\n }],\n createdAt: Date.now(),\n };\n editor.chain()\n .focus()\n .setTextSelection(commentSelectionRange)\n .setComment(id)\n .run();\n setThreads([...threads, thread]);\n setCommentDialogOpen(false);\n }, [editor, commentSelectionRange, threads, setThreads, currentUser]);\n\n const handleScrollToThread = useCallback((id: string) => {\n commentPanelRef.current?.scrollToThread(id);\n }, []);\n\n if (!editor) return null;\n\n const minH = typeof minHeight === 'number' ? `${minHeight}px` : minHeight;\n const maxH = maxHeight ? (typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight) : undefined;\n\n const containerClass = cn(\n 'rte-container',\n formatPainterActive && 'rte-container--format-painter',\n className,\n );\n\n const activeCommentCount = threads.filter((t) => !t.resolved).length;\n\n const showCommentButton = toolbarConfig?.buttons?.comments ?? true;\n const toolbarEnd = showCommentButton ? (\n <div className=\"rte-toolbar__end\">\n <button\n type=\"button\"\n className={`rte-toolbar__btn rte-toolbar__comment-btn ${showComments ? 'rte-toolbar__btn--active' : ''}`}\n onClick={() => setShowComments(!showComments)}\n title=\"Toggle comments\"\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=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" />\n </svg>\n {activeCommentCount > 0 && <span className=\"rte-toolbar__comment-badge\" />}\n </button>\n </div>\n ) : null;\n\n return (\n <div className={containerClass} style={{ minHeight: minH, maxHeight: maxH }}>\n {editable && (\n <Toolbar\n editor={editor}\n config={toolbarConfig}\n labels={labels}\n hasAI={!!aiConfig}\n onAIClick={handleAIClick}\n onRequestAIConfig={onRequestAIConfig}\n onFormatPainterChange={setFormatPainterActive}\n >\n {toolbarEnd}\n </Toolbar>\n )}\n\n\n <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>\n <div className=\"rte-editor-wrapper\" style={{ flex: 1 }}>\n <EditorContent editor={editor} className=\"rte-editor-content\" />\n {editable && <ContextMenu editor={editor} labels={labels} onAIClick={aiConfig ? handleAIClick : undefined} />}\n {editable && <SlashMenu editor={editor} />}\n {editable && <BubbleToolbar editor={editor} onAddComment={requestAddComment} />}\n {editable && <BlockHandle editor={editor} persistent />}\n <CommentPopover\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n showPanel={showComments}\n onOpenPanel={() => setShowComments(true)}\n onScrollToThread={handleScrollToThread}\n currentUser={currentUser}\n />\n </div>\n\n {showComments && (\n <CommentPanel\n ref={commentPanelRef}\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n onRequestAddComment={requestAddComment}\n currentUser={currentUser}\n />\n )}\n </div>\n\n {aiConfig && showAIPanel && (\n <AIRewrite\n editor={editor}\n aiConfig={aiConfig}\n labels={labels}\n initialSelection={aiSelection}\n selectionRange={aiSelectionRange}\n followSelection={aiSelectionFollowsEditor}\n onClose={() => setShowAIPanel(false)}\n />\n )}\n\n <CommentDialog\n open={commentDialogOpen}\n onSubmit={handleCommentSubmit}\n onClose={() => setCommentDialogOpen(false)}\n />\n </div>\n );\n};\n\nexport default RichTextEditor;\n"],"mappings":"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"}
@@ -102,6 +102,8 @@ export interface RichTextEditorProps {
102
102
  onRequestAIConfig?: () => void;
103
103
  /** Toggle toolbar sections (all enabled by default) */
104
104
  toolbarConfig?: ToolbarSection;
105
+ /** Keep an open AI panel's selected text and replacement target in sync with new editor selections. */
106
+ aiSelectionFollowsEditor?: boolean;
105
107
  /** Minimum editor height */
106
108
  minHeight?: string | number;
107
109
  /** Maximum editor height */
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/types.ts"],"sourcesContent":["import type { Editor } from '@tiptap/react';\n\nexport type AIEditMode = 'replace' | 'insert';\n\nexport interface AIRequest {\n /** Text sent to the provider. For insert mode this is the user's prompt. */\n text: string;\n /** The instruction entered by the user, when provided. */\n prompt: string;\n /** Selected editor text. Empty when generating at the cursor. */\n selectedText: string;\n /** Replace a selection or insert at the captured cursor position. */\n mode: AIEditMode;\n action: AIAction;\n systemPrompt: string;\n signal: AbortSignal;\n}\n\nexport interface AIConfig {\n /** Required by built-in OpenAI and Anthropic protocols. */\n gateway?: string;\n protocol: 'openai' | 'anthropic' | 'custom';\n /** Required by built-in OpenAI and Anthropic protocols. */\n model?: string;\n apiKey?: string;\n headers?: Record<string, string>;\n /** Base system instruction applied to every AI edit request. */\n systemPrompt?: string;\n /** Custom handler; useful for keeping provider credentials outside the browser. */\n customHandler?: (params: AIRequest) => AsyncIterable<string>;\n}\n\nexport type AIAction =\n | 'rewrite'\n | 'shorten'\n | 'expand'\n | 'fix_grammar'\n | 'translate_en'\n | 'translate_zh'\n | 'professional'\n | 'casual';\n\nexport interface ToolbarButtonConfig {\n undo?: boolean;\n redo?: boolean;\n fontFamily?: boolean;\n fontSize?: boolean;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n subscript?: boolean;\n superscript?: boolean;\n formatPainter?: boolean;\n heading1?: boolean;\n heading2?: boolean;\n heading3?: boolean;\n heading4?: boolean;\n heading5?: boolean;\n heading6?: boolean;\n alignLeft?: boolean;\n alignCenter?: boolean;\n alignRight?: boolean;\n alignJustify?: boolean;\n bulletList?: boolean;\n orderedList?: boolean;\n taskList?: boolean;\n blockquote?: boolean;\n codeBlock?: boolean;\n mermaidBlock?: boolean;\n link?: boolean;\n image?: boolean;\n table?: boolean;\n tableOps?: boolean;\n horizontalRule?: boolean;\n markdownBlock?: boolean;\n markdownTemplates?: boolean;\n floatingDialog?: boolean;\n textColor?: boolean;\n highlight?: boolean;\n ai?: boolean;\n comments?: boolean;\n}\n\nexport interface ToolbarSection {\n textFormat?: boolean;\n heading?: boolean;\n alignment?: boolean;\n list?: boolean;\n insert?: boolean;\n color?: boolean;\n history?: boolean;\n ai?: boolean;\n tableOps?: boolean;\n fontStyle?: boolean;\n formatPainter?: boolean;\n /** Fine-grained visibility overrides for every toolbar control. */\n buttons?: ToolbarButtonConfig;\n}\n\nexport interface RichTextEditorProps {\n /** Initial HTML content */\n content?: string;\n /** Controlled content (HTML string) */\n value?: string;\n /** Called when content changes, returns HTML */\n onChange?: (html: string) => void;\n /** Called when content changes, returns JSON */\n onChangeJSON?: (json: Record<string, unknown>) => void;\n /** Editor placeholder text */\n placeholder?: string;\n /** Whether the editor is read-only */\n editable?: boolean;\n /** AI editing configuration. May be supplied or updated by the consuming app. */\n aiConfig?: AIConfig;\n /** Called when the AI button is clicked without aiConfig. Open your configuration UI here. */\n onRequestAIConfig?: () => void;\n /** Toggle toolbar sections (all enabled by default) */\n toolbarConfig?: ToolbarSection;\n /** Minimum editor height */\n minHeight?: string | number;\n /** Maximum editor height */\n maxHeight?: string | number;\n /** Additional CSS class for the root container */\n className?: string;\n /** Whether to autofocus on mount */\n autofocus?: boolean;\n /** Labels for i18n */\n labels?: RichTextEditorLabels;\n /** Ref to access the Tiptap editor instance */\n editorRef?: React.MutableRefObject<Editor | null>;\n /** Show comment panel by default */\n showComments?: boolean;\n /** Controlled comment threads */\n commentThreads?: import('./extensions/CommentMark').CommentThread[];\n /** Callback when comment threads change */\n onCommentThreadsChange?: (threads: import('./extensions/CommentMark').CommentThread[]) => void;\n /** Current user name for comments */\n currentUser?: string;\n}\n\nexport interface RichTextEditorLabels {\n bold?: string;\n italic?: string;\n underline?: string;\n strikethrough?: string;\n subscript?: string;\n superscript?: string;\n heading?: string;\n alignLeft?: string;\n alignCenter?: string;\n alignRight?: string;\n alignJustify?: string;\n bulletList?: string;\n orderedList?: string;\n taskList?: string;\n blockquote?: string;\n codeBlock?: string;\n link?: string;\n image?: string;\n table?: string;\n markdownBlock?: string;\n undo?: string;\n redo?: string;\n color?: string;\n highlight?: string;\n ai?: string;\n aiRewrite?: string;\n aiShorten?: string;\n aiExpand?: string;\n aiFixGrammar?: string;\n aiTranslateEn?: string;\n aiTranslateZh?: string;\n aiProfessional?: string;\n aiCasual?: string;\n aiProcessing?: string;\n aiAccept?: string;\n aiReject?: string;\n aiPromptLabel?: string;\n aiPromptPlaceholder?: string;\n aiSelectedText?: string;\n aiInsertHint?: string;\n aiResult?: string;\n aiGenerate?: string;\n aiCancel?: string;\n aiClose?: string;\n aiDismiss?: string;\n aiNotConfigured?: string;\n aiConfigure?: string;\n markdownEditMode?: string;\n markdownPreviewMode?: string;\n insertLinkUrl?: string;\n insertImageUrl?: string;\n horizontalRule?: string;\n tableAddColumnBefore?: string;\n tableAddColumnAfter?: string;\n tableDeleteColumn?: string;\n tableAddRowBefore?: string;\n tableAddRowAfter?: string;\n tableDeleteRow?: string;\n tableMergeCells?: string;\n tableSplitCell?: string;\n tableDelete?: string;\n tableOps?: string;\n fontFamily?: string;\n fontSize?: string;\n formatPainter?: string;\n formatPainterActive?: string;\n mermaidBlock?: string;\n mdTemplates?: string;\n mdTplFlowchart?: string;\n mdTplSequence?: string;\n mdTplPieChart?: string;\n mdTplGantt?: string;\n mdTplBarChart?: string;\n mdTplPython?: string;\n mdTplTypeScript?: string;\n mdTplRust?: string;\n mdTplMath?: string;\n mdTplMixed?: string;\n floatingDialog?: string;\n layoutBlock?: string;\n layoutWrapLeft?: string;\n layoutWrapRight?: string;\n layoutFloat?: string;\n}\n\nexport const defaultLabels: RichTextEditorLabels = {\n bold: 'Bold',\n italic: 'Italic',\n underline: 'Underline',\n strikethrough: 'Strikethrough',\n subscript: 'Subscript',\n superscript: 'Superscript',\n heading: 'Heading',\n alignLeft: 'Align Left',\n alignCenter: 'Align Center',\n alignRight: 'Align Right',\n alignJustify: 'Justify',\n bulletList: 'Bullet List',\n orderedList: 'Ordered List',\n taskList: 'Task List',\n blockquote: 'Blockquote',\n codeBlock: 'Code Block',\n link: 'Link',\n image: 'Image',\n table: 'Table',\n markdownBlock: 'Markdown Block',\n undo: 'Undo',\n redo: 'Redo',\n color: 'Text Color',\n highlight: 'Highlight',\n ai: 'AI',\n aiRewrite: 'Rewrite',\n aiShorten: 'Shorten',\n aiExpand: 'Expand',\n aiFixGrammar: 'Fix Grammar',\n aiTranslateEn: 'Translate to English',\n aiTranslateZh: 'Translate to Chinese',\n aiProfessional: 'Professional Tone',\n aiCasual: 'Casual Tone',\n aiProcessing: 'AI Processing...',\n aiAccept: 'Accept',\n aiReject: 'Reject',\n aiPromptLabel: 'Prompt',\n aiPromptPlaceholder: 'Describe what AI should write… (Ctrl+Enter to generate)',\n aiSelectedText: 'Selected text',\n aiInsertHint: 'No text selected. The result will be inserted at the cursor.',\n aiResult: 'Result',\n aiGenerate: 'Generate',\n aiCancel: 'Cancel',\n aiClose: 'Close AI assistant',\n aiDismiss: 'Dismiss',\n aiNotConfigured: 'AI is not configured',\n aiConfigure: 'Configure AI',\n markdownEditMode: 'Edit',\n markdownPreviewMode: 'Preview',\n insertLinkUrl: 'Enter URL',\n insertImageUrl: 'Enter image URL',\n horizontalRule: 'Horizontal Rule',\n tableAddColumnBefore: 'Add Column Before',\n tableAddColumnAfter: 'Add Column After',\n tableDeleteColumn: 'Delete Column',\n tableAddRowBefore: 'Add Row Before',\n tableAddRowAfter: 'Add Row After',\n tableDeleteRow: 'Delete Row',\n tableMergeCells: 'Merge Cells',\n tableSplitCell: 'Split Cell',\n tableDelete: 'Delete Table',\n tableOps: 'Table Operations',\n fontFamily: 'Font Family',\n fontSize: 'Font Size',\n formatPainter: 'Format Painter',\n formatPainterActive: 'Format Painter (click target)',\n mermaidBlock: 'Mermaid Diagram',\n mdTemplates: 'Markdown Templates',\n mdTplFlowchart: 'Flowchart',\n mdTplSequence: 'Sequence Diagram',\n mdTplPieChart: 'Pie Chart',\n mdTplGantt: 'Gantt Chart',\n mdTplBarChart: 'Bar Chart (xychart)',\n mdTplPython: 'Python Code',\n mdTplTypeScript: 'TypeScript Code',\n mdTplRust: 'Rust Code',\n mdTplMath: 'Math Formulas (TeX)',\n mdTplMixed: 'Mixed Example',\n floatingDialog: 'Floating Dialog',\n layoutBlock: 'Block (Full Width)',\n layoutWrapLeft: 'Wrap Left',\n layoutWrapRight: 'Wrap Right',\n layoutFloat: 'Float (Overlay)',\n};\n"],"mappings":";AAmOA,IAAa,IAAsC;CACjD,MAAM;CACN,QAAQ;CACR,WAAW;CACX,eAAe;CACf,WAAW;CACX,aAAa;CACb,SAAS;CACT,WAAW;CACX,aAAa;CACb,YAAY;CACZ,cAAc;CACd,YAAY;CACZ,aAAa;CACb,UAAU;CACV,YAAY;CACZ,WAAW;CACX,MAAM;CACN,OAAO;CACP,OAAO;CACP,eAAe;CACf,MAAM;CACN,MAAM;CACN,OAAO;CACP,WAAW;CACX,IAAI;CACJ,WAAW;CACX,WAAW;CACX,UAAU;CACV,cAAc;CACd,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,UAAU;CACV,cAAc;CACd,UAAU;CACV,UAAU;CACV,eAAe;CACf,qBAAqB;CACrB,gBAAgB;CAChB,cAAc;CACd,UAAU;CACV,YAAY;CACZ,UAAU;CACV,SAAS;CACT,WAAW;CACX,iBAAiB;CACjB,aAAa;CACb,kBAAkB;CAClB,qBAAqB;CACrB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;CAChB,sBAAsB;CACtB,qBAAqB;CACrB,mBAAmB;CACnB,mBAAmB;CACnB,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,aAAa;CACb,UAAU;CACV,YAAY;CACZ,UAAU;CACV,eAAe;CACf,qBAAqB;CACrB,cAAc;CACd,aAAa;CACb,gBAAgB;CAChB,eAAe;CACf,eAAe;CACf,YAAY;CACZ,eAAe;CACf,aAAa;CACb,iBAAiB;CACjB,WAAW;CACX,WAAW;CACX,YAAY;CACZ,gBAAgB;CAChB,aAAa;CACb,gBAAgB;CAChB,iBAAiB;CACjB,aAAa;AACf"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/types.ts"],"sourcesContent":["import type { Editor } from '@tiptap/react';\n\nexport type AIEditMode = 'replace' | 'insert';\n\nexport interface AIRequest {\n /** Text sent to the provider. For insert mode this is the user's prompt. */\n text: string;\n /** The instruction entered by the user, when provided. */\n prompt: string;\n /** Selected editor text. Empty when generating at the cursor. */\n selectedText: string;\n /** Replace a selection or insert at the captured cursor position. */\n mode: AIEditMode;\n action: AIAction;\n systemPrompt: string;\n signal: AbortSignal;\n}\n\nexport interface AIConfig {\n /** Required by built-in OpenAI and Anthropic protocols. */\n gateway?: string;\n protocol: 'openai' | 'anthropic' | 'custom';\n /** Required by built-in OpenAI and Anthropic protocols. */\n model?: string;\n apiKey?: string;\n headers?: Record<string, string>;\n /** Base system instruction applied to every AI edit request. */\n systemPrompt?: string;\n /** Custom handler; useful for keeping provider credentials outside the browser. */\n customHandler?: (params: AIRequest) => AsyncIterable<string>;\n}\n\nexport type AIAction =\n | 'rewrite'\n | 'shorten'\n | 'expand'\n | 'fix_grammar'\n | 'translate_en'\n | 'translate_zh'\n | 'professional'\n | 'casual';\n\nexport interface ToolbarButtonConfig {\n undo?: boolean;\n redo?: boolean;\n fontFamily?: boolean;\n fontSize?: boolean;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n subscript?: boolean;\n superscript?: boolean;\n formatPainter?: boolean;\n heading1?: boolean;\n heading2?: boolean;\n heading3?: boolean;\n heading4?: boolean;\n heading5?: boolean;\n heading6?: boolean;\n alignLeft?: boolean;\n alignCenter?: boolean;\n alignRight?: boolean;\n alignJustify?: boolean;\n bulletList?: boolean;\n orderedList?: boolean;\n taskList?: boolean;\n blockquote?: boolean;\n codeBlock?: boolean;\n mermaidBlock?: boolean;\n link?: boolean;\n image?: boolean;\n table?: boolean;\n tableOps?: boolean;\n horizontalRule?: boolean;\n markdownBlock?: boolean;\n markdownTemplates?: boolean;\n floatingDialog?: boolean;\n textColor?: boolean;\n highlight?: boolean;\n ai?: boolean;\n comments?: boolean;\n}\n\nexport interface ToolbarSection {\n textFormat?: boolean;\n heading?: boolean;\n alignment?: boolean;\n list?: boolean;\n insert?: boolean;\n color?: boolean;\n history?: boolean;\n ai?: boolean;\n tableOps?: boolean;\n fontStyle?: boolean;\n formatPainter?: boolean;\n /** Fine-grained visibility overrides for every toolbar control. */\n buttons?: ToolbarButtonConfig;\n}\n\nexport interface RichTextEditorProps {\n /** Initial HTML content */\n content?: string;\n /** Controlled content (HTML string) */\n value?: string;\n /** Called when content changes, returns HTML */\n onChange?: (html: string) => void;\n /** Called when content changes, returns JSON */\n onChangeJSON?: (json: Record<string, unknown>) => void;\n /** Editor placeholder text */\n placeholder?: string;\n /** Whether the editor is read-only */\n editable?: boolean;\n /** AI editing configuration. May be supplied or updated by the consuming app. */\n aiConfig?: AIConfig;\n /** Called when the AI button is clicked without aiConfig. Open your configuration UI here. */\n onRequestAIConfig?: () => void;\n /** Toggle toolbar sections (all enabled by default) */\n toolbarConfig?: ToolbarSection;\n /** Keep an open AI panel's selected text and replacement target in sync with new editor selections. */\n aiSelectionFollowsEditor?: boolean;\n /** Minimum editor height */\n minHeight?: string | number;\n /** Maximum editor height */\n maxHeight?: string | number;\n /** Additional CSS class for the root container */\n className?: string;\n /** Whether to autofocus on mount */\n autofocus?: boolean;\n /** Labels for i18n */\n labels?: RichTextEditorLabels;\n /** Ref to access the Tiptap editor instance */\n editorRef?: React.MutableRefObject<Editor | null>;\n /** Show comment panel by default */\n showComments?: boolean;\n /** Controlled comment threads */\n commentThreads?: import('./extensions/CommentMark').CommentThread[];\n /** Callback when comment threads change */\n onCommentThreadsChange?: (threads: import('./extensions/CommentMark').CommentThread[]) => void;\n /** Current user name for comments */\n currentUser?: string;\n}\n\nexport interface RichTextEditorLabels {\n bold?: string;\n italic?: string;\n underline?: string;\n strikethrough?: string;\n subscript?: string;\n superscript?: string;\n heading?: string;\n alignLeft?: string;\n alignCenter?: string;\n alignRight?: string;\n alignJustify?: string;\n bulletList?: string;\n orderedList?: string;\n taskList?: string;\n blockquote?: string;\n codeBlock?: string;\n link?: string;\n image?: string;\n table?: string;\n markdownBlock?: string;\n undo?: string;\n redo?: string;\n color?: string;\n highlight?: string;\n ai?: string;\n aiRewrite?: string;\n aiShorten?: string;\n aiExpand?: string;\n aiFixGrammar?: string;\n aiTranslateEn?: string;\n aiTranslateZh?: string;\n aiProfessional?: string;\n aiCasual?: string;\n aiProcessing?: string;\n aiAccept?: string;\n aiReject?: string;\n aiPromptLabel?: string;\n aiPromptPlaceholder?: string;\n aiSelectedText?: string;\n aiInsertHint?: string;\n aiResult?: string;\n aiGenerate?: string;\n aiCancel?: string;\n aiClose?: string;\n aiDismiss?: string;\n aiNotConfigured?: string;\n aiConfigure?: string;\n markdownEditMode?: string;\n markdownPreviewMode?: string;\n insertLinkUrl?: string;\n insertImageUrl?: string;\n horizontalRule?: string;\n tableAddColumnBefore?: string;\n tableAddColumnAfter?: string;\n tableDeleteColumn?: string;\n tableAddRowBefore?: string;\n tableAddRowAfter?: string;\n tableDeleteRow?: string;\n tableMergeCells?: string;\n tableSplitCell?: string;\n tableDelete?: string;\n tableOps?: string;\n fontFamily?: string;\n fontSize?: string;\n formatPainter?: string;\n formatPainterActive?: string;\n mermaidBlock?: string;\n mdTemplates?: string;\n mdTplFlowchart?: string;\n mdTplSequence?: string;\n mdTplPieChart?: string;\n mdTplGantt?: string;\n mdTplBarChart?: string;\n mdTplPython?: string;\n mdTplTypeScript?: string;\n mdTplRust?: string;\n mdTplMath?: string;\n mdTplMixed?: string;\n floatingDialog?: string;\n layoutBlock?: string;\n layoutWrapLeft?: string;\n layoutWrapRight?: string;\n layoutFloat?: string;\n}\n\nexport const defaultLabels: RichTextEditorLabels = {\n bold: 'Bold',\n italic: 'Italic',\n underline: 'Underline',\n strikethrough: 'Strikethrough',\n subscript: 'Subscript',\n superscript: 'Superscript',\n heading: 'Heading',\n alignLeft: 'Align Left',\n alignCenter: 'Align Center',\n alignRight: 'Align Right',\n alignJustify: 'Justify',\n bulletList: 'Bullet List',\n orderedList: 'Ordered List',\n taskList: 'Task List',\n blockquote: 'Blockquote',\n codeBlock: 'Code Block',\n link: 'Link',\n image: 'Image',\n table: 'Table',\n markdownBlock: 'Markdown Block',\n undo: 'Undo',\n redo: 'Redo',\n color: 'Text Color',\n highlight: 'Highlight',\n ai: 'AI',\n aiRewrite: 'Rewrite',\n aiShorten: 'Shorten',\n aiExpand: 'Expand',\n aiFixGrammar: 'Fix Grammar',\n aiTranslateEn: 'Translate to English',\n aiTranslateZh: 'Translate to Chinese',\n aiProfessional: 'Professional Tone',\n aiCasual: 'Casual Tone',\n aiProcessing: 'AI Processing...',\n aiAccept: 'Accept',\n aiReject: 'Reject',\n aiPromptLabel: 'Prompt',\n aiPromptPlaceholder: 'Describe what AI should write… (Ctrl+Enter to generate)',\n aiSelectedText: 'Selected text',\n aiInsertHint: 'No text selected. The result will be inserted at the cursor.',\n aiResult: 'Result',\n aiGenerate: 'Generate',\n aiCancel: 'Cancel',\n aiClose: 'Close AI assistant',\n aiDismiss: 'Dismiss',\n aiNotConfigured: 'AI is not configured',\n aiConfigure: 'Configure AI',\n markdownEditMode: 'Edit',\n markdownPreviewMode: 'Preview',\n insertLinkUrl: 'Enter URL',\n insertImageUrl: 'Enter image URL',\n horizontalRule: 'Horizontal Rule',\n tableAddColumnBefore: 'Add Column Before',\n tableAddColumnAfter: 'Add Column After',\n tableDeleteColumn: 'Delete Column',\n tableAddRowBefore: 'Add Row Before',\n tableAddRowAfter: 'Add Row After',\n tableDeleteRow: 'Delete Row',\n tableMergeCells: 'Merge Cells',\n tableSplitCell: 'Split Cell',\n tableDelete: 'Delete Table',\n tableOps: 'Table Operations',\n fontFamily: 'Font Family',\n fontSize: 'Font Size',\n formatPainter: 'Format Painter',\n formatPainterActive: 'Format Painter (click target)',\n mermaidBlock: 'Mermaid Diagram',\n mdTemplates: 'Markdown Templates',\n mdTplFlowchart: 'Flowchart',\n mdTplSequence: 'Sequence Diagram',\n mdTplPieChart: 'Pie Chart',\n mdTplGantt: 'Gantt Chart',\n mdTplBarChart: 'Bar Chart (xychart)',\n mdTplPython: 'Python Code',\n mdTplTypeScript: 'TypeScript Code',\n mdTplRust: 'Rust Code',\n mdTplMath: 'Math Formulas (TeX)',\n mdTplMixed: 'Mixed Example',\n floatingDialog: 'Floating Dialog',\n layoutBlock: 'Block (Full Width)',\n layoutWrapLeft: 'Wrap Left',\n layoutWrapRight: 'Wrap Right',\n layoutFloat: 'Float (Overlay)',\n};\n"],"mappings":";AAqOA,IAAa,IAAsC;CACjD,MAAM;CACN,QAAQ;CACR,WAAW;CACX,eAAe;CACf,WAAW;CACX,aAAa;CACb,SAAS;CACT,WAAW;CACX,aAAa;CACb,YAAY;CACZ,cAAc;CACd,YAAY;CACZ,aAAa;CACb,UAAU;CACV,YAAY;CACZ,WAAW;CACX,MAAM;CACN,OAAO;CACP,OAAO;CACP,eAAe;CACf,MAAM;CACN,MAAM;CACN,OAAO;CACP,WAAW;CACX,IAAI;CACJ,WAAW;CACX,WAAW;CACX,UAAU;CACV,cAAc;CACd,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,UAAU;CACV,cAAc;CACd,UAAU;CACV,UAAU;CACV,eAAe;CACf,qBAAqB;CACrB,gBAAgB;CAChB,cAAc;CACd,UAAU;CACV,YAAY;CACZ,UAAU;CACV,SAAS;CACT,WAAW;CACX,iBAAiB;CACjB,aAAa;CACb,kBAAkB;CAClB,qBAAqB;CACrB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;CAChB,sBAAsB;CACtB,qBAAqB;CACrB,mBAAmB;CACnB,mBAAmB;CACnB,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,aAAa;CACb,UAAU;CACV,YAAY;CACZ,UAAU;CACV,eAAe;CACf,qBAAqB;CACrB,cAAc;CACd,aAAa;CACb,gBAAgB;CAChB,eAAe;CACf,eAAe;CACf,YAAY;CACZ,eAAe;CACf,aAAa;CACb,iBAAiB;CACjB,WAAW;CACX,WAAW;CACX,YAAY;CACZ,gBAAgB;CAChB,aAAa;CACb,gBAAgB;CAChB,iBAAiB;CACjB,aAAa;AACf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dishui",
3
- "version": "0.0.106",
3
+ "version": "0.0.108",
4
4
  "description": "New Components UI Framework with AI Powered",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.12.0",