@cyberyozh/text-editor 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editor.css +65 -0
- package/dist/editor.css.map +1 -1
- package/dist/editor.js +294 -122
- package/dist/editor.js.map +1 -1
- package/dist/editor.mjs +254 -82
- package/dist/editor.mjs.map +1 -1
- package/dist/render.js +34 -75
- package/dist/render.js.map +1 -1
- package/dist/render.mjs +32 -73
- package/dist/render.mjs.map +1 -1
- package/dist/styles/index.css +65 -0
- package/package.json +1 -1
- package/src/editor/dialogs/image-dialog/image-dialog.tsx +25 -3
- package/src/extensions/base/figure.ts +5 -5
- package/src/extensions/editor/figure.ts +184 -1
- package/src/extensions/editor/get-editor-extensions.ts +8 -2
- package/src/extensions/editor/index.ts +0 -24
- package/src/extensions/render/get-render-extensions.ts +1 -2
- package/src/extensions/views/components/index.ts +0 -1
- package/src/extensions/views/node-views/figure.tsx +1 -1
- package/src/render/static-renderer-config.tsx +0 -4
- package/src/styles/extensions/figure.css +77 -0
- package/src/extensions/views/components/table.tsx +0 -74
package/dist/editor.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/editor/editor.tsx
|
|
2
|
-
import { useState as
|
|
2
|
+
import { useState as useState12, useEffect as useEffect9 } from "react";
|
|
3
3
|
import { NodeSelection } from "@tiptap/pm/state";
|
|
4
4
|
import { Slice } from "@tiptap/pm/model";
|
|
5
5
|
import { useEditor, EditorContent } from "@tiptap/react";
|
|
@@ -1907,15 +1907,34 @@ var ImageDialog = ({
|
|
|
1907
1907
|
const img = new Image();
|
|
1908
1908
|
img.src = imageUrl;
|
|
1909
1909
|
img.onload = () => {
|
|
1910
|
-
const
|
|
1910
|
+
const naturalWidth = img.width;
|
|
1911
|
+
const naturalHeight = img.height;
|
|
1912
|
+
const naturalAspectRatio = naturalHeight / naturalWidth;
|
|
1913
|
+
let maxWidth;
|
|
1914
|
+
try {
|
|
1915
|
+
const editorElement = document.querySelector(".tiptap-content-wrapper");
|
|
1916
|
+
if (editorElement && editorElement.clientWidth > 0) {
|
|
1917
|
+
maxWidth = editorElement.clientWidth - 32;
|
|
1918
|
+
}
|
|
1919
|
+
} catch {
|
|
1920
|
+
}
|
|
1921
|
+
let finalWidth;
|
|
1922
|
+
let finalHeight;
|
|
1923
|
+
if (maxWidth && naturalWidth > maxWidth) {
|
|
1924
|
+
finalWidth = maxWidth;
|
|
1925
|
+
finalHeight = Math.round(maxWidth * naturalAspectRatio);
|
|
1926
|
+
} else {
|
|
1927
|
+
finalWidth = naturalWidth;
|
|
1928
|
+
finalHeight = naturalHeight;
|
|
1929
|
+
}
|
|
1911
1930
|
setFormState((prev) => ({
|
|
1912
1931
|
...prev,
|
|
1913
1932
|
file,
|
|
1914
1933
|
fileUrl: imageUrl,
|
|
1915
1934
|
title: file.name,
|
|
1916
1935
|
alt: file.name,
|
|
1917
|
-
width,
|
|
1918
|
-
height
|
|
1936
|
+
width: finalWidth,
|
|
1937
|
+
height: finalHeight
|
|
1919
1938
|
}));
|
|
1920
1939
|
};
|
|
1921
1940
|
};
|
|
@@ -3222,8 +3241,9 @@ var BaseFigure = Image2.extend({
|
|
|
3222
3241
|
isolating: true,
|
|
3223
3242
|
selectable: false,
|
|
3224
3243
|
addOptions() {
|
|
3244
|
+
const parentOptions = this.parent?.() || {};
|
|
3225
3245
|
return {
|
|
3226
|
-
|
|
3246
|
+
...parentOptions,
|
|
3227
3247
|
getImageById: void 0,
|
|
3228
3248
|
onFigureClick: void 0
|
|
3229
3249
|
};
|
|
@@ -3757,7 +3777,7 @@ var BaseLegacyFigure = Image3.extend({
|
|
|
3757
3777
|
|
|
3758
3778
|
// src/extensions/views/node-views/callout.tsx
|
|
3759
3779
|
import { NodeViewContent, NodeViewWrapper } from "@tiptap/react";
|
|
3760
|
-
import { useState as
|
|
3780
|
+
import { useState as useState10 } from "react";
|
|
3761
3781
|
|
|
3762
3782
|
// src/icons/color/TiptapCalloutError.tsx
|
|
3763
3783
|
import { jsx as jsx71, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
@@ -4346,27 +4366,23 @@ var PromptContent = ({ children, isEmpty, placeholder }) => /* @__PURE__ */ jsx8
|
|
|
4346
4366
|
}
|
|
4347
4367
|
) });
|
|
4348
4368
|
|
|
4349
|
-
// src/extensions/views/components/table.tsx
|
|
4350
|
-
import { useEffect as useEffect8, useRef as useRef10, useState as useState10 } from "react";
|
|
4351
|
-
import { jsx as jsx82, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
4352
|
-
|
|
4353
4369
|
// src/extensions/views/components/video.tsx
|
|
4354
|
-
import { jsx as
|
|
4370
|
+
import { jsx as jsx82, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
4355
4371
|
var Video = ({ src, children }) => {
|
|
4356
4372
|
const videoInfo = detectVideoHosting(src);
|
|
4357
4373
|
if (!videoInfo?.embedUrl) {
|
|
4358
|
-
return /* @__PURE__ */
|
|
4359
|
-
/* @__PURE__ */
|
|
4374
|
+
return /* @__PURE__ */ jsxs33("div", { className: "video-node", children: [
|
|
4375
|
+
/* @__PURE__ */ jsx82("div", { className: "video-error", children: /* @__PURE__ */ jsx82("span", { children: "Unsupported or invalid video URL" }) }),
|
|
4360
4376
|
children
|
|
4361
4377
|
] });
|
|
4362
4378
|
}
|
|
4363
|
-
return /* @__PURE__ */
|
|
4379
|
+
return /* @__PURE__ */ jsxs33(
|
|
4364
4380
|
"div",
|
|
4365
4381
|
{
|
|
4366
4382
|
className: "video-node",
|
|
4367
4383
|
"data-video": "",
|
|
4368
4384
|
children: [
|
|
4369
|
-
/* @__PURE__ */
|
|
4385
|
+
/* @__PURE__ */ jsx82("div", { className: "video-player-wrapper", children: /* @__PURE__ */ jsx82(
|
|
4370
4386
|
"iframe",
|
|
4371
4387
|
{
|
|
4372
4388
|
className: "video-iframe",
|
|
@@ -4383,13 +4399,13 @@ var Video = ({ src, children }) => {
|
|
|
4383
4399
|
};
|
|
4384
4400
|
|
|
4385
4401
|
// src/editor/controls/emoji-picker.tsx
|
|
4386
|
-
import { useEffect as
|
|
4402
|
+
import { useEffect as useEffect8, useRef as useRef10 } from "react";
|
|
4387
4403
|
import EmojiPicker from "emoji-picker-react";
|
|
4388
|
-
import { jsx as
|
|
4404
|
+
import { jsx as jsx83 } from "react/jsx-runtime";
|
|
4389
4405
|
var EmojiPickerComponent = ({ isOpen, onClose, onEmojiSelect }) => {
|
|
4390
|
-
const pickerRef =
|
|
4406
|
+
const pickerRef = useRef10(null);
|
|
4391
4407
|
const translations2 = useTiptapTranslations();
|
|
4392
|
-
|
|
4408
|
+
useEffect8(() => {
|
|
4393
4409
|
const handleClickOutside = (event) => {
|
|
4394
4410
|
if (pickerRef.current && !pickerRef.current.contains(event.target)) {
|
|
4395
4411
|
onClose();
|
|
@@ -4403,12 +4419,12 @@ var EmojiPickerComponent = ({ isOpen, onClose, onEmojiSelect }) => {
|
|
|
4403
4419
|
};
|
|
4404
4420
|
}, [isOpen, onClose]);
|
|
4405
4421
|
if (!isOpen) return null;
|
|
4406
|
-
return /* @__PURE__ */
|
|
4422
|
+
return /* @__PURE__ */ jsx83(
|
|
4407
4423
|
"div",
|
|
4408
4424
|
{
|
|
4409
4425
|
ref: pickerRef,
|
|
4410
4426
|
className: "tiptap__emoji-picker-wrapper",
|
|
4411
|
-
children: /* @__PURE__ */
|
|
4427
|
+
children: /* @__PURE__ */ jsx83(
|
|
4412
4428
|
EmojiPicker,
|
|
4413
4429
|
{
|
|
4414
4430
|
skinTonesDisabled: true,
|
|
@@ -4433,12 +4449,12 @@ var EmojiPickerComponent = ({ isOpen, onClose, onEmojiSelect }) => {
|
|
|
4433
4449
|
};
|
|
4434
4450
|
|
|
4435
4451
|
// src/extensions/views/node-views/callout.tsx
|
|
4436
|
-
import { jsx as
|
|
4452
|
+
import { jsx as jsx84, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
4437
4453
|
var CalloutView = (props) => {
|
|
4438
4454
|
const type = props.node.attrs.type || "info";
|
|
4439
4455
|
const bgColor = props.node.attrs.bgColor;
|
|
4440
4456
|
const emoji = props.node.attrs.emoji;
|
|
4441
|
-
const [showEmojiPicker, setShowEmojiPicker] =
|
|
4457
|
+
const [showEmojiPicker, setShowEmojiPicker] = useState10(false);
|
|
4442
4458
|
const handleIconClick = (e) => {
|
|
4443
4459
|
e.preventDefault();
|
|
4444
4460
|
e.stopPropagation();
|
|
@@ -4448,23 +4464,23 @@ var CalloutView = (props) => {
|
|
|
4448
4464
|
props.updateAttributes({ emoji: newEmoji });
|
|
4449
4465
|
setShowEmojiPicker(false);
|
|
4450
4466
|
};
|
|
4451
|
-
return /* @__PURE__ */
|
|
4467
|
+
return /* @__PURE__ */ jsx84(NodeViewWrapper, { children: /* @__PURE__ */ jsx84(
|
|
4452
4468
|
Callout,
|
|
4453
4469
|
{
|
|
4454
4470
|
type,
|
|
4455
4471
|
bgColor,
|
|
4456
4472
|
emoji,
|
|
4457
|
-
iconWrapper: (icon) => /* @__PURE__ */
|
|
4458
|
-
/* @__PURE__ */
|
|
4473
|
+
iconWrapper: (icon) => /* @__PURE__ */ jsxs34("div", { className: "callout-icon-wrapper", children: [
|
|
4474
|
+
/* @__PURE__ */ jsx84(
|
|
4459
4475
|
"button",
|
|
4460
4476
|
{
|
|
4461
4477
|
className: "callout-icon-button",
|
|
4462
4478
|
onClick: handleIconClick,
|
|
4463
4479
|
type: "button",
|
|
4464
|
-
children: /* @__PURE__ */
|
|
4480
|
+
children: /* @__PURE__ */ jsx84("div", { className: "callout-icon", children: icon })
|
|
4465
4481
|
}
|
|
4466
4482
|
),
|
|
4467
|
-
/* @__PURE__ */
|
|
4483
|
+
/* @__PURE__ */ jsx84(
|
|
4468
4484
|
EmojiPickerComponent,
|
|
4469
4485
|
{
|
|
4470
4486
|
isOpen: showEmojiPicker,
|
|
@@ -4473,101 +4489,101 @@ var CalloutView = (props) => {
|
|
|
4473
4489
|
}
|
|
4474
4490
|
)
|
|
4475
4491
|
] }),
|
|
4476
|
-
children: /* @__PURE__ */
|
|
4492
|
+
children: /* @__PURE__ */ jsx84(NodeViewContent, { as: "div" })
|
|
4477
4493
|
}
|
|
4478
4494
|
) });
|
|
4479
4495
|
};
|
|
4480
4496
|
|
|
4481
4497
|
// src/extensions/views/node-views/code-block.tsx
|
|
4482
|
-
import { useState as
|
|
4498
|
+
import { useState as useState11 } from "react";
|
|
4483
4499
|
import { NodeViewContent as NodeViewContent2, NodeViewWrapper as NodeViewWrapper2 } from "@tiptap/react";
|
|
4484
|
-
import { jsx as
|
|
4500
|
+
import { jsx as jsx85 } from "react/jsx-runtime";
|
|
4485
4501
|
var CodeBlockView = (props) => {
|
|
4486
|
-
const [selectedLanguage, setSelectedLanguage] =
|
|
4502
|
+
const [selectedLanguage, setSelectedLanguage] = useState11(props.node.attrs.language ?? "");
|
|
4487
4503
|
const translations2 = useTiptapTranslations();
|
|
4488
4504
|
const handleLanguageChange = (language) => {
|
|
4489
4505
|
props.updateAttributes({ language });
|
|
4490
4506
|
setSelectedLanguage(language);
|
|
4491
4507
|
};
|
|
4492
|
-
return /* @__PURE__ */
|
|
4508
|
+
return /* @__PURE__ */ jsx85(NodeViewWrapper2, { children: /* @__PURE__ */ jsx85(
|
|
4493
4509
|
CodeBlock,
|
|
4494
4510
|
{
|
|
4495
4511
|
language: selectedLanguage,
|
|
4496
4512
|
isEditable: props.editor.isEditable,
|
|
4497
4513
|
onLanguageChange: handleLanguageChange,
|
|
4498
4514
|
translations: translations2,
|
|
4499
|
-
children: /* @__PURE__ */
|
|
4515
|
+
children: /* @__PURE__ */ jsx85(NodeViewContent2, {})
|
|
4500
4516
|
}
|
|
4501
4517
|
) });
|
|
4502
4518
|
};
|
|
4503
4519
|
|
|
4504
4520
|
// src/extensions/views/node-views/copyable-text.tsx
|
|
4505
4521
|
import { MarkViewContent } from "@tiptap/react";
|
|
4506
|
-
import { jsx as
|
|
4522
|
+
import { jsx as jsx86 } from "react/jsx-runtime";
|
|
4507
4523
|
var CopyableTextView = () => {
|
|
4508
|
-
return /* @__PURE__ */
|
|
4524
|
+
return /* @__PURE__ */ jsx86(CopyableText2, { children: /* @__PURE__ */ jsx86(MarkViewContent, {}) });
|
|
4509
4525
|
};
|
|
4510
4526
|
|
|
4511
4527
|
// src/extensions/views/node-views/custom-quote.tsx
|
|
4512
4528
|
import { NodeViewContent as NodeViewContent3, NodeViewWrapper as NodeViewWrapper3 } from "@tiptap/react";
|
|
4513
|
-
import { jsx as
|
|
4529
|
+
import { jsx as jsx87 } from "react/jsx-runtime";
|
|
4514
4530
|
var CustomQuoteView = () => {
|
|
4515
|
-
return /* @__PURE__ */
|
|
4531
|
+
return /* @__PURE__ */ jsx87(NodeViewWrapper3, { children: /* @__PURE__ */ jsx87(CustomQuote, { children: /* @__PURE__ */ jsx87(NodeViewContent3, {}) }) });
|
|
4516
4532
|
};
|
|
4517
4533
|
var CustomQuoteTextView = (props) => {
|
|
4518
4534
|
const isEmpty = !props.node.content.size;
|
|
4519
4535
|
const translations2 = useTiptapTranslations();
|
|
4520
|
-
return /* @__PURE__ */
|
|
4536
|
+
return /* @__PURE__ */ jsx87(NodeViewWrapper3, { children: /* @__PURE__ */ jsx87(
|
|
4521
4537
|
CustomQuoteText,
|
|
4522
4538
|
{
|
|
4523
4539
|
isEmpty,
|
|
4524
4540
|
placeholder: translations2.customQuote.textPlaceholder,
|
|
4525
|
-
children: /* @__PURE__ */
|
|
4541
|
+
children: /* @__PURE__ */ jsx87(NodeViewContent3, { className: isEmpty ? "is-empty" : "" })
|
|
4526
4542
|
}
|
|
4527
4543
|
) });
|
|
4528
4544
|
};
|
|
4529
4545
|
var CustomQuoteAuthorView = (props) => {
|
|
4530
4546
|
const isEmpty = !props.node.content.size;
|
|
4531
4547
|
const translations2 = useTiptapTranslations();
|
|
4532
|
-
return /* @__PURE__ */
|
|
4548
|
+
return /* @__PURE__ */ jsx87(NodeViewWrapper3, { children: /* @__PURE__ */ jsx87(
|
|
4533
4549
|
CustomQuoteAuthor,
|
|
4534
4550
|
{
|
|
4535
4551
|
isEmpty,
|
|
4536
4552
|
placeholder: translations2.customQuote.authorPlaceholder,
|
|
4537
|
-
children: /* @__PURE__ */
|
|
4553
|
+
children: /* @__PURE__ */ jsx87(NodeViewContent3, { className: isEmpty ? "is-empty" : "" })
|
|
4538
4554
|
}
|
|
4539
4555
|
) });
|
|
4540
4556
|
};
|
|
4541
4557
|
var CustomQuoteSignView = (props) => {
|
|
4542
4558
|
const isEmpty = !props.node.content.size;
|
|
4543
4559
|
const translations2 = useTiptapTranslations();
|
|
4544
|
-
return /* @__PURE__ */
|
|
4560
|
+
return /* @__PURE__ */ jsx87(NodeViewWrapper3, { children: /* @__PURE__ */ jsx87(
|
|
4545
4561
|
CustomQuoteSign,
|
|
4546
4562
|
{
|
|
4547
4563
|
isEmpty,
|
|
4548
4564
|
placeholder: translations2.customQuote.signPlaceholder,
|
|
4549
|
-
children: /* @__PURE__ */
|
|
4565
|
+
children: /* @__PURE__ */ jsx87(NodeViewContent3, { className: isEmpty ? "is-empty" : "" })
|
|
4550
4566
|
}
|
|
4551
4567
|
) });
|
|
4552
4568
|
};
|
|
4553
4569
|
|
|
4554
4570
|
// src/extensions/views/node-views/figure.tsx
|
|
4555
4571
|
import { NodeViewWrapper as NodeViewWrapper4 } from "@tiptap/react";
|
|
4556
|
-
import { jsx as
|
|
4572
|
+
import { jsx as jsx88 } from "react/jsx-runtime";
|
|
4557
4573
|
var FigureView = ({ node, getPos, editor }) => {
|
|
4558
|
-
const { fileId, src, alt, title, caption, width, height
|
|
4574
|
+
const { fileId, src, alt, title, caption, width, height } = node.attrs;
|
|
4559
4575
|
const imageExtension = editor.extensionManager.extensions.find((ext) => ext.name === "image");
|
|
4560
4576
|
const getImageById = imageExtension?.options.getImageById;
|
|
4561
4577
|
const onFigureClick = imageExtension?.options.onFigureClick;
|
|
4562
4578
|
const handleEditClick = () => {
|
|
4563
4579
|
onFigureClick?.(node.attrs, getPos());
|
|
4564
4580
|
};
|
|
4565
|
-
return /* @__PURE__ */
|
|
4581
|
+
return /* @__PURE__ */ jsx88(
|
|
4566
4582
|
NodeViewWrapper4,
|
|
4567
4583
|
{
|
|
4568
4584
|
className: "figure-node-view",
|
|
4569
4585
|
"data-drag-handle": true,
|
|
4570
|
-
children: /* @__PURE__ */
|
|
4586
|
+
children: /* @__PURE__ */ jsx88(
|
|
4571
4587
|
Figure,
|
|
4572
4588
|
{
|
|
4573
4589
|
fileId,
|
|
@@ -4588,38 +4604,38 @@ var FigureView = ({ node, getPos, editor }) => {
|
|
|
4588
4604
|
|
|
4589
4605
|
// src/extensions/views/node-views/prompt.tsx
|
|
4590
4606
|
import { NodeViewContent as NodeViewContent4, NodeViewWrapper as NodeViewWrapper5 } from "@tiptap/react";
|
|
4591
|
-
import { jsx as
|
|
4607
|
+
import { jsx as jsx89 } from "react/jsx-runtime";
|
|
4592
4608
|
var PromptHeaderView = (props) => {
|
|
4593
4609
|
const isEmpty = !props.node.content.size;
|
|
4594
4610
|
const translations2 = useTiptapTranslations();
|
|
4595
|
-
return /* @__PURE__ */
|
|
4611
|
+
return /* @__PURE__ */ jsx89(NodeViewWrapper5, { children: /* @__PURE__ */ jsx89(
|
|
4596
4612
|
PromptHeader,
|
|
4597
4613
|
{
|
|
4598
4614
|
isEmpty,
|
|
4599
4615
|
placeholder: translations2.prompt.headerPlaceholder,
|
|
4600
|
-
children: /* @__PURE__ */
|
|
4616
|
+
children: /* @__PURE__ */ jsx89(NodeViewContent4, { className: isEmpty ? "is-empty" : "" })
|
|
4601
4617
|
}
|
|
4602
4618
|
) });
|
|
4603
4619
|
};
|
|
4604
4620
|
var PromptContentView = (props) => {
|
|
4605
4621
|
const isEmpty = !props.node.content.size;
|
|
4606
4622
|
const translations2 = useTiptapTranslations();
|
|
4607
|
-
return /* @__PURE__ */
|
|
4623
|
+
return /* @__PURE__ */ jsx89(NodeViewWrapper5, { children: /* @__PURE__ */ jsx89(
|
|
4608
4624
|
PromptContent,
|
|
4609
4625
|
{
|
|
4610
4626
|
isEmpty,
|
|
4611
4627
|
placeholder: translations2.prompt.contentPlaceholder,
|
|
4612
|
-
children: /* @__PURE__ */
|
|
4628
|
+
children: /* @__PURE__ */ jsx89(NodeViewContent4, { className: isEmpty ? "is-empty" : "" })
|
|
4613
4629
|
}
|
|
4614
4630
|
) });
|
|
4615
4631
|
};
|
|
4616
4632
|
|
|
4617
4633
|
// src/extensions/views/node-views/video.tsx
|
|
4618
4634
|
import { NodeViewContent as NodeViewContent5, NodeViewWrapper as NodeViewWrapper6 } from "@tiptap/react";
|
|
4619
|
-
import { jsx as
|
|
4635
|
+
import { jsx as jsx90 } from "react/jsx-runtime";
|
|
4620
4636
|
var VideoView = (props) => {
|
|
4621
4637
|
const { src } = props.node.attrs;
|
|
4622
|
-
return /* @__PURE__ */
|
|
4638
|
+
return /* @__PURE__ */ jsx90(NodeViewWrapper6, { children: /* @__PURE__ */ jsx90(Video, { src, children: /* @__PURE__ */ jsx90(
|
|
4623
4639
|
NodeViewContent5,
|
|
4624
4640
|
{
|
|
4625
4641
|
as: "div",
|
|
@@ -5138,9 +5154,159 @@ var LegacyPromptSEContent = BaseLegacyPromptSEContent.extend({
|
|
|
5138
5154
|
|
|
5139
5155
|
// src/extensions/editor/figure.ts
|
|
5140
5156
|
import { ReactNodeViewRenderer as ReactNodeViewRenderer6 } from "@tiptap/react";
|
|
5157
|
+
import { ResizableNodeView } from "@tiptap/core";
|
|
5141
5158
|
var Figure2 = BaseFigure.extend({
|
|
5142
5159
|
addNodeView() {
|
|
5143
|
-
|
|
5160
|
+
const resizeOptions = this.options.resize;
|
|
5161
|
+
if (!resizeOptions) {
|
|
5162
|
+
return ReactNodeViewRenderer6(FigureView);
|
|
5163
|
+
}
|
|
5164
|
+
return (props) => {
|
|
5165
|
+
const { node, getPos, editor } = props;
|
|
5166
|
+
const attrs = node.attrs;
|
|
5167
|
+
const imageExtension = editor.extensionManager.extensions.find(
|
|
5168
|
+
(ext) => ext.name === "image"
|
|
5169
|
+
);
|
|
5170
|
+
const getImageById = imageExtension?.options.getImageById;
|
|
5171
|
+
let imgSrc = attrs.src;
|
|
5172
|
+
if (attrs.fileId && getImageById) {
|
|
5173
|
+
const resolvedSrc = getImageById(attrs.fileId);
|
|
5174
|
+
if (resolvedSrc) imgSrc = resolvedSrc;
|
|
5175
|
+
}
|
|
5176
|
+
let maxWidth;
|
|
5177
|
+
try {
|
|
5178
|
+
if (editor.view?.dom) {
|
|
5179
|
+
const contentWrapper = editor.view.dom.closest(".tiptap-content-wrapper");
|
|
5180
|
+
if (contentWrapper && contentWrapper.clientWidth > 0) {
|
|
5181
|
+
maxWidth = contentWrapper.clientWidth - 32;
|
|
5182
|
+
}
|
|
5183
|
+
}
|
|
5184
|
+
} catch {
|
|
5185
|
+
}
|
|
5186
|
+
let naturalAspectRatio;
|
|
5187
|
+
let maxHeight;
|
|
5188
|
+
const constrainDimensions = (w, h) => {
|
|
5189
|
+
let constrainedW = w;
|
|
5190
|
+
let constrainedH = h;
|
|
5191
|
+
if (maxWidth && maxHeight && naturalAspectRatio && w >= maxWidth) {
|
|
5192
|
+
constrainedW = maxWidth;
|
|
5193
|
+
constrainedH = maxHeight;
|
|
5194
|
+
}
|
|
5195
|
+
return { width: constrainedW, height: constrainedH };
|
|
5196
|
+
};
|
|
5197
|
+
const updateImageDimensions = (width, height) => {
|
|
5198
|
+
imageContainer.style.width = `${width}px`;
|
|
5199
|
+
imageContainer.style.height = `${height}px`;
|
|
5200
|
+
};
|
|
5201
|
+
const figure = document.createElement("figure");
|
|
5202
|
+
figure.setAttribute("data-drag-handle", "");
|
|
5203
|
+
const imageContainer = document.createElement("div");
|
|
5204
|
+
imageContainer.className = "figure-image-container";
|
|
5205
|
+
const img = document.createElement("img");
|
|
5206
|
+
img.src = imgSrc || "";
|
|
5207
|
+
if (attrs.alt) img.alt = attrs.alt;
|
|
5208
|
+
if (attrs.title) img.title = attrs.title;
|
|
5209
|
+
if (attrs.width && attrs.height) {
|
|
5210
|
+
imageContainer.style.width = `${attrs.width}px`;
|
|
5211
|
+
imageContainer.style.height = `${attrs.height}px`;
|
|
5212
|
+
}
|
|
5213
|
+
img.onload = () => {
|
|
5214
|
+
naturalAspectRatio = img.naturalHeight / img.naturalWidth;
|
|
5215
|
+
if (maxWidth && naturalAspectRatio) {
|
|
5216
|
+
maxHeight = Math.round(maxWidth * naturalAspectRatio);
|
|
5217
|
+
}
|
|
5218
|
+
};
|
|
5219
|
+
imageContainer.appendChild(img);
|
|
5220
|
+
if (editor.isEditable) {
|
|
5221
|
+
const editButton = document.createElement("button");
|
|
5222
|
+
editButton.type = "button";
|
|
5223
|
+
editButton.className = "figure-edit-button";
|
|
5224
|
+
editButton.contentEditable = "false";
|
|
5225
|
+
editButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="21" height="20" viewBox="0 0 21 20" fill="none"><path d="M2.52441 14.3751V17.5001H5.64941L14.8661 8.28346L11.7411 5.15846L2.52441 14.3751ZM17.2827 5.8668C17.6077 5.5418 17.6077 5.0168 17.2827 4.6918L15.3327 2.7418C15.0077 2.4168 14.4827 2.4168 14.1577 2.7418L12.6327 4.2668L15.7577 7.3918L17.2827 5.8668Z" fill="currentColor"/></svg>';
|
|
5226
|
+
editButton.addEventListener("click", () => {
|
|
5227
|
+
const onFigureClick = imageExtension?.options.onFigureClick;
|
|
5228
|
+
const pos = getPos();
|
|
5229
|
+
if (onFigureClick && typeof pos === "number") {
|
|
5230
|
+
onFigureClick(attrs, pos);
|
|
5231
|
+
}
|
|
5232
|
+
});
|
|
5233
|
+
imageContainer.appendChild(editButton);
|
|
5234
|
+
}
|
|
5235
|
+
const resizableView = new ResizableNodeView({
|
|
5236
|
+
element: imageContainer,
|
|
5237
|
+
node,
|
|
5238
|
+
getPos,
|
|
5239
|
+
onResize: (w, h) => {
|
|
5240
|
+
const { width, height } = constrainDimensions(w, h);
|
|
5241
|
+
updateImageDimensions(width, height);
|
|
5242
|
+
},
|
|
5243
|
+
onCommit: (w, h) => {
|
|
5244
|
+
const { width, height } = constrainDimensions(w, h);
|
|
5245
|
+
const pos = getPos();
|
|
5246
|
+
if (typeof pos === "number") {
|
|
5247
|
+
updateImageDimensions(Math.round(width), Math.round(height));
|
|
5248
|
+
editor.chain().focus().setNodeSelection(pos).updateAttributes("image", {
|
|
5249
|
+
width: Math.round(width),
|
|
5250
|
+
height: Math.round(height)
|
|
5251
|
+
}).run();
|
|
5252
|
+
}
|
|
5253
|
+
},
|
|
5254
|
+
onUpdate: (updatedNode) => {
|
|
5255
|
+
if (updatedNode.attrs.width) {
|
|
5256
|
+
imageContainer.style.width = `${updatedNode.attrs.width}px`;
|
|
5257
|
+
}
|
|
5258
|
+
if (updatedNode.attrs.height) {
|
|
5259
|
+
imageContainer.style.height = `${updatedNode.attrs.height}px`;
|
|
5260
|
+
}
|
|
5261
|
+
const existingCaption = figure.querySelector("figcaption");
|
|
5262
|
+
if (updatedNode.attrs.caption && !existingCaption) {
|
|
5263
|
+
const figcaption = document.createElement("figcaption");
|
|
5264
|
+
figcaption.textContent = updatedNode.attrs.caption;
|
|
5265
|
+
figure.appendChild(figcaption);
|
|
5266
|
+
} else if (existingCaption) {
|
|
5267
|
+
if (updatedNode.attrs.caption) {
|
|
5268
|
+
existingCaption.textContent = updatedNode.attrs.caption;
|
|
5269
|
+
} else {
|
|
5270
|
+
existingCaption.remove();
|
|
5271
|
+
}
|
|
5272
|
+
}
|
|
5273
|
+
if (updatedNode.type !== node.type) return false;
|
|
5274
|
+
return true;
|
|
5275
|
+
},
|
|
5276
|
+
options: {
|
|
5277
|
+
directions: resizeOptions.directions || [
|
|
5278
|
+
"bottom-right",
|
|
5279
|
+
"bottom-left",
|
|
5280
|
+
"top-right",
|
|
5281
|
+
"top-left"
|
|
5282
|
+
],
|
|
5283
|
+
min: {
|
|
5284
|
+
width: resizeOptions.minWidth || 100,
|
|
5285
|
+
height: resizeOptions.minHeight || 100
|
|
5286
|
+
},
|
|
5287
|
+
max: maxWidth && maxHeight ? { width: maxWidth, height: maxHeight } : void 0,
|
|
5288
|
+
preserveAspectRatio: true,
|
|
5289
|
+
className: {
|
|
5290
|
+
container: "tiptap-resize-container",
|
|
5291
|
+
wrapper: "tiptap-resize-wrapper",
|
|
5292
|
+
handle: "tiptap-resize-handle",
|
|
5293
|
+
resizing: "is-resizing"
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
});
|
|
5297
|
+
figure.appendChild(resizableView.dom);
|
|
5298
|
+
if (attrs.caption) {
|
|
5299
|
+
const figcaption = document.createElement("figcaption");
|
|
5300
|
+
figcaption.textContent = attrs.caption;
|
|
5301
|
+
figure.appendChild(figcaption);
|
|
5302
|
+
}
|
|
5303
|
+
return {
|
|
5304
|
+
dom: figure,
|
|
5305
|
+
contentDOM: resizableView.contentDOM,
|
|
5306
|
+
update: resizableView.update.bind(resizableView),
|
|
5307
|
+
destroy: resizableView.destroy?.bind(resizableView)
|
|
5308
|
+
};
|
|
5309
|
+
};
|
|
5144
5310
|
}
|
|
5145
5311
|
});
|
|
5146
5312
|
var LegacyFigure = BaseLegacyFigure.extend({
|
|
@@ -5174,8 +5340,14 @@ function getEditorExtensions(options) {
|
|
|
5174
5340
|
PromptHeader2,
|
|
5175
5341
|
PromptContent2,
|
|
5176
5342
|
Video2,
|
|
5177
|
-
|
|
5178
|
-
|
|
5343
|
+
Figure2.configure({
|
|
5344
|
+
getImageById,
|
|
5345
|
+
onFigureClick,
|
|
5346
|
+
resize: {
|
|
5347
|
+
enabled: true,
|
|
5348
|
+
directions: ["top-left", "top-right", "bottom-left", "bottom-right"]
|
|
5349
|
+
}
|
|
5350
|
+
}),
|
|
5179
5351
|
Mathematics.configure({
|
|
5180
5352
|
katexOptions: {
|
|
5181
5353
|
throwOnError: false
|
|
@@ -5618,7 +5790,7 @@ var filterCommandItems = (items, query) => {
|
|
|
5618
5790
|
};
|
|
5619
5791
|
|
|
5620
5792
|
// src/editor/commands/suggestion.tsx
|
|
5621
|
-
import { jsx as
|
|
5793
|
+
import { jsx as jsx91 } from "react/jsx-runtime";
|
|
5622
5794
|
var component = null;
|
|
5623
5795
|
var closeMenu = () => {
|
|
5624
5796
|
if (component) {
|
|
@@ -5632,7 +5804,7 @@ var mapCommandMenuItemToCommandItem = (item) => {
|
|
|
5632
5804
|
const IconComponent = item.icon;
|
|
5633
5805
|
return {
|
|
5634
5806
|
title: item.title,
|
|
5635
|
-
icon: /* @__PURE__ */
|
|
5807
|
+
icon: /* @__PURE__ */ jsx91(IconComponent, {}),
|
|
5636
5808
|
command: ({ editor, range }) => {
|
|
5637
5809
|
editor.chain().focus().deleteRange(range).run();
|
|
5638
5810
|
item.onClick(editor);
|
|
@@ -6063,7 +6235,7 @@ function getTranslations(lang) {
|
|
|
6063
6235
|
}
|
|
6064
6236
|
|
|
6065
6237
|
// src/editor/editor.tsx
|
|
6066
|
-
import { Fragment as Fragment3, jsx as
|
|
6238
|
+
import { Fragment as Fragment3, jsx as jsx92, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
6067
6239
|
function TiptapContent({
|
|
6068
6240
|
content,
|
|
6069
6241
|
handleChange,
|
|
@@ -6073,12 +6245,12 @@ function TiptapContent({
|
|
|
6073
6245
|
lang,
|
|
6074
6246
|
error
|
|
6075
6247
|
}) {
|
|
6076
|
-
const [linkDialogContext, setLinkDialogContext] =
|
|
6077
|
-
const [katexDialogContext, setKatexDialogContext] =
|
|
6248
|
+
const [linkDialogContext, setLinkDialogContext] = useState12(null);
|
|
6249
|
+
const [katexDialogContext, setKatexDialogContext] = useState12(
|
|
6078
6250
|
null
|
|
6079
6251
|
);
|
|
6080
|
-
const [editFigureContext, setEditFigureContext] =
|
|
6081
|
-
const [savedDialogCursorPos, setSavedDialogCursorPos] =
|
|
6252
|
+
const [editFigureContext, setEditFigureContext] = useState12(null);
|
|
6253
|
+
const [savedDialogCursorPos, setSavedDialogCursorPos] = useState12(void 0);
|
|
6082
6254
|
const { activeDialog, closeDialogCommand, openDialogCommand } = useDialogCommand();
|
|
6083
6255
|
const translations2 = useTiptapTranslations();
|
|
6084
6256
|
let safeContent;
|
|
@@ -6129,7 +6301,7 @@ function TiptapContent({
|
|
|
6129
6301
|
},
|
|
6130
6302
|
[lang]
|
|
6131
6303
|
);
|
|
6132
|
-
|
|
6304
|
+
useEffect9(() => {
|
|
6133
6305
|
if (activeDialog && editor && !editor.isDestroyed) {
|
|
6134
6306
|
const pos = editor.state.selection.from;
|
|
6135
6307
|
setSavedDialogCursorPos(pos);
|
|
@@ -6156,7 +6328,7 @@ function TiptapContent({
|
|
|
6156
6328
|
const katexHandler = createHandleKatexAdd(editor, handleCloseDialog, savedDialogCursorPos);
|
|
6157
6329
|
katexHandler(latex, katexDialogContext?.pos);
|
|
6158
6330
|
};
|
|
6159
|
-
|
|
6331
|
+
useEffect9(() => {
|
|
6160
6332
|
if (!editor || editor.isDestroyed) return;
|
|
6161
6333
|
editor.commands.setContent(safeContent, {
|
|
6162
6334
|
emitUpdate: false
|
|
@@ -6175,16 +6347,16 @@ function TiptapContent({
|
|
|
6175
6347
|
return true;
|
|
6176
6348
|
};
|
|
6177
6349
|
if (!editor) return null;
|
|
6178
|
-
return /* @__PURE__ */
|
|
6179
|
-
/* @__PURE__ */
|
|
6180
|
-
isEditable && !isDisabled && /* @__PURE__ */
|
|
6181
|
-
isEditable && !isDisabled && /* @__PURE__ */
|
|
6350
|
+
return /* @__PURE__ */ jsxs35(Fragment3, { children: [
|
|
6351
|
+
/* @__PURE__ */ jsx92(DragHandle, { editor }),
|
|
6352
|
+
isEditable && !isDisabled && /* @__PURE__ */ jsx92(TableMenu, { editor }),
|
|
6353
|
+
isEditable && !isDisabled && /* @__PURE__ */ jsx92(
|
|
6182
6354
|
BubbleMenu,
|
|
6183
6355
|
{
|
|
6184
6356
|
shouldShow: shouldBubbleMenuShow,
|
|
6185
6357
|
editor,
|
|
6186
6358
|
options: { placement: "bottom", offset: 8, flip: true },
|
|
6187
|
-
children: /* @__PURE__ */
|
|
6359
|
+
children: /* @__PURE__ */ jsx92(
|
|
6188
6360
|
BubbleMenuContent,
|
|
6189
6361
|
{
|
|
6190
6362
|
editor,
|
|
@@ -6193,19 +6365,19 @@ function TiptapContent({
|
|
|
6193
6365
|
)
|
|
6194
6366
|
}
|
|
6195
6367
|
),
|
|
6196
|
-
/* @__PURE__ */
|
|
6368
|
+
/* @__PURE__ */ jsxs35(
|
|
6197
6369
|
"div",
|
|
6198
6370
|
{
|
|
6199
6371
|
className: `tiptap-content-wrapper ${!!error ? "has-error" : ""} ${isDisabled ? "is-disabled" : ""}`,
|
|
6200
6372
|
children: [
|
|
6201
|
-
/* @__PURE__ */
|
|
6202
|
-
isEditable && !isDisabled && /* @__PURE__ */
|
|
6373
|
+
/* @__PURE__ */ jsx92(EditorContent, { editor }),
|
|
6374
|
+
isEditable && !isDisabled && /* @__PURE__ */ jsx92(CharacterCount, { editor })
|
|
6203
6375
|
]
|
|
6204
6376
|
}
|
|
6205
6377
|
),
|
|
6206
|
-
!!error && /* @__PURE__ */
|
|
6207
|
-
isEditable && /* @__PURE__ */
|
|
6208
|
-
activeDialog === "image" && /* @__PURE__ */
|
|
6378
|
+
!!error && /* @__PURE__ */ jsx92("p", { className: "tiptap-error-message", children: error }),
|
|
6379
|
+
isEditable && /* @__PURE__ */ jsxs35(Fragment3, { children: [
|
|
6380
|
+
activeDialog === "image" && /* @__PURE__ */ jsx92(
|
|
6209
6381
|
ImageDialog,
|
|
6210
6382
|
{
|
|
6211
6383
|
open: true,
|
|
@@ -6218,7 +6390,7 @@ function TiptapContent({
|
|
|
6218
6390
|
mode: editFigureContext ? "edit" : "add"
|
|
6219
6391
|
}
|
|
6220
6392
|
),
|
|
6221
|
-
activeDialog === "link" && /* @__PURE__ */
|
|
6393
|
+
activeDialog === "link" && /* @__PURE__ */ jsx92(
|
|
6222
6394
|
AddLinkDialog,
|
|
6223
6395
|
{
|
|
6224
6396
|
open: true,
|
|
@@ -6227,7 +6399,7 @@ function TiptapContent({
|
|
|
6227
6399
|
linkDialogContext
|
|
6228
6400
|
}
|
|
6229
6401
|
),
|
|
6230
|
-
activeDialog === "video" && /* @__PURE__ */
|
|
6402
|
+
activeDialog === "video" && /* @__PURE__ */ jsx92(
|
|
6231
6403
|
AddVideoDialog,
|
|
6232
6404
|
{
|
|
6233
6405
|
open: true,
|
|
@@ -6235,7 +6407,7 @@ function TiptapContent({
|
|
|
6235
6407
|
onVideoAdd: handleVideoAdd
|
|
6236
6408
|
}
|
|
6237
6409
|
),
|
|
6238
|
-
activeDialog === "katex" && /* @__PURE__ */
|
|
6410
|
+
activeDialog === "katex" && /* @__PURE__ */ jsx92(
|
|
6239
6411
|
AddKatexDialog,
|
|
6240
6412
|
{
|
|
6241
6413
|
open: true,
|
|
@@ -6250,7 +6422,7 @@ function TiptapContent({
|
|
|
6250
6422
|
var Tiptap = (props) => {
|
|
6251
6423
|
const { lang = "ru" } = props;
|
|
6252
6424
|
const translations2 = getTranslations(lang);
|
|
6253
|
-
return /* @__PURE__ */
|
|
6425
|
+
return /* @__PURE__ */ jsx92(TiptapTranslationsProvider, { translations: translations2, children: /* @__PURE__ */ jsx92(DialogCommandProvider, { children: /* @__PURE__ */ jsx92(TiptapContent, { ...props }) }) });
|
|
6254
6426
|
};
|
|
6255
6427
|
export {
|
|
6256
6428
|
Tiptap
|