@kopexa/tiptap 17.7.0 → 17.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2059 -1347
- package/dist/index.mjs +2063 -1322
- package/package.json +24 -24
package/dist/index.mjs
CHANGED
|
@@ -991,7 +991,7 @@ var ImageNode = TiptapImage.extend({
|
|
|
991
991
|
return ReactNodeViewRenderer2(ImageNodeView, {
|
|
992
992
|
stopEvent: ({ event }) => {
|
|
993
993
|
const target = event.target;
|
|
994
|
-
if (target.closest("button, [role='button'], input, a")) {
|
|
994
|
+
if (target instanceof HTMLElement && target.closest("button, [role='button'], input, a")) {
|
|
995
995
|
return true;
|
|
996
996
|
}
|
|
997
997
|
return false;
|
|
@@ -1350,7 +1350,7 @@ var ImageUploadNode = Node2.create({
|
|
|
1350
1350
|
return ReactNodeViewRenderer3(ImageUploadNodeView, {
|
|
1351
1351
|
stopEvent: ({ event }) => {
|
|
1352
1352
|
const target = event.target;
|
|
1353
|
-
if (target.closest("button, [role='button'], input, a")) {
|
|
1353
|
+
if (target instanceof HTMLElement && target.closest("button, [role='button'], input, a")) {
|
|
1354
1354
|
return true;
|
|
1355
1355
|
}
|
|
1356
1356
|
return false;
|
|
@@ -2743,6 +2743,7 @@ import * as React6 from "react";
|
|
|
2743
2743
|
|
|
2744
2744
|
// src/ui/suggestion-menu/suggestion-menu.tsx
|
|
2745
2745
|
import { FloatingPortal, flip, offset, shift, size } from "@floating-ui/react";
|
|
2746
|
+
import { useTiptapEditor } from "@kopexa/editor-utils";
|
|
2746
2747
|
import { PluginKey } from "@tiptap/pm/state";
|
|
2747
2748
|
import {
|
|
2748
2749
|
Suggestion,
|
|
@@ -2928,35 +2929,6 @@ function useMenuNavigation({
|
|
|
2928
2929
|
};
|
|
2929
2930
|
}
|
|
2930
2931
|
|
|
2931
|
-
// src/hooks/use-tiptap-editor.ts
|
|
2932
|
-
import { useCurrentEditor, useEditorState as useEditorState7 } from "@tiptap/react";
|
|
2933
|
-
import { useMemo as useMemo12 } from "react";
|
|
2934
|
-
function useTiptapEditor(providedEditor) {
|
|
2935
|
-
const { editor: coreEditor } = useCurrentEditor();
|
|
2936
|
-
const mainEditor = useMemo12(
|
|
2937
|
-
() => providedEditor || coreEditor,
|
|
2938
|
-
[providedEditor, coreEditor]
|
|
2939
|
-
);
|
|
2940
|
-
const editorState = useEditorState7({
|
|
2941
|
-
editor: mainEditor,
|
|
2942
|
-
selector(context) {
|
|
2943
|
-
if (!context.editor) {
|
|
2944
|
-
return {
|
|
2945
|
-
editor: null,
|
|
2946
|
-
editorState: void 0,
|
|
2947
|
-
canCommand: void 0
|
|
2948
|
-
};
|
|
2949
|
-
}
|
|
2950
|
-
return {
|
|
2951
|
-
editor: context.editor,
|
|
2952
|
-
editorState: context.editor.state,
|
|
2953
|
-
canCommand: context.editor.can
|
|
2954
|
-
};
|
|
2955
|
-
}
|
|
2956
|
-
});
|
|
2957
|
-
return editorState || { editor: null };
|
|
2958
|
-
}
|
|
2959
|
-
|
|
2960
2932
|
// src/ui/suggestion-menu/suggestion-menu-utils.ts
|
|
2961
2933
|
function calculateStartPosition(cursorPosition, previousNode, triggerChar) {
|
|
2962
2934
|
if (!(previousNode == null ? void 0 : previousNode.text) || !triggerChar) {
|
|
@@ -3434,11 +3406,290 @@ var Link = TiptapLink.extend({
|
|
|
3434
3406
|
}
|
|
3435
3407
|
});
|
|
3436
3408
|
|
|
3409
|
+
// src/extensions/node-alignment/index.ts
|
|
3410
|
+
import { getSelectedNodesOfType, updateNodesAttr } from "@kopexa/editor-utils";
|
|
3411
|
+
import { Extension } from "@tiptap/core";
|
|
3412
|
+
function getToggleValue(targets, attributeName, inputValue) {
|
|
3413
|
+
var _a, _b;
|
|
3414
|
+
if (targets.length === 0) return null;
|
|
3415
|
+
for (const target of targets) {
|
|
3416
|
+
const currentValue = (_b = (_a = target.node.attrs) == null ? void 0 : _a[attributeName]) != null ? _b : null;
|
|
3417
|
+
if (currentValue !== inputValue) {
|
|
3418
|
+
return inputValue;
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
return null;
|
|
3422
|
+
}
|
|
3423
|
+
var NodeAlignment = Extension.create({
|
|
3424
|
+
name: "nodeAlignment",
|
|
3425
|
+
addOptions() {
|
|
3426
|
+
return {
|
|
3427
|
+
types: ["paragraph", "heading", "blockquote", "tableCell", "tableHeader"],
|
|
3428
|
+
useStyle: true,
|
|
3429
|
+
textAlignValues: ["left", "center", "right", "justify"],
|
|
3430
|
+
verticalAlignValues: ["top", "middle", "bottom"]
|
|
3431
|
+
};
|
|
3432
|
+
},
|
|
3433
|
+
addGlobalAttributes() {
|
|
3434
|
+
return [
|
|
3435
|
+
{
|
|
3436
|
+
types: this.options.types,
|
|
3437
|
+
attributes: {
|
|
3438
|
+
nodeTextAlign: {
|
|
3439
|
+
default: null,
|
|
3440
|
+
parseHTML: (element) => {
|
|
3441
|
+
var _a;
|
|
3442
|
+
const styleAlign = (_a = element.style) == null ? void 0 : _a.textAlign;
|
|
3443
|
+
if (styleAlign && this.options.textAlignValues.includes(styleAlign)) {
|
|
3444
|
+
return styleAlign;
|
|
3445
|
+
}
|
|
3446
|
+
const dataAlign = element.getAttribute("data-node-text-align");
|
|
3447
|
+
if (dataAlign && this.options.textAlignValues.includes(dataAlign)) {
|
|
3448
|
+
return dataAlign;
|
|
3449
|
+
}
|
|
3450
|
+
return null;
|
|
3451
|
+
},
|
|
3452
|
+
renderHTML: (attributes) => {
|
|
3453
|
+
const align = attributes.nodeTextAlign;
|
|
3454
|
+
if (!align || !this.options.textAlignValues.includes(align))
|
|
3455
|
+
return {};
|
|
3456
|
+
if (this.options.useStyle) {
|
|
3457
|
+
return { style: `text-align: ${align}` };
|
|
3458
|
+
} else {
|
|
3459
|
+
return { "data-node-text-align": align };
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
},
|
|
3463
|
+
nodeVerticalAlign: {
|
|
3464
|
+
default: null,
|
|
3465
|
+
parseHTML: (element) => {
|
|
3466
|
+
var _a;
|
|
3467
|
+
const styleVAlign = (_a = element.style) == null ? void 0 : _a.verticalAlign;
|
|
3468
|
+
if (styleVAlign && this.options.verticalAlignValues.includes(styleVAlign)) {
|
|
3469
|
+
return styleVAlign;
|
|
3470
|
+
}
|
|
3471
|
+
const dataVAlign = element.getAttribute(
|
|
3472
|
+
"data-node-vertical-align"
|
|
3473
|
+
);
|
|
3474
|
+
if (dataVAlign && this.options.verticalAlignValues.includes(dataVAlign)) {
|
|
3475
|
+
return dataVAlign;
|
|
3476
|
+
}
|
|
3477
|
+
return null;
|
|
3478
|
+
},
|
|
3479
|
+
renderHTML: (attributes) => {
|
|
3480
|
+
const vAlign = attributes.nodeVerticalAlign;
|
|
3481
|
+
if (!vAlign || !this.options.verticalAlignValues.includes(vAlign))
|
|
3482
|
+
return {};
|
|
3483
|
+
if (this.options.useStyle) {
|
|
3484
|
+
return { style: `vertical-align: ${vAlign}` };
|
|
3485
|
+
} else {
|
|
3486
|
+
return { "data-node-vertical-align": vAlign };
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
];
|
|
3493
|
+
},
|
|
3494
|
+
addCommands() {
|
|
3495
|
+
const executeAlignmentCommand = (attributeName, getTargetValue) => {
|
|
3496
|
+
return (inputValue) => ({ state, tr }) => {
|
|
3497
|
+
const targets = getSelectedNodesOfType(
|
|
3498
|
+
state.selection,
|
|
3499
|
+
this.options.types
|
|
3500
|
+
);
|
|
3501
|
+
if (targets.length === 0) return false;
|
|
3502
|
+
const targetValue = getTargetValue(targets, inputValue);
|
|
3503
|
+
return updateNodesAttr(tr, targets, attributeName, targetValue);
|
|
3504
|
+
};
|
|
3505
|
+
};
|
|
3506
|
+
return {
|
|
3507
|
+
// TEXT ALIGN
|
|
3508
|
+
setNodeTextAlign: executeAlignmentCommand(
|
|
3509
|
+
"nodeTextAlign",
|
|
3510
|
+
(_, inputValue) => {
|
|
3511
|
+
if (!inputValue || !this.options.textAlignValues.includes(inputValue))
|
|
3512
|
+
return null;
|
|
3513
|
+
return inputValue;
|
|
3514
|
+
}
|
|
3515
|
+
),
|
|
3516
|
+
unsetNodeTextAlign: executeAlignmentCommand("nodeTextAlign", () => null),
|
|
3517
|
+
toggleNodeTextAlign: executeAlignmentCommand(
|
|
3518
|
+
"nodeTextAlign",
|
|
3519
|
+
(targets, inputValue) => {
|
|
3520
|
+
if (!inputValue || !this.options.textAlignValues.includes(inputValue))
|
|
3521
|
+
return null;
|
|
3522
|
+
return getToggleValue(targets, "nodeTextAlign", inputValue);
|
|
3523
|
+
}
|
|
3524
|
+
),
|
|
3525
|
+
// VERTICAL ALIGN
|
|
3526
|
+
setNodeVAlign: executeAlignmentCommand(
|
|
3527
|
+
"nodeVerticalAlign",
|
|
3528
|
+
(_, inputValue) => {
|
|
3529
|
+
if (!inputValue || !this.options.verticalAlignValues.includes(inputValue))
|
|
3530
|
+
return null;
|
|
3531
|
+
return inputValue;
|
|
3532
|
+
}
|
|
3533
|
+
),
|
|
3534
|
+
unsetNodeVAlign: executeAlignmentCommand("nodeVerticalAlign", () => null),
|
|
3535
|
+
toggleNodeVAlign: executeAlignmentCommand(
|
|
3536
|
+
"nodeVerticalAlign",
|
|
3537
|
+
(targets, inputValue) => {
|
|
3538
|
+
if (!inputValue || !this.options.verticalAlignValues.includes(inputValue))
|
|
3539
|
+
return null;
|
|
3540
|
+
return getToggleValue(targets, "nodeVerticalAlign", inputValue);
|
|
3541
|
+
}
|
|
3542
|
+
),
|
|
3543
|
+
// BOTH
|
|
3544
|
+
setNodeAlignment: (textAlign, verticalAlign) => ({ state, tr }) => {
|
|
3545
|
+
const targets = getSelectedNodesOfType(
|
|
3546
|
+
state.selection,
|
|
3547
|
+
this.options.types
|
|
3548
|
+
);
|
|
3549
|
+
if (targets.length === 0) return false;
|
|
3550
|
+
let hasChanges = false;
|
|
3551
|
+
for (const { node, pos } of targets) {
|
|
3552
|
+
const newAttrs = { ...node.attrs };
|
|
3553
|
+
if (textAlign && this.options.textAlignValues.includes(textAlign)) {
|
|
3554
|
+
newAttrs.nodeTextAlign = textAlign;
|
|
3555
|
+
hasChanges = true;
|
|
3556
|
+
}
|
|
3557
|
+
if (verticalAlign && this.options.verticalAlignValues.includes(verticalAlign)) {
|
|
3558
|
+
newAttrs.nodeVerticalAlign = verticalAlign;
|
|
3559
|
+
hasChanges = true;
|
|
3560
|
+
}
|
|
3561
|
+
if (hasChanges) tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
3562
|
+
}
|
|
3563
|
+
return hasChanges;
|
|
3564
|
+
},
|
|
3565
|
+
unsetNodeAlignment: () => ({ state, tr }) => {
|
|
3566
|
+
var _a, _b, _c, _d;
|
|
3567
|
+
const targets = getSelectedNodesOfType(
|
|
3568
|
+
state.selection,
|
|
3569
|
+
this.options.types
|
|
3570
|
+
);
|
|
3571
|
+
if (targets.length === 0) return false;
|
|
3572
|
+
let hasChanges = false;
|
|
3573
|
+
for (const { node, pos } of targets) {
|
|
3574
|
+
const hasText = (_b = (_a = node.attrs) == null ? void 0 : _a.nodeTextAlign) != null ? _b : null;
|
|
3575
|
+
const hasV = (_d = (_c = node.attrs) == null ? void 0 : _c.nodeVerticalAlign) != null ? _d : null;
|
|
3576
|
+
if (hasText || hasV) {
|
|
3577
|
+
const newAttrs = {
|
|
3578
|
+
...node.attrs,
|
|
3579
|
+
nodeTextAlign: null,
|
|
3580
|
+
nodeVerticalAlign: null
|
|
3581
|
+
};
|
|
3582
|
+
tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
3583
|
+
hasChanges = true;
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3586
|
+
return hasChanges;
|
|
3587
|
+
}
|
|
3588
|
+
};
|
|
3589
|
+
}
|
|
3590
|
+
});
|
|
3591
|
+
|
|
3592
|
+
// src/extensions/node-background/index.ts
|
|
3593
|
+
import { getSelectedNodesOfType as getSelectedNodesOfType2, updateNodesAttr as updateNodesAttr2 } from "@kopexa/editor-utils";
|
|
3594
|
+
import { Extension as Extension2 } from "@tiptap/core";
|
|
3595
|
+
function getToggleColor(targets, inputColor) {
|
|
3596
|
+
var _a, _b;
|
|
3597
|
+
if (targets.length === 0) return null;
|
|
3598
|
+
for (const target of targets) {
|
|
3599
|
+
const currentColor = (_b = (_a = target.node.attrs) == null ? void 0 : _a.backgroundColor) != null ? _b : null;
|
|
3600
|
+
if (currentColor !== inputColor) {
|
|
3601
|
+
return inputColor;
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
return null;
|
|
3605
|
+
}
|
|
3606
|
+
var NodeBackground = Extension2.create({
|
|
3607
|
+
name: "nodeBackground",
|
|
3608
|
+
addOptions() {
|
|
3609
|
+
return {
|
|
3610
|
+
types: [
|
|
3611
|
+
"paragraph",
|
|
3612
|
+
"heading",
|
|
3613
|
+
"blockquote",
|
|
3614
|
+
"taskList",
|
|
3615
|
+
"bulletList",
|
|
3616
|
+
"orderedList",
|
|
3617
|
+
"tableCell",
|
|
3618
|
+
"tableHeader"
|
|
3619
|
+
],
|
|
3620
|
+
useStyle: true
|
|
3621
|
+
};
|
|
3622
|
+
},
|
|
3623
|
+
addGlobalAttributes() {
|
|
3624
|
+
return [
|
|
3625
|
+
{
|
|
3626
|
+
types: this.options.types,
|
|
3627
|
+
attributes: {
|
|
3628
|
+
backgroundColor: {
|
|
3629
|
+
default: null,
|
|
3630
|
+
parseHTML: (element) => {
|
|
3631
|
+
var _a;
|
|
3632
|
+
const styleColor = (_a = element.style) == null ? void 0 : _a.backgroundColor;
|
|
3633
|
+
if (styleColor) return styleColor;
|
|
3634
|
+
const dataColor = element.getAttribute("data-background-color");
|
|
3635
|
+
return dataColor || null;
|
|
3636
|
+
},
|
|
3637
|
+
renderHTML: (attributes) => {
|
|
3638
|
+
const color = attributes.backgroundColor;
|
|
3639
|
+
if (!color) return {};
|
|
3640
|
+
if (this.options.useStyle) {
|
|
3641
|
+
return {
|
|
3642
|
+
style: `background-color: ${color}`
|
|
3643
|
+
};
|
|
3644
|
+
} else {
|
|
3645
|
+
return {
|
|
3646
|
+
"data-background-color": color
|
|
3647
|
+
};
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
];
|
|
3654
|
+
},
|
|
3655
|
+
addCommands() {
|
|
3656
|
+
const executeBackgroundCommand = (getTargetColor) => {
|
|
3657
|
+
return (inputColor) => ({ state, tr }) => {
|
|
3658
|
+
const targets = getSelectedNodesOfType2(
|
|
3659
|
+
state.selection,
|
|
3660
|
+
this.options.types
|
|
3661
|
+
);
|
|
3662
|
+
if (targets.length === 0) return false;
|
|
3663
|
+
const targetColor = getTargetColor(targets, inputColor);
|
|
3664
|
+
return updateNodesAttr2(tr, targets, "backgroundColor", targetColor);
|
|
3665
|
+
};
|
|
3666
|
+
};
|
|
3667
|
+
return {
|
|
3668
|
+
/**
|
|
3669
|
+
* Set background color to specific value
|
|
3670
|
+
*/
|
|
3671
|
+
setNodeBackgroundColor: executeBackgroundCommand(
|
|
3672
|
+
(_, inputColor) => inputColor || null
|
|
3673
|
+
),
|
|
3674
|
+
/**
|
|
3675
|
+
* Remove background color
|
|
3676
|
+
*/
|
|
3677
|
+
unsetNodeBackgroundColor: executeBackgroundCommand(() => null),
|
|
3678
|
+
/**
|
|
3679
|
+
* Toggle background color (set if different/missing, unset if all have it)
|
|
3680
|
+
*/
|
|
3681
|
+
toggleNodeBackgroundColor: executeBackgroundCommand(
|
|
3682
|
+
(targets, inputColor) => getToggleColor(targets, inputColor || "")
|
|
3683
|
+
)
|
|
3684
|
+
};
|
|
3685
|
+
}
|
|
3686
|
+
});
|
|
3687
|
+
|
|
3437
3688
|
// src/extensions/selection/index.ts
|
|
3438
3689
|
import { Plugin as Plugin2, PluginKey as PluginKey4 } from "@tiptap/pm/state";
|
|
3439
3690
|
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
3440
|
-
import { Extension, isNodeSelection } from "@tiptap/react";
|
|
3441
|
-
var Selection =
|
|
3691
|
+
import { Extension as Extension3, isNodeSelection } from "@tiptap/react";
|
|
3692
|
+
var Selection = Extension3.create({
|
|
3442
3693
|
name: "selection",
|
|
3443
3694
|
addProseMirrorPlugins() {
|
|
3444
3695
|
const { editor } = this;
|
|
@@ -3470,7 +3721,7 @@ var Selection = Extension.create({
|
|
|
3470
3721
|
|
|
3471
3722
|
// src/extensions/trailing-node/index.ts
|
|
3472
3723
|
import { Plugin as Plugin3, PluginKey as PluginKey5 } from "@tiptap/pm/state";
|
|
3473
|
-
import { Extension as
|
|
3724
|
+
import { Extension as Extension4 } from "@tiptap/react";
|
|
3474
3725
|
function nodeEqualsType({
|
|
3475
3726
|
types,
|
|
3476
3727
|
node
|
|
@@ -3481,7 +3732,7 @@ function nodeEqualsType({
|
|
|
3481
3732
|
}
|
|
3482
3733
|
return node.type === types;
|
|
3483
3734
|
}
|
|
3484
|
-
var TrailingNode =
|
|
3735
|
+
var TrailingNode = Extension4.create({
|
|
3485
3736
|
name: "trailingNode",
|
|
3486
3737
|
addOptions() {
|
|
3487
3738
|
return {
|
|
@@ -3527,7 +3778,7 @@ var TrailingNode = Extension2.create({
|
|
|
3527
3778
|
});
|
|
3528
3779
|
|
|
3529
3780
|
// src/extensions/ui-state/index.ts
|
|
3530
|
-
import { Extension as
|
|
3781
|
+
import { Extension as Extension5 } from "@tiptap/core";
|
|
3531
3782
|
var defaultUiState = {
|
|
3532
3783
|
aiGenerationIsSelection: false,
|
|
3533
3784
|
aiGenerationIsLoading: false,
|
|
@@ -3537,7 +3788,7 @@ var defaultUiState = {
|
|
|
3537
3788
|
lockDragHandle: false,
|
|
3538
3789
|
isDragging: false
|
|
3539
3790
|
};
|
|
3540
|
-
var UiState =
|
|
3791
|
+
var UiState = Extension5.create({
|
|
3541
3792
|
name: "uiState",
|
|
3542
3793
|
addStorage() {
|
|
3543
3794
|
return {
|
|
@@ -3862,6 +4113,8 @@ function getExtensions({
|
|
|
3862
4113
|
}),
|
|
3863
4114
|
UiState,
|
|
3864
4115
|
TableKit,
|
|
4116
|
+
NodeAlignment,
|
|
4117
|
+
NodeBackground,
|
|
3865
4118
|
TocNode,
|
|
3866
4119
|
CalloutNode,
|
|
3867
4120
|
MathBlock,
|
|
@@ -4010,6 +4263,11 @@ async function handleFileUpload(editor, file, fileHandler, pos) {
|
|
|
4010
4263
|
}
|
|
4011
4264
|
|
|
4012
4265
|
// src/presets/basic/index.tsx
|
|
4266
|
+
import {
|
|
4267
|
+
TableCellHandleMenu,
|
|
4268
|
+
TableHandle,
|
|
4269
|
+
TableSelectionOverlay
|
|
4270
|
+
} from "@kopexa/extension-table";
|
|
4013
4271
|
import {
|
|
4014
4272
|
editorBasic,
|
|
4015
4273
|
editorSpinner
|
|
@@ -4018,17 +4276,17 @@ import {
|
|
|
4018
4276
|
EditorContent,
|
|
4019
4277
|
EditorContext
|
|
4020
4278
|
} from "@tiptap/react";
|
|
4021
|
-
import { useCallback as
|
|
4279
|
+
import { useCallback as useCallback38, useContext as useContext4 } from "react";
|
|
4022
4280
|
|
|
4023
4281
|
// src/context/editor-context.ts
|
|
4024
4282
|
import { createContext as createContext4 } from "@kopexa/react-utils";
|
|
4025
4283
|
var [EditorUIProvider, useEditorUIContext] = createContext4();
|
|
4026
4284
|
|
|
4027
4285
|
// src/hooks/use-ui-editor-state.ts
|
|
4028
|
-
import { useEditorState as
|
|
4286
|
+
import { useEditorState as useEditorState7 } from "@tiptap/react";
|
|
4029
4287
|
function useUiEditorState(editor) {
|
|
4030
4288
|
var _a;
|
|
4031
|
-
return (_a =
|
|
4289
|
+
return (_a = useEditorState7({
|
|
4032
4290
|
editor,
|
|
4033
4291
|
selector: ({ editor: editor2 }) => {
|
|
4034
4292
|
if (!editor2) return defaultUiState;
|
|
@@ -4050,6 +4308,7 @@ import { BubbleMenu as TiptapBubbleMenu } from "@tiptap/react/menus";
|
|
|
4050
4308
|
|
|
4051
4309
|
// src/ui/link-popover/link-popover.tsx
|
|
4052
4310
|
import { IconButton as IconButton6 } from "@kopexa/button";
|
|
4311
|
+
import { useTiptapEditor as useTiptapEditor3 } from "@kopexa/editor-utils";
|
|
4053
4312
|
import {
|
|
4054
4313
|
CheckIcon,
|
|
4055
4314
|
EditIcon as EditIcon2,
|
|
@@ -4063,7 +4322,7 @@ import { ToolbarButton } from "@kopexa/toolbar";
|
|
|
4063
4322
|
import { useCallback as useCallback14, useEffect as useEffect16, useState as useState15 } from "react";
|
|
4064
4323
|
|
|
4065
4324
|
// src/ui/link-popover/use-link-popover.ts
|
|
4066
|
-
import { isMarkInSchema } from "@kopexa/editor-utils";
|
|
4325
|
+
import { isMarkInSchema, useTiptapEditor as useTiptapEditor2 } from "@kopexa/editor-utils";
|
|
4067
4326
|
import { LinkIcon } from "@kopexa/icons";
|
|
4068
4327
|
import * as React7 from "react";
|
|
4069
4328
|
|
|
@@ -4269,7 +4528,7 @@ function useLinkPopover(config) {
|
|
|
4269
4528
|
hideWhenUnavailable = false,
|
|
4270
4529
|
onSetLink
|
|
4271
4530
|
} = config || {};
|
|
4272
|
-
const { editor } =
|
|
4531
|
+
const { editor } = useTiptapEditor2(providedEditor);
|
|
4273
4532
|
const { isVisible, canSet, isActive } = useLinkState({
|
|
4274
4533
|
editor,
|
|
4275
4534
|
hideWhenUnavailable
|
|
@@ -4432,7 +4691,7 @@ function LinkPopover({
|
|
|
4432
4691
|
children,
|
|
4433
4692
|
...buttonProps
|
|
4434
4693
|
}) {
|
|
4435
|
-
const { editor } =
|
|
4694
|
+
const { editor } = useTiptapEditor3(providedEditor);
|
|
4436
4695
|
const [isOpen, setIsOpen] = useState15(false);
|
|
4437
4696
|
const {
|
|
4438
4697
|
isVisible,
|
|
@@ -4519,7 +4778,11 @@ function LinkPopover({
|
|
|
4519
4778
|
LinkButton.displayName = "LinkButton";
|
|
4520
4779
|
|
|
4521
4780
|
// src/ui/mark-button/index.tsx
|
|
4522
|
-
import {
|
|
4781
|
+
import {
|
|
4782
|
+
isMarkInSchema as isMarkInSchema2,
|
|
4783
|
+
isNodeTypeSelected,
|
|
4784
|
+
useTiptapEditor as useTiptapEditor4
|
|
4785
|
+
} from "@kopexa/editor-utils";
|
|
4523
4786
|
import {
|
|
4524
4787
|
BoldIcon,
|
|
4525
4788
|
CodeIcon,
|
|
@@ -4531,7 +4794,7 @@ import {
|
|
|
4531
4794
|
} from "@kopexa/icons";
|
|
4532
4795
|
import { ToolbarButton as ToolbarButton2 } from "@kopexa/toolbar";
|
|
4533
4796
|
import { isNodeSelection as isNodeSelection2 } from "@tiptap/react";
|
|
4534
|
-
import { useCallback as useCallback15, useMemo as
|
|
4797
|
+
import { useCallback as useCallback15, useMemo as useMemo13 } from "react";
|
|
4535
4798
|
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
4536
4799
|
var markIcons = {
|
|
4537
4800
|
bold: BoldIcon,
|
|
@@ -4614,7 +4877,7 @@ var MarkButton = ({
|
|
|
4614
4877
|
children,
|
|
4615
4878
|
...buttonProps
|
|
4616
4879
|
}) => {
|
|
4617
|
-
const { editor } =
|
|
4880
|
+
const { editor } = useTiptapEditor4(providedEditor);
|
|
4618
4881
|
const {
|
|
4619
4882
|
markInSchema,
|
|
4620
4883
|
isDisabled,
|
|
@@ -4632,7 +4895,7 @@ var MarkButton = ({
|
|
|
4632
4895
|
},
|
|
4633
4896
|
[onClick, isDisabled, editor, type]
|
|
4634
4897
|
);
|
|
4635
|
-
const show =
|
|
4898
|
+
const show = useMemo13(() => {
|
|
4636
4899
|
return shouldShowMarkButton({
|
|
4637
4900
|
editor,
|
|
4638
4901
|
type,
|
|
@@ -4707,7 +4970,7 @@ function BubbleMenu({ editor }) {
|
|
|
4707
4970
|
}
|
|
4708
4971
|
|
|
4709
4972
|
// src/ui/copy-anchor-link-button/use-scroll-to-hash.ts
|
|
4710
|
-
import { getEditorExtension } from "@kopexa/editor-utils";
|
|
4973
|
+
import { getEditorExtension, useTiptapEditor as useTiptapEditor5 } from "@kopexa/editor-utils";
|
|
4711
4974
|
import * as React9 from "react";
|
|
4712
4975
|
|
|
4713
4976
|
// src/hooks/use-floating-toolbar-visibility.ts
|
|
@@ -4732,7 +4995,7 @@ function useScrollToHash(config = {}) {
|
|
|
4732
4995
|
onTargetNotFound = () => {
|
|
4733
4996
|
}
|
|
4734
4997
|
} = config;
|
|
4735
|
-
const { editor } =
|
|
4998
|
+
const { editor } = useTiptapEditor5(providedEditor);
|
|
4736
4999
|
const scrollToNode = React9.useCallback(
|
|
4737
5000
|
(id) => {
|
|
4738
5001
|
var _a, _b, _c;
|
|
@@ -4997,7 +5260,11 @@ import {
|
|
|
4997
5260
|
import * as React10 from "react";
|
|
4998
5261
|
|
|
4999
5262
|
// src/ui/table-button/use-table.ts
|
|
5000
|
-
import {
|
|
5263
|
+
import {
|
|
5264
|
+
isNodeInSchema,
|
|
5265
|
+
isNodeTypeSelected as isNodeTypeSelected2,
|
|
5266
|
+
useTiptapEditor as useTiptapEditor6
|
|
5267
|
+
} from "@kopexa/editor-utils";
|
|
5001
5268
|
import { TableIcon } from "@kopexa/icons";
|
|
5002
5269
|
import { isNodeSelection as isNodeSelection4 } from "@tiptap/react";
|
|
5003
5270
|
import { useCallback as useCallback18, useEffect as useEffect20, useState as useState18 } from "react";
|
|
@@ -5043,7 +5310,7 @@ function useTableBlock(config) {
|
|
|
5043
5310
|
hideWhenUnavailable = false,
|
|
5044
5311
|
onToggled
|
|
5045
5312
|
} = config || {};
|
|
5046
|
-
const { editor } =
|
|
5313
|
+
const { editor } = useTiptapEditor6(providedEditor);
|
|
5047
5314
|
const [isVisible, setIsVisible] = useState18(true);
|
|
5048
5315
|
const canToggleState = canToggle(editor);
|
|
5049
5316
|
const isActive = (editor == null ? void 0 : editor.isActive("table")) || false;
|
|
@@ -5604,6 +5871,7 @@ var List = ({
|
|
|
5604
5871
|
};
|
|
5605
5872
|
|
|
5606
5873
|
// src/presets/basic/editor-header.tsx
|
|
5874
|
+
import { useTiptapEditor as useTiptapEditor26 } from "@kopexa/editor-utils";
|
|
5607
5875
|
import { MoreVerticalIcon } from "@kopexa/icons";
|
|
5608
5876
|
import { Popover as Popover3 } from "@kopexa/popover";
|
|
5609
5877
|
import {
|
|
@@ -5612,8 +5880,8 @@ import {
|
|
|
5612
5880
|
ToolbarGroup as ToolbarGroup2,
|
|
5613
5881
|
ToolbarSeparator as ToolbarSeparator3
|
|
5614
5882
|
} from "@kopexa/toolbar";
|
|
5615
|
-
import { useIsMobile as
|
|
5616
|
-
import { useEffect as
|
|
5883
|
+
import { useIsMobile as useIsMobile3 } from "@kopexa/use-is-mobile";
|
|
5884
|
+
import { useEffect as useEffect31, useRef as useRef11, useState as useState30 } from "react";
|
|
5617
5885
|
|
|
5618
5886
|
// src/hooks/use-cursor-visibility.ts
|
|
5619
5887
|
import * as React13 from "react";
|
|
@@ -5717,99 +5985,126 @@ function useCursorVisibility({
|
|
|
5717
5985
|
return rect;
|
|
5718
5986
|
}
|
|
5719
5987
|
|
|
5720
|
-
// src/ui/
|
|
5988
|
+
// src/ui/color-highlight-popover/color-highlight-popover.tsx
|
|
5989
|
+
import { IconButton as IconButton8 } from "@kopexa/button";
|
|
5990
|
+
import { useTiptapEditor as useTiptapEditor9 } from "@kopexa/editor-utils";
|
|
5991
|
+
import { BanIcon, HighlighterIcon as HighlighterIcon2 } from "@kopexa/icons";
|
|
5992
|
+
import { Popover as Popover2 } from "@kopexa/popover";
|
|
5993
|
+
import { ToolbarSeparator as ToolbarSeparator2 } from "@kopexa/toolbar";
|
|
5994
|
+
import { useMemo as useMemo16, useRef as useRef10, useState as useState22 } from "react";
|
|
5995
|
+
|
|
5996
|
+
// src/ui/color-highlight-button/color-highlight-button.tsx
|
|
5997
|
+
import { useTiptapEditor as useTiptapEditor8 } from "@kopexa/editor-utils";
|
|
5998
|
+
import { colorHighlightButton } from "@kopexa/theme";
|
|
5721
5999
|
import { ToolbarButton as ToolbarButton3 } from "@kopexa/toolbar";
|
|
5722
|
-
import
|
|
6000
|
+
import { useCallback as useCallback22, useMemo as useMemo15 } from "react";
|
|
5723
6001
|
|
|
5724
|
-
// src/ui/
|
|
6002
|
+
// src/ui/color-highlight-button/use-color-highlight.ts
|
|
5725
6003
|
import {
|
|
5726
|
-
|
|
5727
|
-
isNodeInSchema as isNodeInSchema3,
|
|
6004
|
+
isMarkInSchema as isMarkInSchema3,
|
|
5728
6005
|
isNodeTypeSelected as isNodeTypeSelected3,
|
|
5729
|
-
|
|
6006
|
+
useTiptapEditor as useTiptapEditor7
|
|
5730
6007
|
} from "@kopexa/editor-utils";
|
|
5731
|
-
import {
|
|
5732
|
-
import {
|
|
6008
|
+
import { HighlighterIcon } from "@kopexa/icons";
|
|
6009
|
+
import { useIsMobile } from "@kopexa/use-is-mobile";
|
|
5733
6010
|
import * as React14 from "react";
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
6011
|
+
import { useHotkeys } from "react-hotkeys-hook";
|
|
6012
|
+
var COLOR_HIGHLIGHT_SHORTCUT_KEY = "mod+shift+h";
|
|
6013
|
+
var HIGHLIGHT_COLORS = [
|
|
6014
|
+
{
|
|
6015
|
+
label: "Default background",
|
|
6016
|
+
value: "var(--tt-bg-color)",
|
|
6017
|
+
border: "var(--tt-bg-color-contrast)"
|
|
6018
|
+
},
|
|
6019
|
+
{
|
|
6020
|
+
label: "Gray background",
|
|
6021
|
+
value: "var(--tt-color-highlight-gray)",
|
|
6022
|
+
border: "var(--tt-color-highlight-gray-contrast)"
|
|
6023
|
+
},
|
|
6024
|
+
{
|
|
6025
|
+
label: "Brown background",
|
|
6026
|
+
value: "var(--tt-color-highlight-brown)",
|
|
6027
|
+
border: "var(--tt-color-highlight-brown-contrast)"
|
|
6028
|
+
},
|
|
6029
|
+
{
|
|
6030
|
+
label: "Orange background",
|
|
6031
|
+
value: "var(--tt-color-highlight-orange)",
|
|
6032
|
+
border: "var(--tt-color-highlight-orange-contrast)"
|
|
6033
|
+
},
|
|
6034
|
+
{
|
|
6035
|
+
label: "Yellow background",
|
|
6036
|
+
value: "var(--tt-color-highlight-yellow)",
|
|
6037
|
+
border: "var(--tt-color-highlight-yellow-contrast)"
|
|
6038
|
+
},
|
|
6039
|
+
{
|
|
6040
|
+
label: "Green background",
|
|
6041
|
+
value: "var(--tt-color-highlight-green)",
|
|
6042
|
+
border: "var(--tt-color-highlight-green-contrast)"
|
|
6043
|
+
},
|
|
6044
|
+
{
|
|
6045
|
+
label: "Blue background",
|
|
6046
|
+
value: "var(--tt-color-highlight-blue)",
|
|
6047
|
+
border: "var(--tt-color-highlight-blue-contrast)"
|
|
6048
|
+
},
|
|
6049
|
+
{
|
|
6050
|
+
label: "Purple background",
|
|
6051
|
+
value: "var(--tt-color-highlight-purple)",
|
|
6052
|
+
border: "var(--tt-color-highlight-purple-contrast)"
|
|
6053
|
+
},
|
|
6054
|
+
{
|
|
6055
|
+
label: "Pink background",
|
|
6056
|
+
value: "var(--tt-color-highlight-pink)",
|
|
6057
|
+
border: "var(--tt-color-highlight-pink-contrast)"
|
|
6058
|
+
},
|
|
6059
|
+
{
|
|
6060
|
+
label: "Red background",
|
|
6061
|
+
value: "var(--tt-color-highlight-red)",
|
|
6062
|
+
border: "var(--tt-color-highlight-red-contrast)"
|
|
5757
6063
|
}
|
|
6064
|
+
];
|
|
6065
|
+
function pickHighlightColorsByValue(values) {
|
|
6066
|
+
const colorMap = new Map(
|
|
6067
|
+
HIGHLIGHT_COLORS.map((color) => [color.value, color])
|
|
6068
|
+
);
|
|
6069
|
+
return values.map((value) => colorMap.get(value)).filter((color) => !!color);
|
|
5758
6070
|
}
|
|
5759
|
-
function
|
|
5760
|
-
var _a, _b, _c;
|
|
6071
|
+
function canColorHighlight(editor) {
|
|
5761
6072
|
if (!editor || !editor.isEditable) return false;
|
|
5762
|
-
if (!
|
|
5763
|
-
try {
|
|
5764
|
-
const view = editor.view;
|
|
5765
|
-
let state = view.state;
|
|
5766
|
-
let tr = state.tr;
|
|
5767
|
-
if (state.selection.empty || state.selection instanceof TextSelection2) {
|
|
5768
|
-
const pos = (_a = findNodePosition({
|
|
5769
|
-
editor,
|
|
5770
|
-
node: state.selection.$anchor.node(1)
|
|
5771
|
-
})) == null ? void 0 : _a.pos;
|
|
5772
|
-
if (!isValidPosition(pos)) return false;
|
|
5773
|
-
tr = tr.setSelection(NodeSelection2.create(state.doc, pos));
|
|
5774
|
-
view.dispatch(tr);
|
|
5775
|
-
state = view.state;
|
|
5776
|
-
}
|
|
5777
|
-
const selection = state.selection;
|
|
5778
|
-
let chain = editor.chain().focus();
|
|
5779
|
-
if (selection instanceof NodeSelection2) {
|
|
5780
|
-
const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
|
|
5781
|
-
const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
|
|
5782
|
-
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
5783
|
-
const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
|
|
5784
|
-
chain = chain.setTextSelection({ from, to }).clearNodes();
|
|
5785
|
-
}
|
|
5786
|
-
const toggle = editor.isActive("blockquote") ? chain.lift("blockquote") : chain.wrapIn("blockquote");
|
|
5787
|
-
toggle.run();
|
|
5788
|
-
editor.chain().focus().selectTextblockEnd().run();
|
|
5789
|
-
return true;
|
|
5790
|
-
} catch {
|
|
6073
|
+
if (!isMarkInSchema3("highlight", editor) || isNodeTypeSelected3(editor, ["image"]))
|
|
5791
6074
|
return false;
|
|
5792
|
-
|
|
6075
|
+
return editor.can().setMark("highlight");
|
|
5793
6076
|
}
|
|
5794
|
-
function
|
|
5795
|
-
const { editor, hideWhenUnavailable } = props;
|
|
6077
|
+
function isColorHighlightActive(editor, highlightColor) {
|
|
5796
6078
|
if (!editor || !editor.isEditable) return false;
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
6079
|
+
return highlightColor ? editor.isActive("highlight", { color: highlightColor }) : editor.isActive("highlight");
|
|
6080
|
+
}
|
|
6081
|
+
function removeHighlight(editor) {
|
|
6082
|
+
if (!editor || !editor.isEditable) return false;
|
|
6083
|
+
if (!canColorHighlight(editor)) return false;
|
|
6084
|
+
return editor.chain().focus().unsetMark("highlight").run();
|
|
6085
|
+
}
|
|
6086
|
+
function shouldShowButton2(props) {
|
|
6087
|
+
const { editor, hideWhenUnavailable } = props;
|
|
6088
|
+
if (!editor || !editor.isEditable) return false;
|
|
6089
|
+
if (!isMarkInSchema3("highlight", editor)) return false;
|
|
6090
|
+
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
6091
|
+
return canColorHighlight(editor);
|
|
6092
|
+
}
|
|
5801
6093
|
return true;
|
|
5802
6094
|
}
|
|
5803
|
-
function
|
|
6095
|
+
function useColorHighlight(config) {
|
|
5804
6096
|
const {
|
|
5805
6097
|
editor: providedEditor,
|
|
6098
|
+
label,
|
|
6099
|
+
highlightColor,
|
|
5806
6100
|
hideWhenUnavailable = false,
|
|
5807
|
-
|
|
5808
|
-
} = config
|
|
5809
|
-
const { editor } =
|
|
6101
|
+
onApplied
|
|
6102
|
+
} = config;
|
|
6103
|
+
const { editor } = useTiptapEditor7(providedEditor);
|
|
6104
|
+
const isMobile = useIsMobile();
|
|
5810
6105
|
const [isVisible, setIsVisible] = React14.useState(true);
|
|
5811
|
-
const
|
|
5812
|
-
const isActive = (editor
|
|
6106
|
+
const canColorHighlightState = canColorHighlight(editor);
|
|
6107
|
+
const isActive = isColorHighlightActive(editor, highlightColor);
|
|
5813
6108
|
React14.useEffect(() => {
|
|
5814
6109
|
if (!editor) return;
|
|
5815
6110
|
const handleSelectionUpdate = () => {
|
|
@@ -5821,1062 +6116,1320 @@ function useBlockquote(config) {
|
|
|
5821
6116
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
5822
6117
|
};
|
|
5823
6118
|
}, [editor, hideWhenUnavailable]);
|
|
5824
|
-
const
|
|
5825
|
-
if (!editor
|
|
5826
|
-
|
|
6119
|
+
const handleColorHighlight = React14.useCallback(() => {
|
|
6120
|
+
if (!editor || !canColorHighlightState || !highlightColor || !label)
|
|
6121
|
+
return false;
|
|
6122
|
+
if (editor.state.storedMarks) {
|
|
6123
|
+
const highlightMarkType = editor.schema.marks.highlight;
|
|
6124
|
+
if (highlightMarkType) {
|
|
6125
|
+
editor.view.dispatch(
|
|
6126
|
+
editor.state.tr.removeStoredMark(highlightMarkType)
|
|
6127
|
+
);
|
|
6128
|
+
}
|
|
6129
|
+
}
|
|
6130
|
+
setTimeout(() => {
|
|
6131
|
+
const success = editor.chain().focus().toggleMark("highlight", { color: highlightColor }).run();
|
|
6132
|
+
if (success) {
|
|
6133
|
+
onApplied == null ? void 0 : onApplied({ color: highlightColor, label });
|
|
6134
|
+
}
|
|
6135
|
+
return success;
|
|
6136
|
+
}, 0);
|
|
6137
|
+
}, [canColorHighlightState, highlightColor, editor, label, onApplied]);
|
|
6138
|
+
const handleRemoveHighlight = React14.useCallback(() => {
|
|
6139
|
+
const success = removeHighlight(editor);
|
|
5827
6140
|
if (success) {
|
|
5828
|
-
|
|
6141
|
+
onApplied == null ? void 0 : onApplied({ color: "", label: "Remove highlight" });
|
|
5829
6142
|
}
|
|
5830
6143
|
return success;
|
|
5831
|
-
}, [editor,
|
|
6144
|
+
}, [editor, onApplied]);
|
|
6145
|
+
useHotkeys(
|
|
6146
|
+
COLOR_HIGHLIGHT_SHORTCUT_KEY,
|
|
6147
|
+
(event) => {
|
|
6148
|
+
event.preventDefault();
|
|
6149
|
+
handleColorHighlight();
|
|
6150
|
+
},
|
|
6151
|
+
{
|
|
6152
|
+
enabled: isVisible && canColorHighlightState,
|
|
6153
|
+
enableOnContentEditable: !isMobile,
|
|
6154
|
+
enableOnFormTags: true
|
|
6155
|
+
}
|
|
6156
|
+
);
|
|
5832
6157
|
return {
|
|
5833
6158
|
isVisible,
|
|
5834
6159
|
isActive,
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
6160
|
+
handleColorHighlight,
|
|
6161
|
+
handleRemoveHighlight,
|
|
6162
|
+
canColorHighlight: canColorHighlightState,
|
|
6163
|
+
label: label || `Highlight`,
|
|
6164
|
+
shortcutKeys: COLOR_HIGHLIGHT_SHORTCUT_KEY,
|
|
6165
|
+
Icon: HighlighterIcon
|
|
5840
6166
|
};
|
|
5841
6167
|
}
|
|
5842
6168
|
|
|
5843
|
-
// src/ui/
|
|
6169
|
+
// src/ui/color-highlight-button/color-highlight-button.tsx
|
|
5844
6170
|
import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5845
|
-
var
|
|
6171
|
+
var ColorHighlightButton = ({
|
|
5846
6172
|
editor: providedEditor,
|
|
6173
|
+
highlightColor,
|
|
5847
6174
|
text,
|
|
5848
6175
|
hideWhenUnavailable = false,
|
|
5849
|
-
|
|
6176
|
+
onApplied,
|
|
5850
6177
|
showShortcut = false,
|
|
5851
6178
|
onClick,
|
|
5852
6179
|
children,
|
|
6180
|
+
style,
|
|
6181
|
+
className,
|
|
5853
6182
|
...buttonProps
|
|
5854
6183
|
}) => {
|
|
5855
|
-
const { editor } =
|
|
6184
|
+
const { editor } = useTiptapEditor8(providedEditor);
|
|
5856
6185
|
const {
|
|
5857
6186
|
isVisible,
|
|
5858
|
-
|
|
6187
|
+
canColorHighlight: canColorHighlight2,
|
|
5859
6188
|
isActive,
|
|
5860
|
-
|
|
6189
|
+
handleColorHighlight,
|
|
5861
6190
|
label,
|
|
5862
|
-
shortcutKeys
|
|
5863
|
-
|
|
5864
|
-
} = useBlockquote({
|
|
6191
|
+
shortcutKeys
|
|
6192
|
+
} = useColorHighlight({
|
|
5865
6193
|
editor,
|
|
6194
|
+
highlightColor,
|
|
6195
|
+
label: text || `Toggle highlight (${highlightColor})`,
|
|
5866
6196
|
hideWhenUnavailable,
|
|
5867
|
-
|
|
6197
|
+
onApplied
|
|
5868
6198
|
});
|
|
5869
|
-
const handleClick =
|
|
6199
|
+
const handleClick = useCallback22(
|
|
5870
6200
|
(event) => {
|
|
5871
6201
|
onClick == null ? void 0 : onClick(event);
|
|
5872
6202
|
if (event.defaultPrevented) return;
|
|
5873
|
-
|
|
6203
|
+
handleColorHighlight();
|
|
5874
6204
|
},
|
|
5875
|
-
[
|
|
6205
|
+
[handleColorHighlight, onClick]
|
|
6206
|
+
);
|
|
6207
|
+
const buttonStyle = useMemo15(
|
|
6208
|
+
() => ({
|
|
6209
|
+
...style,
|
|
6210
|
+
"--highlight-color": highlightColor
|
|
6211
|
+
}),
|
|
6212
|
+
[highlightColor, style]
|
|
5876
6213
|
);
|
|
5877
6214
|
if (!isVisible) {
|
|
5878
6215
|
return null;
|
|
5879
6216
|
}
|
|
5880
|
-
|
|
6217
|
+
const styles = colorHighlightButton();
|
|
6218
|
+
return /* @__PURE__ */ jsxs16(
|
|
5881
6219
|
ToolbarButton3,
|
|
5882
6220
|
{
|
|
5883
6221
|
type: "button",
|
|
6222
|
+
disabled: !canColorHighlight2,
|
|
6223
|
+
"data-disabled": !canColorHighlight2,
|
|
5884
6224
|
variant: "ghost",
|
|
5885
6225
|
color: "default",
|
|
5886
|
-
disabled: !canToggle3,
|
|
5887
|
-
"data-disabled": !canToggle3,
|
|
5888
6226
|
"data-active-state": isActive ? "on" : "off",
|
|
5889
6227
|
tabIndex: -1,
|
|
5890
|
-
"aria-label":
|
|
5891
|
-
"aria-pressed": isActive,
|
|
5892
|
-
title: label,
|
|
6228
|
+
"aria-label": label,
|
|
5893
6229
|
shortcutKeys,
|
|
6230
|
+
"aria-pressed": isActive,
|
|
5894
6231
|
onClick: handleClick,
|
|
5895
|
-
|
|
6232
|
+
style: buttonStyle,
|
|
6233
|
+
className: styles.button({ className }),
|
|
6234
|
+
isIconOnly: true,
|
|
5896
6235
|
...buttonProps,
|
|
5897
|
-
children:
|
|
5898
|
-
/* @__PURE__ */ jsx21(
|
|
5899
|
-
|
|
5900
|
-
|
|
6236
|
+
children: [
|
|
6237
|
+
/* @__PURE__ */ jsx21(
|
|
6238
|
+
"span",
|
|
6239
|
+
{
|
|
6240
|
+
"data-active-state": isActive ? "on" : "off",
|
|
6241
|
+
className: styles.mark()
|
|
6242
|
+
}
|
|
6243
|
+
),
|
|
6244
|
+
children || /* @__PURE__ */ jsxs16(Fragment4, { children: [
|
|
6245
|
+
/* @__PURE__ */ jsx21(
|
|
6246
|
+
"span",
|
|
6247
|
+
{
|
|
6248
|
+
style: { "--highlight-color": highlightColor }
|
|
6249
|
+
}
|
|
6250
|
+
),
|
|
6251
|
+
text
|
|
6252
|
+
] })
|
|
6253
|
+
]
|
|
5901
6254
|
}
|
|
5902
6255
|
);
|
|
5903
6256
|
};
|
|
5904
6257
|
|
|
5905
|
-
// src/ui/
|
|
5906
|
-
import {
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
if (!isNodeInSchema4("codeBlock", editor) || isNodeTypeSelected4(editor, ["image"]))
|
|
5925
|
-
return false;
|
|
5926
|
-
if (!turnInto) {
|
|
5927
|
-
return editor.can().toggleNode("codeBlock", "paragraph");
|
|
5928
|
-
}
|
|
5929
|
-
try {
|
|
5930
|
-
const view = editor.view;
|
|
5931
|
-
const state = view.state;
|
|
5932
|
-
const selection = state.selection;
|
|
5933
|
-
if (selection.empty || selection instanceof TextSelection3) {
|
|
5934
|
-
const pos = (_a = findNodePosition2({
|
|
5935
|
-
editor,
|
|
5936
|
-
node: state.selection.$anchor.node(1)
|
|
5937
|
-
})) == null ? void 0 : _a.pos;
|
|
5938
|
-
if (!isValidPosition2(pos)) return false;
|
|
5939
|
-
}
|
|
5940
|
-
return true;
|
|
5941
|
-
} catch {
|
|
5942
|
-
return false;
|
|
6258
|
+
// src/ui/color-highlight-popover/color-highlight-popover.tsx
|
|
6259
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
6260
|
+
var ColorHighlightPopoverButton = ({
|
|
6261
|
+
className,
|
|
6262
|
+
children,
|
|
6263
|
+
...props
|
|
6264
|
+
}) => /* @__PURE__ */ jsx22(
|
|
6265
|
+
IconButton8,
|
|
6266
|
+
{
|
|
6267
|
+
type: "button",
|
|
6268
|
+
className,
|
|
6269
|
+
variant: "ghost",
|
|
6270
|
+
color: "default",
|
|
6271
|
+
tabIndex: -1,
|
|
6272
|
+
"aria-label": "Highlight text",
|
|
6273
|
+
tooltip: "Highlight",
|
|
6274
|
+
isIconOnly: !children,
|
|
6275
|
+
...props,
|
|
6276
|
+
children: children != null ? children : /* @__PURE__ */ jsx22(HighlighterIcon2, {})
|
|
5943
6277
|
}
|
|
6278
|
+
);
|
|
6279
|
+
function ColorHighlightPopoverContent({
|
|
6280
|
+
editor,
|
|
6281
|
+
colors = pickHighlightColorsByValue([
|
|
6282
|
+
"var(--tt-color-highlight-green)",
|
|
6283
|
+
"var(--tt-color-highlight-blue)",
|
|
6284
|
+
"var(--tt-color-highlight-red)",
|
|
6285
|
+
"var(--tt-color-highlight-purple)",
|
|
6286
|
+
"var(--tt-color-highlight-yellow)"
|
|
6287
|
+
])
|
|
6288
|
+
}) {
|
|
6289
|
+
const { handleRemoveHighlight } = useColorHighlight({ editor });
|
|
6290
|
+
const containerRef = useRef10(null);
|
|
6291
|
+
const menuItems = useMemo16(
|
|
6292
|
+
() => [...colors, { label: "Remove highlight", value: "none" }],
|
|
6293
|
+
[colors]
|
|
6294
|
+
);
|
|
6295
|
+
const { selectedIndex } = useMenuNavigation({
|
|
6296
|
+
containerRef,
|
|
6297
|
+
items: menuItems,
|
|
6298
|
+
orientation: "both",
|
|
6299
|
+
onSelect: (item) => {
|
|
6300
|
+
if (!containerRef.current) return false;
|
|
6301
|
+
const highlightedElement = containerRef.current.querySelector(
|
|
6302
|
+
'[data-highlighted="true"]'
|
|
6303
|
+
);
|
|
6304
|
+
if (highlightedElement) highlightedElement.click();
|
|
6305
|
+
if (item.value === "none") handleRemoveHighlight();
|
|
6306
|
+
},
|
|
6307
|
+
autoSelectFirstItem: false
|
|
6308
|
+
});
|
|
6309
|
+
return /* @__PURE__ */ jsxs17("div", { ref: containerRef, className: "flex gap-1 items-center", children: [
|
|
6310
|
+
/* @__PURE__ */ jsx22(
|
|
6311
|
+
"div",
|
|
6312
|
+
{
|
|
6313
|
+
className: "flex items-center gap-1 outline-none",
|
|
6314
|
+
"data-orientation": "horizontal",
|
|
6315
|
+
children: colors.map((color, index) => /* @__PURE__ */ jsx22(
|
|
6316
|
+
ColorHighlightButton,
|
|
6317
|
+
{
|
|
6318
|
+
editor,
|
|
6319
|
+
highlightColor: color.value,
|
|
6320
|
+
"aria-label": `${color.label} highlight color`,
|
|
6321
|
+
tabIndex: index === selectedIndex ? 0 : -1,
|
|
6322
|
+
"data-highlighted": selectedIndex === index
|
|
6323
|
+
},
|
|
6324
|
+
color.value
|
|
6325
|
+
))
|
|
6326
|
+
}
|
|
6327
|
+
),
|
|
6328
|
+
/* @__PURE__ */ jsx22(ToolbarSeparator2, { orientation: "vertical" }),
|
|
6329
|
+
/* @__PURE__ */ jsx22("div", { className: "tiptap-button-group", children: /* @__PURE__ */ jsx22(
|
|
6330
|
+
IconButton8,
|
|
6331
|
+
{
|
|
6332
|
+
onClick: handleRemoveHighlight,
|
|
6333
|
+
"aria-label": "Remove highlight",
|
|
6334
|
+
tabIndex: selectedIndex === colors.length ? 0 : -1,
|
|
6335
|
+
type: "button",
|
|
6336
|
+
role: "menuitem",
|
|
6337
|
+
variant: "ghost",
|
|
6338
|
+
color: "default",
|
|
6339
|
+
"data-highlighted": selectedIndex === colors.length,
|
|
6340
|
+
children: /* @__PURE__ */ jsx22(BanIcon, {})
|
|
6341
|
+
}
|
|
6342
|
+
) })
|
|
6343
|
+
] });
|
|
5944
6344
|
}
|
|
5945
|
-
function
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
6345
|
+
function ColorHighlightPopover({
|
|
6346
|
+
editor: providedEditor,
|
|
6347
|
+
colors = pickHighlightColorsByValue([
|
|
6348
|
+
"var(--tt-color-highlight-green)",
|
|
6349
|
+
"var(--tt-color-highlight-blue)",
|
|
6350
|
+
"var(--tt-color-highlight-red)",
|
|
6351
|
+
"var(--tt-color-highlight-purple)",
|
|
6352
|
+
"var(--tt-color-highlight-yellow)"
|
|
6353
|
+
]),
|
|
6354
|
+
hideWhenUnavailable = false,
|
|
6355
|
+
onApplied,
|
|
6356
|
+
...props
|
|
6357
|
+
}) {
|
|
6358
|
+
const { editor } = useTiptapEditor9(providedEditor);
|
|
6359
|
+
const [isOpen, setIsOpen] = useState22(false);
|
|
6360
|
+
const { isVisible, canColorHighlight: canColorHighlight2, isActive, label } = useColorHighlight({
|
|
6361
|
+
editor,
|
|
6362
|
+
hideWhenUnavailable,
|
|
6363
|
+
onApplied
|
|
6364
|
+
});
|
|
6365
|
+
if (!isVisible) return null;
|
|
6366
|
+
return /* @__PURE__ */ jsxs17(Popover2.Root, { open: isOpen, onOpenChange: setIsOpen, spacing: "dense", children: [
|
|
6367
|
+
/* @__PURE__ */ jsx22(
|
|
6368
|
+
Popover2.Trigger,
|
|
6369
|
+
{
|
|
6370
|
+
render: /* @__PURE__ */ jsx22(
|
|
6371
|
+
ColorHighlightPopoverButton,
|
|
6372
|
+
{
|
|
6373
|
+
disabled: !canColorHighlight2,
|
|
6374
|
+
"data-disabled": !canColorHighlight2,
|
|
6375
|
+
"data-active-state": isActive ? "on" : "off",
|
|
6376
|
+
"aria-pressed": isActive,
|
|
6377
|
+
"aria-label": label,
|
|
6378
|
+
title: label,
|
|
6379
|
+
...props
|
|
6380
|
+
}
|
|
6381
|
+
)
|
|
6382
|
+
}
|
|
6383
|
+
),
|
|
6384
|
+
/* @__PURE__ */ jsx22(Popover2.Content, { "aria-label": "Highlight colors", children: /* @__PURE__ */ jsx22(ColorHighlightPopoverContent, { editor, colors }) })
|
|
6385
|
+
] });
|
|
6386
|
+
}
|
|
6387
|
+
|
|
6388
|
+
// src/ui/list-dropdown-menu/index.tsx
|
|
6389
|
+
import { Button as Button8 } from "@kopexa/button";
|
|
6390
|
+
import { DropdownMenu } from "@kopexa/dropdown-menu";
|
|
6391
|
+
import { isNodeInSchema as isNodeInSchema4, useTiptapEditor as useTiptapEditor11 } from "@kopexa/editor-utils";
|
|
6392
|
+
import { ChevronDownIcon, ListIcon as ListIcon4 } from "@kopexa/icons";
|
|
6393
|
+
import { isNodeSelection as isNodeSelection6 } from "@tiptap/react";
|
|
6394
|
+
import { useCallback as useCallback24, useMemo as useMemo18, useState as useState23 } from "react";
|
|
6395
|
+
|
|
6396
|
+
// src/ui/list-button/index.tsx
|
|
6397
|
+
import { Button as Button7 } from "@kopexa/button";
|
|
6398
|
+
import { isNodeInSchema as isNodeInSchema3, useTiptapEditor as useTiptapEditor10 } from "@kopexa/editor-utils";
|
|
6399
|
+
import { ListIcon as ListIcon3, ListOrderedIcon as ListOrderedIcon2, ListTodoIcon as ListTodoIcon2 } from "@kopexa/icons";
|
|
6400
|
+
import { isNodeSelection as isNodeSelection5 } from "@tiptap/react";
|
|
6401
|
+
import { useCallback as useCallback23, useMemo as useMemo17 } from "react";
|
|
6402
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
6403
|
+
var listOptions = [
|
|
6404
|
+
{
|
|
6405
|
+
label: "Bullet List",
|
|
6406
|
+
type: "bulletList",
|
|
6407
|
+
icon: ListIcon3
|
|
6408
|
+
},
|
|
6409
|
+
{
|
|
6410
|
+
label: "Ordered List",
|
|
6411
|
+
type: "orderedList",
|
|
6412
|
+
icon: ListOrderedIcon2
|
|
6413
|
+
},
|
|
6414
|
+
{
|
|
6415
|
+
label: "Task List",
|
|
6416
|
+
type: "taskList",
|
|
6417
|
+
icon: ListTodoIcon2
|
|
6418
|
+
}
|
|
6419
|
+
];
|
|
6420
|
+
var listShortcutKeys = {
|
|
6421
|
+
bulletList: "Ctrl-Shift-8",
|
|
6422
|
+
orderedList: "Ctrl-Shift-7",
|
|
6423
|
+
taskList: "Ctrl-Shift-9"
|
|
6424
|
+
};
|
|
6425
|
+
function canToggleList(editor, type) {
|
|
6426
|
+
if (!editor) {
|
|
5977
6427
|
return false;
|
|
5978
6428
|
}
|
|
6429
|
+
switch (type) {
|
|
6430
|
+
case "bulletList":
|
|
6431
|
+
return editor.can().toggleBulletList();
|
|
6432
|
+
case "orderedList":
|
|
6433
|
+
return editor.can().toggleOrderedList();
|
|
6434
|
+
case "taskList":
|
|
6435
|
+
return editor.can().toggleList("taskList", "taskItem");
|
|
6436
|
+
default:
|
|
6437
|
+
return false;
|
|
6438
|
+
}
|
|
5979
6439
|
}
|
|
5980
|
-
function
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
6440
|
+
function isListActive(editor, type) {
|
|
6441
|
+
if (!editor) return false;
|
|
6442
|
+
switch (type) {
|
|
6443
|
+
case "bulletList":
|
|
6444
|
+
return editor.isActive("bulletList");
|
|
6445
|
+
case "orderedList":
|
|
6446
|
+
return editor.isActive("orderedList");
|
|
6447
|
+
case "taskList":
|
|
6448
|
+
return editor.isActive("taskList");
|
|
6449
|
+
default:
|
|
6450
|
+
return false;
|
|
5986
6451
|
}
|
|
5987
|
-
return true;
|
|
5988
6452
|
}
|
|
5989
|
-
function
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
onToggled == null ? void 0 : onToggled();
|
|
6453
|
+
function toggleList(editor, type) {
|
|
6454
|
+
if (!editor) return;
|
|
6455
|
+
switch (type) {
|
|
6456
|
+
case "bulletList":
|
|
6457
|
+
editor.chain().focus().toggleBulletList().run();
|
|
6458
|
+
break;
|
|
6459
|
+
case "orderedList":
|
|
6460
|
+
editor.chain().focus().toggleOrderedList().run();
|
|
6461
|
+
break;
|
|
6462
|
+
case "taskList":
|
|
6463
|
+
editor.chain().focus().toggleList("taskList", "taskItem").run();
|
|
6464
|
+
break;
|
|
6465
|
+
}
|
|
6466
|
+
}
|
|
6467
|
+
function getListOption(type) {
|
|
6468
|
+
return listOptions.find((option) => option.type === type);
|
|
6469
|
+
}
|
|
6470
|
+
function shouldShowListButton(params) {
|
|
6471
|
+
const { editor, type, hideWhenUnavailable, listInSchema } = params;
|
|
6472
|
+
if (!listInSchema || !editor) {
|
|
6473
|
+
return false;
|
|
6474
|
+
}
|
|
6475
|
+
if (hideWhenUnavailable) {
|
|
6476
|
+
if (isNodeSelection5(editor.state.selection) || !canToggleList(editor, type)) {
|
|
6477
|
+
return false;
|
|
6015
6478
|
}
|
|
6016
|
-
|
|
6017
|
-
|
|
6479
|
+
}
|
|
6480
|
+
return true;
|
|
6481
|
+
}
|
|
6482
|
+
function useListState(editor, type) {
|
|
6483
|
+
const listInSchema = isNodeInSchema3(type, editor);
|
|
6484
|
+
const listOption = getListOption(type);
|
|
6485
|
+
const isActive = isListActive(editor, type);
|
|
6486
|
+
const shortcutKey = listShortcutKeys[type];
|
|
6018
6487
|
return {
|
|
6019
|
-
|
|
6488
|
+
listInSchema,
|
|
6489
|
+
listOption,
|
|
6020
6490
|
isActive,
|
|
6021
|
-
|
|
6022
|
-
canToggle: canToggleState,
|
|
6023
|
-
label: "Code Block",
|
|
6024
|
-
shortcutKeys: CODE_BLOCK_SHORTCUT_KEY,
|
|
6025
|
-
Icon: CodeblockIcon
|
|
6491
|
+
shortcutKey
|
|
6026
6492
|
};
|
|
6027
6493
|
}
|
|
6028
|
-
|
|
6029
|
-
// src/ui/codeblock-button/code-block-button.tsx
|
|
6030
|
-
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
6031
|
-
var CodeBlockButton = ({
|
|
6494
|
+
var ListButton = ({
|
|
6032
6495
|
editor: providedEditor,
|
|
6033
|
-
|
|
6496
|
+
type,
|
|
6034
6497
|
hideWhenUnavailable = false,
|
|
6035
|
-
|
|
6036
|
-
showShortcut = false,
|
|
6498
|
+
className = "",
|
|
6037
6499
|
onClick,
|
|
6500
|
+
text,
|
|
6038
6501
|
children,
|
|
6502
|
+
ref,
|
|
6039
6503
|
...buttonProps
|
|
6040
6504
|
}) => {
|
|
6041
|
-
const { editor } =
|
|
6042
|
-
const {
|
|
6505
|
+
const { editor } = useTiptapEditor10(providedEditor);
|
|
6506
|
+
const { listInSchema, listOption, isActive, shortcutKey } = useListState(
|
|
6043
6507
|
editor,
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
const handleClick =
|
|
6048
|
-
(
|
|
6049
|
-
onClick == null ? void 0 : onClick(
|
|
6050
|
-
if (
|
|
6051
|
-
|
|
6508
|
+
type
|
|
6509
|
+
);
|
|
6510
|
+
const Icon = (listOption == null ? void 0 : listOption.icon) || ListIcon3;
|
|
6511
|
+
const handleClick = useCallback23(
|
|
6512
|
+
(e) => {
|
|
6513
|
+
onClick == null ? void 0 : onClick(e);
|
|
6514
|
+
if (!e.defaultPrevented && editor) {
|
|
6515
|
+
toggleList(editor, type);
|
|
6516
|
+
}
|
|
6052
6517
|
},
|
|
6053
|
-
[
|
|
6518
|
+
[onClick, editor, type]
|
|
6054
6519
|
);
|
|
6055
|
-
|
|
6520
|
+
const show = useMemo17(() => {
|
|
6521
|
+
return shouldShowListButton({
|
|
6522
|
+
editor,
|
|
6523
|
+
type,
|
|
6524
|
+
hideWhenUnavailable,
|
|
6525
|
+
listInSchema
|
|
6526
|
+
});
|
|
6527
|
+
}, [editor, type, hideWhenUnavailable, listInSchema]);
|
|
6528
|
+
if (!show || !editor || !editor.isEditable) {
|
|
6056
6529
|
return null;
|
|
6057
6530
|
}
|
|
6058
|
-
return /* @__PURE__ */
|
|
6059
|
-
|
|
6531
|
+
return /* @__PURE__ */ jsx23(
|
|
6532
|
+
Button7,
|
|
6060
6533
|
{
|
|
6061
6534
|
type: "button",
|
|
6535
|
+
className: className.trim(),
|
|
6062
6536
|
variant: "ghost",
|
|
6063
6537
|
color: "default",
|
|
6064
|
-
disabled: !canToggle3,
|
|
6065
|
-
"data-disabled": !canToggle3,
|
|
6066
6538
|
"data-active-state": isActive ? "on" : "off",
|
|
6067
6539
|
tabIndex: -1,
|
|
6068
|
-
"aria-label":
|
|
6540
|
+
"aria-label": (listOption == null ? void 0 : listOption.label) || type,
|
|
6069
6541
|
"aria-pressed": isActive,
|
|
6070
|
-
|
|
6071
|
-
shortcutKeys,
|
|
6542
|
+
tooltip: (listOption == null ? void 0 : listOption.label) || type,
|
|
6543
|
+
shortcutKeys: shortcutKey,
|
|
6072
6544
|
onClick: handleClick,
|
|
6073
|
-
|
|
6545
|
+
startContent: /* @__PURE__ */ jsx23(Icon, {}),
|
|
6074
6546
|
...buttonProps,
|
|
6075
|
-
|
|
6547
|
+
ref,
|
|
6548
|
+
children: children || text
|
|
6076
6549
|
}
|
|
6077
6550
|
);
|
|
6078
6551
|
};
|
|
6079
6552
|
|
|
6080
|
-
// src/ui/
|
|
6081
|
-
import {
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
import { useMemo as useMemo17, useRef as useRef10, useState as useState24 } from "react";
|
|
6086
|
-
|
|
6087
|
-
// src/ui/color-highlight-button/color-highlight-button.tsx
|
|
6088
|
-
import { colorHighlightButton } from "@kopexa/theme";
|
|
6089
|
-
import { ToolbarButton as ToolbarButton5 } from "@kopexa/toolbar";
|
|
6090
|
-
import { useCallback as useCallback26, useMemo as useMemo16 } from "react";
|
|
6091
|
-
|
|
6092
|
-
// src/ui/color-highlight-button/use-color-highlight.ts
|
|
6093
|
-
import { isMarkInSchema as isMarkInSchema3, isNodeTypeSelected as isNodeTypeSelected5 } from "@kopexa/editor-utils";
|
|
6094
|
-
import { HighlighterIcon } from "@kopexa/icons";
|
|
6095
|
-
import { useIsMobile } from "@kopexa/use-is-mobile";
|
|
6096
|
-
import * as React17 from "react";
|
|
6097
|
-
import { useHotkeys } from "react-hotkeys-hook";
|
|
6098
|
-
var COLOR_HIGHLIGHT_SHORTCUT_KEY = "mod+shift+h";
|
|
6099
|
-
var HIGHLIGHT_COLORS = [
|
|
6100
|
-
{
|
|
6101
|
-
label: "Default background",
|
|
6102
|
-
value: "var(--tt-bg-color)",
|
|
6103
|
-
border: "var(--tt-bg-color-contrast)"
|
|
6104
|
-
},
|
|
6105
|
-
{
|
|
6106
|
-
label: "Gray background",
|
|
6107
|
-
value: "var(--tt-color-highlight-gray)",
|
|
6108
|
-
border: "var(--tt-color-highlight-gray-contrast)"
|
|
6109
|
-
},
|
|
6110
|
-
{
|
|
6111
|
-
label: "Brown background",
|
|
6112
|
-
value: "var(--tt-color-highlight-brown)",
|
|
6113
|
-
border: "var(--tt-color-highlight-brown-contrast)"
|
|
6114
|
-
},
|
|
6115
|
-
{
|
|
6116
|
-
label: "Orange background",
|
|
6117
|
-
value: "var(--tt-color-highlight-orange)",
|
|
6118
|
-
border: "var(--tt-color-highlight-orange-contrast)"
|
|
6119
|
-
},
|
|
6120
|
-
{
|
|
6121
|
-
label: "Yellow background",
|
|
6122
|
-
value: "var(--tt-color-highlight-yellow)",
|
|
6123
|
-
border: "var(--tt-color-highlight-yellow-contrast)"
|
|
6124
|
-
},
|
|
6125
|
-
{
|
|
6126
|
-
label: "Green background",
|
|
6127
|
-
value: "var(--tt-color-highlight-green)",
|
|
6128
|
-
border: "var(--tt-color-highlight-green-contrast)"
|
|
6129
|
-
},
|
|
6130
|
-
{
|
|
6131
|
-
label: "Blue background",
|
|
6132
|
-
value: "var(--tt-color-highlight-blue)",
|
|
6133
|
-
border: "var(--tt-color-highlight-blue-contrast)"
|
|
6134
|
-
},
|
|
6135
|
-
{
|
|
6136
|
-
label: "Purple background",
|
|
6137
|
-
value: "var(--tt-color-highlight-purple)",
|
|
6138
|
-
border: "var(--tt-color-highlight-purple-contrast)"
|
|
6139
|
-
},
|
|
6140
|
-
{
|
|
6141
|
-
label: "Pink background",
|
|
6142
|
-
value: "var(--tt-color-highlight-pink)",
|
|
6143
|
-
border: "var(--tt-color-highlight-pink-contrast)"
|
|
6144
|
-
},
|
|
6145
|
-
{
|
|
6146
|
-
label: "Red background",
|
|
6147
|
-
value: "var(--tt-color-highlight-red)",
|
|
6148
|
-
border: "var(--tt-color-highlight-red-contrast)"
|
|
6149
|
-
}
|
|
6150
|
-
];
|
|
6151
|
-
function pickHighlightColorsByValue(values) {
|
|
6152
|
-
const colorMap = new Map(
|
|
6153
|
-
HIGHLIGHT_COLORS.map((color) => [color.value, color])
|
|
6154
|
-
);
|
|
6155
|
-
return values.map((value) => colorMap.get(value)).filter((color) => !!color);
|
|
6156
|
-
}
|
|
6157
|
-
function canColorHighlight(editor) {
|
|
6158
|
-
if (!editor || !editor.isEditable) return false;
|
|
6159
|
-
if (!isMarkInSchema3("highlight", editor) || isNodeTypeSelected5(editor, ["image"]))
|
|
6160
|
-
return false;
|
|
6161
|
-
return editor.can().setMark("highlight");
|
|
6553
|
+
// src/ui/list-dropdown-menu/index.tsx
|
|
6554
|
+
import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
6555
|
+
function canToggleAnyList(editor, listTypes) {
|
|
6556
|
+
if (!editor) return false;
|
|
6557
|
+
return listTypes.some((type) => canToggleList(editor, type));
|
|
6162
6558
|
}
|
|
6163
|
-
function
|
|
6164
|
-
if (!editor
|
|
6165
|
-
return
|
|
6559
|
+
function isAnyListActive(editor, listTypes) {
|
|
6560
|
+
if (!editor) return false;
|
|
6561
|
+
return listTypes.some((type) => isListActive(editor, type));
|
|
6166
6562
|
}
|
|
6167
|
-
function
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6563
|
+
function getFilteredListOptions(availableTypes) {
|
|
6564
|
+
return listOptions.filter(
|
|
6565
|
+
(option) => !option.type || availableTypes.includes(option.type)
|
|
6566
|
+
);
|
|
6171
6567
|
}
|
|
6172
|
-
function
|
|
6173
|
-
const { editor, hideWhenUnavailable } =
|
|
6174
|
-
if (!
|
|
6175
|
-
|
|
6176
|
-
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
6177
|
-
return canColorHighlight(editor);
|
|
6568
|
+
function shouldShowListDropdown(params) {
|
|
6569
|
+
const { editor, hideWhenUnavailable, listInSchema, canToggleAny } = params;
|
|
6570
|
+
if (!listInSchema || !editor) {
|
|
6571
|
+
return false;
|
|
6178
6572
|
}
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
function useColorHighlight(config) {
|
|
6182
|
-
const {
|
|
6183
|
-
editor: providedEditor,
|
|
6184
|
-
label,
|
|
6185
|
-
highlightColor,
|
|
6186
|
-
hideWhenUnavailable = false,
|
|
6187
|
-
onApplied
|
|
6188
|
-
} = config;
|
|
6189
|
-
const { editor } = useTiptapEditor(providedEditor);
|
|
6190
|
-
const isMobile = useIsMobile();
|
|
6191
|
-
const [isVisible, setIsVisible] = React17.useState(true);
|
|
6192
|
-
const canColorHighlightState = canColorHighlight(editor);
|
|
6193
|
-
const isActive = isColorHighlightActive(editor, highlightColor);
|
|
6194
|
-
React17.useEffect(() => {
|
|
6195
|
-
if (!editor) return;
|
|
6196
|
-
const handleSelectionUpdate = () => {
|
|
6197
|
-
setIsVisible(shouldShowButton4({ editor, hideWhenUnavailable }));
|
|
6198
|
-
};
|
|
6199
|
-
handleSelectionUpdate();
|
|
6200
|
-
editor.on("selectionUpdate", handleSelectionUpdate);
|
|
6201
|
-
return () => {
|
|
6202
|
-
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
6203
|
-
};
|
|
6204
|
-
}, [editor, hideWhenUnavailable]);
|
|
6205
|
-
const handleColorHighlight = React17.useCallback(() => {
|
|
6206
|
-
if (!editor || !canColorHighlightState || !highlightColor || !label)
|
|
6573
|
+
if (hideWhenUnavailable) {
|
|
6574
|
+
if (isNodeSelection6(editor.state.selection) || !canToggleAny) {
|
|
6207
6575
|
return false;
|
|
6208
|
-
if (editor.state.storedMarks) {
|
|
6209
|
-
const highlightMarkType = editor.schema.marks.highlight;
|
|
6210
|
-
if (highlightMarkType) {
|
|
6211
|
-
editor.view.dispatch(
|
|
6212
|
-
editor.state.tr.removeStoredMark(highlightMarkType)
|
|
6213
|
-
);
|
|
6214
|
-
}
|
|
6215
|
-
}
|
|
6216
|
-
setTimeout(() => {
|
|
6217
|
-
const success = editor.chain().focus().toggleMark("highlight", { color: highlightColor }).run();
|
|
6218
|
-
if (success) {
|
|
6219
|
-
onApplied == null ? void 0 : onApplied({ color: highlightColor, label });
|
|
6220
|
-
}
|
|
6221
|
-
return success;
|
|
6222
|
-
}, 0);
|
|
6223
|
-
}, [canColorHighlightState, highlightColor, editor, label, onApplied]);
|
|
6224
|
-
const handleRemoveHighlight = React17.useCallback(() => {
|
|
6225
|
-
const success = removeHighlight(editor);
|
|
6226
|
-
if (success) {
|
|
6227
|
-
onApplied == null ? void 0 : onApplied({ color: "", label: "Remove highlight" });
|
|
6228
6576
|
}
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6577
|
+
}
|
|
6578
|
+
return true;
|
|
6579
|
+
}
|
|
6580
|
+
function useListDropdownState(editor, availableTypes) {
|
|
6581
|
+
const [isOpen, setIsOpen] = useState23(false);
|
|
6582
|
+
const listInSchema = availableTypes.some(
|
|
6583
|
+
(type) => isNodeInSchema4(type, editor)
|
|
6584
|
+
);
|
|
6585
|
+
const filteredLists = useMemo18(
|
|
6586
|
+
() => getFilteredListOptions(availableTypes),
|
|
6587
|
+
[availableTypes]
|
|
6588
|
+
);
|
|
6589
|
+
const canToggleAny = canToggleAnyList(editor, availableTypes);
|
|
6590
|
+
const isAnyActive = isAnyListActive(editor, availableTypes);
|
|
6591
|
+
const handleOpenChange = useCallback24(
|
|
6592
|
+
(open, callback) => {
|
|
6593
|
+
setIsOpen(open);
|
|
6594
|
+
callback == null ? void 0 : callback(open);
|
|
6236
6595
|
},
|
|
6237
|
-
|
|
6238
|
-
enabled: isVisible && canColorHighlightState,
|
|
6239
|
-
enableOnContentEditable: !isMobile,
|
|
6240
|
-
enableOnFormTags: true
|
|
6241
|
-
}
|
|
6596
|
+
[]
|
|
6242
6597
|
);
|
|
6243
6598
|
return {
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
Icon: HighlighterIcon
|
|
6599
|
+
isOpen,
|
|
6600
|
+
setIsOpen,
|
|
6601
|
+
listInSchema,
|
|
6602
|
+
filteredLists,
|
|
6603
|
+
canToggleAny,
|
|
6604
|
+
isAnyActive,
|
|
6605
|
+
handleOpenChange
|
|
6252
6606
|
};
|
|
6253
6607
|
}
|
|
6608
|
+
function useActiveListIcon(editor, filteredLists) {
|
|
6609
|
+
return useCallback24(() => {
|
|
6610
|
+
const activeOption = filteredLists.find(
|
|
6611
|
+
(option) => isListActive(editor, option.type)
|
|
6612
|
+
);
|
|
6613
|
+
return activeOption ? /* @__PURE__ */ jsx24(activeOption.icon, {}) : /* @__PURE__ */ jsx24(ListIcon4, {});
|
|
6614
|
+
}, [editor, filteredLists]);
|
|
6615
|
+
}
|
|
6616
|
+
function ListDropdownMenu({
|
|
6617
|
+
editor: providedEditor,
|
|
6618
|
+
types = ["bulletList", "orderedList", "taskList"],
|
|
6619
|
+
hideWhenUnavailable = false,
|
|
6620
|
+
onOpenChange,
|
|
6621
|
+
...props
|
|
6622
|
+
}) {
|
|
6623
|
+
const { editor } = useTiptapEditor11(providedEditor);
|
|
6624
|
+
const {
|
|
6625
|
+
isOpen,
|
|
6626
|
+
listInSchema,
|
|
6627
|
+
filteredLists,
|
|
6628
|
+
canToggleAny,
|
|
6629
|
+
isAnyActive,
|
|
6630
|
+
handleOpenChange
|
|
6631
|
+
} = useListDropdownState(editor, types);
|
|
6632
|
+
const getActiveIcon = useActiveListIcon(editor, filteredLists);
|
|
6633
|
+
const show = useMemo18(() => {
|
|
6634
|
+
return shouldShowListDropdown({
|
|
6635
|
+
editor,
|
|
6636
|
+
listTypes: types,
|
|
6637
|
+
hideWhenUnavailable,
|
|
6638
|
+
listInSchema,
|
|
6639
|
+
canToggleAny
|
|
6640
|
+
});
|
|
6641
|
+
}, [editor, types, hideWhenUnavailable, listInSchema, canToggleAny]);
|
|
6642
|
+
const handleOnOpenChange = useCallback24(
|
|
6643
|
+
(open) => handleOpenChange(open, onOpenChange),
|
|
6644
|
+
[handleOpenChange, onOpenChange]
|
|
6645
|
+
);
|
|
6646
|
+
if (!show || !editor || !editor.isEditable) {
|
|
6647
|
+
return null;
|
|
6648
|
+
}
|
|
6649
|
+
return /* @__PURE__ */ jsxs18(DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
|
|
6650
|
+
/* @__PURE__ */ jsx24(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx24(
|
|
6651
|
+
Button8,
|
|
6652
|
+
{
|
|
6653
|
+
type: "button",
|
|
6654
|
+
variant: "ghost",
|
|
6655
|
+
color: "default",
|
|
6656
|
+
"data-active-state": isAnyActive ? "on" : "off",
|
|
6657
|
+
tabIndex: -1,
|
|
6658
|
+
"aria-label": "List options",
|
|
6659
|
+
tooltip: "List",
|
|
6660
|
+
endContent: /* @__PURE__ */ jsx24(ChevronDownIcon, {}),
|
|
6661
|
+
...props,
|
|
6662
|
+
children: getActiveIcon()
|
|
6663
|
+
}
|
|
6664
|
+
) }),
|
|
6665
|
+
/* @__PURE__ */ jsx24(DropdownMenu.Content, { children: /* @__PURE__ */ jsx24(DropdownMenu.Group, { children: filteredLists.map((option) => /* @__PURE__ */ jsx24(DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ jsx24(
|
|
6666
|
+
ListButton,
|
|
6667
|
+
{
|
|
6668
|
+
editor,
|
|
6669
|
+
type: option.type,
|
|
6670
|
+
text: option.label,
|
|
6671
|
+
hideWhenUnavailable,
|
|
6672
|
+
tooltip: "",
|
|
6673
|
+
fullWidth: true,
|
|
6674
|
+
spacing: "start"
|
|
6675
|
+
}
|
|
6676
|
+
) }, option.type)) }) })
|
|
6677
|
+
] });
|
|
6678
|
+
}
|
|
6254
6679
|
|
|
6255
|
-
// src/ui/
|
|
6256
|
-
import {
|
|
6257
|
-
|
|
6680
|
+
// src/ui/table-button/index.tsx
|
|
6681
|
+
import { useTiptapEditor as useTiptapEditor12 } from "@kopexa/editor-utils";
|
|
6682
|
+
import { ToolbarButton as ToolbarButton4 } from "@kopexa/toolbar";
|
|
6683
|
+
import { useCallback as useCallback25 } from "react";
|
|
6684
|
+
import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
6685
|
+
var TableButton = ({
|
|
6258
6686
|
editor: providedEditor,
|
|
6259
|
-
highlightColor,
|
|
6260
6687
|
text,
|
|
6261
6688
|
hideWhenUnavailable = false,
|
|
6262
|
-
|
|
6263
|
-
showShortcut = false,
|
|
6689
|
+
onToggled,
|
|
6264
6690
|
onClick,
|
|
6265
6691
|
children,
|
|
6266
|
-
style,
|
|
6267
|
-
className,
|
|
6268
6692
|
...buttonProps
|
|
6269
6693
|
}) => {
|
|
6270
|
-
const { editor } =
|
|
6694
|
+
const { editor } = useTiptapEditor12(providedEditor);
|
|
6271
6695
|
const {
|
|
6272
6696
|
isVisible,
|
|
6273
|
-
|
|
6697
|
+
canToggle: canToggle3,
|
|
6274
6698
|
isActive,
|
|
6275
|
-
|
|
6699
|
+
handleToggle,
|
|
6276
6700
|
label,
|
|
6277
|
-
shortcutKeys
|
|
6278
|
-
|
|
6701
|
+
// shortcutKeys,
|
|
6702
|
+
Icon
|
|
6703
|
+
} = useTableBlock({
|
|
6279
6704
|
editor,
|
|
6280
|
-
highlightColor,
|
|
6281
|
-
label: text || `Toggle highlight (${highlightColor})`,
|
|
6282
6705
|
hideWhenUnavailable,
|
|
6283
|
-
|
|
6706
|
+
onToggled
|
|
6284
6707
|
});
|
|
6285
|
-
const handleClick =
|
|
6708
|
+
const handleClick = useCallback25(
|
|
6286
6709
|
(event) => {
|
|
6287
6710
|
onClick == null ? void 0 : onClick(event);
|
|
6288
6711
|
if (event.defaultPrevented) return;
|
|
6289
|
-
|
|
6712
|
+
handleToggle();
|
|
6290
6713
|
},
|
|
6291
|
-
[
|
|
6292
|
-
);
|
|
6293
|
-
const buttonStyle = useMemo16(
|
|
6294
|
-
() => ({
|
|
6295
|
-
...style,
|
|
6296
|
-
"--highlight-color": highlightColor
|
|
6297
|
-
}),
|
|
6298
|
-
[highlightColor, style]
|
|
6714
|
+
[handleToggle, onClick]
|
|
6299
6715
|
);
|
|
6300
6716
|
if (!isVisible) {
|
|
6301
6717
|
return null;
|
|
6302
6718
|
}
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
ToolbarButton5,
|
|
6719
|
+
return /* @__PURE__ */ jsx25(
|
|
6720
|
+
ToolbarButton4,
|
|
6306
6721
|
{
|
|
6307
6722
|
type: "button",
|
|
6308
|
-
disabled: !canColorHighlight2,
|
|
6309
|
-
"data-disabled": !canColorHighlight2,
|
|
6310
6723
|
variant: "ghost",
|
|
6311
6724
|
color: "default",
|
|
6312
6725
|
"data-active-state": isActive ? "on" : "off",
|
|
6726
|
+
disabled: !canToggle3,
|
|
6727
|
+
"data-disabled": !canToggle3,
|
|
6313
6728
|
tabIndex: -1,
|
|
6314
6729
|
"aria-label": label,
|
|
6315
|
-
shortcutKeys,
|
|
6316
6730
|
"aria-pressed": isActive,
|
|
6731
|
+
title: label,
|
|
6317
6732
|
onClick: handleClick,
|
|
6318
|
-
|
|
6319
|
-
className: styles.button({ className }),
|
|
6320
|
-
isIconOnly: true,
|
|
6733
|
+
isIconOnly: !text && !children,
|
|
6321
6734
|
...buttonProps,
|
|
6322
|
-
children: [
|
|
6323
|
-
/* @__PURE__ */
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
"data-active-state": isActive ? "on" : "off",
|
|
6327
|
-
className: styles.mark()
|
|
6328
|
-
}
|
|
6329
|
-
),
|
|
6330
|
-
children || /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
6331
|
-
/* @__PURE__ */ jsx23(
|
|
6332
|
-
"span",
|
|
6333
|
-
{
|
|
6334
|
-
style: { "--highlight-color": highlightColor }
|
|
6335
|
-
}
|
|
6336
|
-
),
|
|
6337
|
-
text
|
|
6338
|
-
] })
|
|
6339
|
-
]
|
|
6735
|
+
children: children || /* @__PURE__ */ jsxs19(Fragment5, { children: [
|
|
6736
|
+
/* @__PURE__ */ jsx25(Icon, {}),
|
|
6737
|
+
text && /* @__PURE__ */ jsx25("span", { children: text })
|
|
6738
|
+
] })
|
|
6340
6739
|
}
|
|
6341
6740
|
);
|
|
6342
6741
|
};
|
|
6343
6742
|
|
|
6344
|
-
// src/ui/
|
|
6345
|
-
import {
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
children,
|
|
6349
|
-
...props
|
|
6350
|
-
}) => /* @__PURE__ */ jsx24(
|
|
6351
|
-
IconButton8,
|
|
6352
|
-
{
|
|
6353
|
-
type: "button",
|
|
6354
|
-
className,
|
|
6355
|
-
variant: "ghost",
|
|
6356
|
-
color: "default",
|
|
6357
|
-
tabIndex: -1,
|
|
6358
|
-
"aria-label": "Highlight text",
|
|
6359
|
-
tooltip: "Highlight",
|
|
6360
|
-
isIconOnly: !children,
|
|
6361
|
-
...props,
|
|
6362
|
-
children: children != null ? children : /* @__PURE__ */ jsx24(HighlighterIcon2, {})
|
|
6363
|
-
}
|
|
6364
|
-
);
|
|
6365
|
-
function ColorHighlightPopoverContent({
|
|
6366
|
-
editor,
|
|
6367
|
-
colors = pickHighlightColorsByValue([
|
|
6368
|
-
"var(--tt-color-highlight-green)",
|
|
6369
|
-
"var(--tt-color-highlight-blue)",
|
|
6370
|
-
"var(--tt-color-highlight-red)",
|
|
6371
|
-
"var(--tt-color-highlight-purple)",
|
|
6372
|
-
"var(--tt-color-highlight-yellow)"
|
|
6373
|
-
])
|
|
6374
|
-
}) {
|
|
6375
|
-
const { handleRemoveHighlight } = useColorHighlight({ editor });
|
|
6376
|
-
const containerRef = useRef10(null);
|
|
6377
|
-
const menuItems = useMemo17(
|
|
6378
|
-
() => [...colors, { label: "Remove highlight", value: "none" }],
|
|
6379
|
-
[colors]
|
|
6380
|
-
);
|
|
6381
|
-
const { selectedIndex } = useMenuNavigation({
|
|
6382
|
-
containerRef,
|
|
6383
|
-
items: menuItems,
|
|
6384
|
-
orientation: "both",
|
|
6385
|
-
onSelect: (item) => {
|
|
6386
|
-
if (!containerRef.current) return false;
|
|
6387
|
-
const highlightedElement = containerRef.current.querySelector(
|
|
6388
|
-
'[data-highlighted="true"]'
|
|
6389
|
-
);
|
|
6390
|
-
if (highlightedElement) highlightedElement.click();
|
|
6391
|
-
if (item.value === "none") handleRemoveHighlight();
|
|
6392
|
-
},
|
|
6393
|
-
autoSelectFirstItem: false
|
|
6394
|
-
});
|
|
6395
|
-
return /* @__PURE__ */ jsxs18("div", { ref: containerRef, className: "flex gap-1 items-center", children: [
|
|
6396
|
-
/* @__PURE__ */ jsx24(
|
|
6397
|
-
"div",
|
|
6398
|
-
{
|
|
6399
|
-
className: "flex items-center gap-1 outline-none",
|
|
6400
|
-
"data-orientation": "horizontal",
|
|
6401
|
-
children: colors.map((color, index) => /* @__PURE__ */ jsx24(
|
|
6402
|
-
ColorHighlightButton,
|
|
6403
|
-
{
|
|
6404
|
-
editor,
|
|
6405
|
-
highlightColor: color.value,
|
|
6406
|
-
"aria-label": `${color.label} highlight color`,
|
|
6407
|
-
tabIndex: index === selectedIndex ? 0 : -1,
|
|
6408
|
-
"data-highlighted": selectedIndex === index
|
|
6409
|
-
},
|
|
6410
|
-
color.value
|
|
6411
|
-
))
|
|
6412
|
-
}
|
|
6413
|
-
),
|
|
6414
|
-
/* @__PURE__ */ jsx24(ToolbarSeparator2, { orientation: "vertical" }),
|
|
6415
|
-
/* @__PURE__ */ jsx24("div", { className: "tiptap-button-group", children: /* @__PURE__ */ jsx24(
|
|
6416
|
-
IconButton8,
|
|
6417
|
-
{
|
|
6418
|
-
onClick: handleRemoveHighlight,
|
|
6419
|
-
"aria-label": "Remove highlight",
|
|
6420
|
-
tabIndex: selectedIndex === colors.length ? 0 : -1,
|
|
6421
|
-
type: "button",
|
|
6422
|
-
role: "menuitem",
|
|
6423
|
-
variant: "ghost",
|
|
6424
|
-
color: "default",
|
|
6425
|
-
"data-highlighted": selectedIndex === colors.length,
|
|
6426
|
-
children: /* @__PURE__ */ jsx24(BanIcon, {})
|
|
6427
|
-
}
|
|
6428
|
-
) })
|
|
6429
|
-
] });
|
|
6430
|
-
}
|
|
6431
|
-
function ColorHighlightPopover({
|
|
6432
|
-
editor: providedEditor,
|
|
6433
|
-
colors = pickHighlightColorsByValue([
|
|
6434
|
-
"var(--tt-color-highlight-green)",
|
|
6435
|
-
"var(--tt-color-highlight-blue)",
|
|
6436
|
-
"var(--tt-color-highlight-red)",
|
|
6437
|
-
"var(--tt-color-highlight-purple)",
|
|
6438
|
-
"var(--tt-color-highlight-yellow)"
|
|
6439
|
-
]),
|
|
6440
|
-
hideWhenUnavailable = false,
|
|
6441
|
-
onApplied,
|
|
6442
|
-
...props
|
|
6443
|
-
}) {
|
|
6444
|
-
const { editor } = useTiptapEditor(providedEditor);
|
|
6445
|
-
const [isOpen, setIsOpen] = useState24(false);
|
|
6446
|
-
const { isVisible, canColorHighlight: canColorHighlight2, isActive, label } = useColorHighlight({
|
|
6447
|
-
editor,
|
|
6448
|
-
hideWhenUnavailable,
|
|
6449
|
-
onApplied
|
|
6450
|
-
});
|
|
6451
|
-
if (!isVisible) return null;
|
|
6452
|
-
return /* @__PURE__ */ jsxs18(Popover2.Root, { open: isOpen, onOpenChange: setIsOpen, spacing: "dense", children: [
|
|
6453
|
-
/* @__PURE__ */ jsx24(
|
|
6454
|
-
Popover2.Trigger,
|
|
6455
|
-
{
|
|
6456
|
-
render: /* @__PURE__ */ jsx24(
|
|
6457
|
-
ColorHighlightPopoverButton,
|
|
6458
|
-
{
|
|
6459
|
-
disabled: !canColorHighlight2,
|
|
6460
|
-
"data-disabled": !canColorHighlight2,
|
|
6461
|
-
"data-active-state": isActive ? "on" : "off",
|
|
6462
|
-
"aria-pressed": isActive,
|
|
6463
|
-
"aria-label": label,
|
|
6464
|
-
title: label,
|
|
6465
|
-
...props
|
|
6466
|
-
}
|
|
6467
|
-
)
|
|
6468
|
-
}
|
|
6469
|
-
),
|
|
6470
|
-
/* @__PURE__ */ jsx24(Popover2.Content, { "aria-label": "Highlight colors", children: /* @__PURE__ */ jsx24(ColorHighlightPopoverContent, { editor, colors }) })
|
|
6471
|
-
] });
|
|
6472
|
-
}
|
|
6473
|
-
|
|
6474
|
-
// src/ui/heading-dropdown-menu/index.tsx
|
|
6475
|
-
import { Button as Button8 } from "@kopexa/button";
|
|
6476
|
-
import { DropdownMenu } from "@kopexa/dropdown-menu";
|
|
6477
|
-
import { isNodeInSchema as isNodeInSchema6 } from "@kopexa/editor-utils";
|
|
6478
|
-
import { ChevronDownIcon, HeadingIcon } from "@kopexa/icons";
|
|
6479
|
-
import { isNodeSelection as isNodeSelection6 } from "@tiptap/react";
|
|
6480
|
-
import * as React19 from "react";
|
|
6743
|
+
// src/ui/text-align-button/text-align-button.tsx
|
|
6744
|
+
import { IconButton as IconButton9 } from "@kopexa/button";
|
|
6745
|
+
import { useTiptapEditor as useTiptapEditor14 } from "@kopexa/editor-utils";
|
|
6746
|
+
import { useCallback as useCallback27 } from "react";
|
|
6481
6747
|
|
|
6482
|
-
// src/ui/
|
|
6483
|
-
import { Button as Button7 } from "@kopexa/button";
|
|
6484
|
-
import { isNodeInSchema as isNodeInSchema5 } from "@kopexa/editor-utils";
|
|
6748
|
+
// src/ui/text-align-button/use-text-align.ts
|
|
6485
6749
|
import {
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6750
|
+
isExtensionAvailable as isExtensionAvailable2,
|
|
6751
|
+
isNodeTypeSelected as isNodeTypeSelected4,
|
|
6752
|
+
useTiptapEditor as useTiptapEditor13
|
|
6753
|
+
} from "@kopexa/editor-utils";
|
|
6754
|
+
import {
|
|
6755
|
+
AlignCenterIcon,
|
|
6756
|
+
AlignJustifyIcon,
|
|
6757
|
+
AlignLeftIcon,
|
|
6758
|
+
AlignRightIcon
|
|
6492
6759
|
} from "@kopexa/icons";
|
|
6493
|
-
import
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
2: "Ctrl-Alt-2",
|
|
6500
|
-
3: "Ctrl-Alt-3",
|
|
6501
|
-
4: "Ctrl-Alt-4",
|
|
6502
|
-
5: "Ctrl-Alt-5",
|
|
6503
|
-
6: "Ctrl-Alt-6"
|
|
6760
|
+
import { useCallback as useCallback26, useEffect as useEffect25, useState as useState24 } from "react";
|
|
6761
|
+
var TEXT_ALIGN_SHORTCUT_KEYS = {
|
|
6762
|
+
left: "mod+shift+l",
|
|
6763
|
+
center: "mod+shift+e",
|
|
6764
|
+
right: "mod+shift+r",
|
|
6765
|
+
justify: "mod+shift+j"
|
|
6504
6766
|
};
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6767
|
+
var textAlignIcons = {
|
|
6768
|
+
left: AlignLeftIcon,
|
|
6769
|
+
center: AlignCenterIcon,
|
|
6770
|
+
right: AlignRightIcon,
|
|
6771
|
+
justify: AlignJustifyIcon
|
|
6772
|
+
};
|
|
6773
|
+
var textAlignLabels = {
|
|
6774
|
+
left: "Align left",
|
|
6775
|
+
center: "Align center",
|
|
6776
|
+
right: "Align right",
|
|
6777
|
+
justify: "Align justify"
|
|
6778
|
+
};
|
|
6779
|
+
function canSetTextAlign(editor, align) {
|
|
6780
|
+
if (!editor || !editor.isEditable) return false;
|
|
6781
|
+
if (!isExtensionAvailable2(editor, "textAlign") || isNodeTypeSelected4(editor, ["image"]))
|
|
6510
6782
|
return false;
|
|
6511
|
-
|
|
6783
|
+
return editor.can().setTextAlign(align);
|
|
6512
6784
|
}
|
|
6513
|
-
function
|
|
6514
|
-
|
|
6515
|
-
return editor.isActive("heading", { level });
|
|
6785
|
+
function hasSetTextAlign(commands) {
|
|
6786
|
+
return "setTextAlign" in commands;
|
|
6516
6787
|
}
|
|
6517
|
-
function
|
|
6518
|
-
if (!editor) return;
|
|
6519
|
-
|
|
6520
|
-
editor.chain().focus().setNode("paragraph").run();
|
|
6521
|
-
} else {
|
|
6522
|
-
editor.chain().focus().toggleNode("heading", "paragraph", { level }).run();
|
|
6523
|
-
}
|
|
6788
|
+
function isTextAlignActive(editor, align) {
|
|
6789
|
+
if (!editor || !editor.isEditable) return false;
|
|
6790
|
+
return editor.isActive({ textAlign: align });
|
|
6524
6791
|
}
|
|
6525
|
-
function
|
|
6526
|
-
if (!editor) return
|
|
6527
|
-
if (
|
|
6528
|
-
|
|
6792
|
+
function setTextAlign(editor, align) {
|
|
6793
|
+
if (!editor || !editor.isEditable) return false;
|
|
6794
|
+
if (!canSetTextAlign(editor, align)) return false;
|
|
6795
|
+
const chain = editor.chain().focus();
|
|
6796
|
+
if (hasSetTextAlign(chain)) {
|
|
6797
|
+
return chain.setTextAlign(align).run();
|
|
6798
|
+
}
|
|
6529
6799
|
return false;
|
|
6530
6800
|
}
|
|
6531
|
-
function
|
|
6532
|
-
const { editor, hideWhenUnavailable,
|
|
6533
|
-
if (!
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6801
|
+
function shouldShowButton3(props) {
|
|
6802
|
+
const { editor, hideWhenUnavailable, align } = props;
|
|
6803
|
+
if (!editor || !editor.isEditable) return false;
|
|
6804
|
+
if (!isExtensionAvailable2(editor, "textAlign")) return false;
|
|
6805
|
+
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
6806
|
+
return canSetTextAlign(editor, align);
|
|
6807
|
+
}
|
|
6808
|
+
return true;
|
|
6809
|
+
}
|
|
6810
|
+
function useTextAlign(config) {
|
|
6811
|
+
const {
|
|
6812
|
+
editor: providedEditor,
|
|
6813
|
+
align,
|
|
6814
|
+
hideWhenUnavailable = false,
|
|
6815
|
+
onAligned
|
|
6816
|
+
} = config;
|
|
6817
|
+
const { editor } = useTiptapEditor13(providedEditor);
|
|
6818
|
+
const [isVisible, setIsVisible] = useState24(true);
|
|
6819
|
+
const canAlign = canSetTextAlign(editor, align);
|
|
6820
|
+
const isActive = isTextAlignActive(editor, align);
|
|
6821
|
+
useEffect25(() => {
|
|
6822
|
+
if (!editor) return;
|
|
6823
|
+
const handleSelectionUpdate = () => {
|
|
6824
|
+
setIsVisible(shouldShowButton3({ editor, align, hideWhenUnavailable }));
|
|
6825
|
+
};
|
|
6826
|
+
handleSelectionUpdate();
|
|
6827
|
+
editor.on("selectionUpdate", handleSelectionUpdate);
|
|
6828
|
+
return () => {
|
|
6829
|
+
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
6830
|
+
};
|
|
6831
|
+
}, [editor, hideWhenUnavailable, align]);
|
|
6832
|
+
const handleTextAlign = useCallback26(() => {
|
|
6833
|
+
if (!editor) return false;
|
|
6834
|
+
const success = setTextAlign(editor, align);
|
|
6835
|
+
if (success) {
|
|
6836
|
+
onAligned == null ? void 0 : onAligned();
|
|
6837
|
+
}
|
|
6838
|
+
return success;
|
|
6839
|
+
}, [editor, align, onAligned]);
|
|
6840
|
+
return {
|
|
6841
|
+
isVisible,
|
|
6842
|
+
isActive,
|
|
6843
|
+
handleTextAlign,
|
|
6844
|
+
canAlign,
|
|
6845
|
+
label: textAlignLabels[align],
|
|
6846
|
+
shortcutKeys: TEXT_ALIGN_SHORTCUT_KEYS[align],
|
|
6847
|
+
Icon: textAlignIcons[align]
|
|
6848
|
+
};
|
|
6849
|
+
}
|
|
6850
|
+
|
|
6851
|
+
// src/ui/text-align-button/text-align-button.tsx
|
|
6852
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
6853
|
+
var TextAlignButton = ({
|
|
6854
|
+
editor: providedEditor,
|
|
6855
|
+
align,
|
|
6856
|
+
text,
|
|
6857
|
+
hideWhenUnavailable = false,
|
|
6858
|
+
onAligned,
|
|
6859
|
+
showShortcut = false,
|
|
6860
|
+
onClick,
|
|
6861
|
+
children,
|
|
6862
|
+
...buttonProps
|
|
6863
|
+
}) => {
|
|
6864
|
+
const { editor } = useTiptapEditor14(providedEditor);
|
|
6865
|
+
const {
|
|
6866
|
+
isVisible,
|
|
6867
|
+
handleTextAlign,
|
|
6868
|
+
label,
|
|
6869
|
+
canAlign,
|
|
6870
|
+
isActive,
|
|
6871
|
+
Icon,
|
|
6872
|
+
shortcutKeys
|
|
6873
|
+
} = useTextAlign({
|
|
6874
|
+
editor,
|
|
6875
|
+
align,
|
|
6876
|
+
hideWhenUnavailable,
|
|
6877
|
+
onAligned
|
|
6878
|
+
});
|
|
6879
|
+
const handleClick = useCallback27(
|
|
6880
|
+
(e) => {
|
|
6881
|
+
onClick == null ? void 0 : onClick(e);
|
|
6882
|
+
if (e.defaultPrevented) return;
|
|
6883
|
+
handleTextAlign();
|
|
6884
|
+
},
|
|
6885
|
+
[handleTextAlign, onClick]
|
|
6886
|
+
);
|
|
6887
|
+
if (!isVisible) {
|
|
6888
|
+
return null;
|
|
6889
|
+
}
|
|
6890
|
+
return /* @__PURE__ */ jsx26(
|
|
6891
|
+
IconButton9,
|
|
6892
|
+
{
|
|
6893
|
+
type: "button",
|
|
6894
|
+
disabled: canAlign,
|
|
6895
|
+
variant: "ghost",
|
|
6896
|
+
color: "default",
|
|
6897
|
+
"data-active-state": isActive ? "on" : "off",
|
|
6898
|
+
"data-disabled": canAlign,
|
|
6899
|
+
tabIndex: -1,
|
|
6900
|
+
"aria-label": label,
|
|
6901
|
+
"aria-pressed": isActive,
|
|
6902
|
+
tooltip: label,
|
|
6903
|
+
shortcutKeys,
|
|
6904
|
+
onClick: handleClick,
|
|
6905
|
+
...buttonProps,
|
|
6906
|
+
children: /* @__PURE__ */ jsx26(Icon, {})
|
|
6907
|
+
}
|
|
6908
|
+
);
|
|
6909
|
+
};
|
|
6910
|
+
|
|
6911
|
+
// src/ui/turn-into-dropdown/turn-into-dropdown.tsx
|
|
6912
|
+
import { Button as Button11 } from "@kopexa/button";
|
|
6913
|
+
import { DropdownMenu as DropdownMenu2 } from "@kopexa/dropdown-menu";
|
|
6914
|
+
import { useTiptapEditor as useTiptapEditor23 } from "@kopexa/editor-utils";
|
|
6915
|
+
import { forwardRef } from "react";
|
|
6916
|
+
|
|
6917
|
+
// src/ui/blockquote-button/blockquote-button.tsx
|
|
6918
|
+
import { useTiptapEditor as useTiptapEditor16 } from "@kopexa/editor-utils";
|
|
6919
|
+
import { ToolbarButton as ToolbarButton5 } from "@kopexa/toolbar";
|
|
6920
|
+
import * as React16 from "react";
|
|
6921
|
+
|
|
6922
|
+
// src/ui/blockquote-button/use-blockquote.ts
|
|
6923
|
+
import {
|
|
6924
|
+
findNodePosition,
|
|
6925
|
+
isNodeInSchema as isNodeInSchema5,
|
|
6926
|
+
isNodeTypeSelected as isNodeTypeSelected5,
|
|
6927
|
+
isValidPosition,
|
|
6928
|
+
useTiptapEditor as useTiptapEditor15
|
|
6929
|
+
} from "@kopexa/editor-utils";
|
|
6930
|
+
import { BlockquoteIcon as BlockquoteIcon2 } from "@kopexa/icons";
|
|
6931
|
+
import { NodeSelection as NodeSelection2, TextSelection as TextSelection2 } from "@tiptap/pm/state";
|
|
6932
|
+
import * as React15 from "react";
|
|
6933
|
+
var BLOCKQUOTE_SHORTCUT_KEY = "mod+shift+b";
|
|
6934
|
+
function canToggleBlockquote(editor, turnInto = true) {
|
|
6935
|
+
var _a;
|
|
6936
|
+
if (!editor || !editor.isEditable) return false;
|
|
6937
|
+
if (!isNodeInSchema5("blockquote", editor) || isNodeTypeSelected5(editor, ["image"]))
|
|
6938
|
+
return false;
|
|
6939
|
+
if (!turnInto) {
|
|
6940
|
+
return editor.can().toggleWrap("blockquote");
|
|
6941
|
+
}
|
|
6942
|
+
try {
|
|
6943
|
+
const view = editor.view;
|
|
6944
|
+
const state = view.state;
|
|
6945
|
+
const selection = state.selection;
|
|
6946
|
+
if (selection.empty || selection instanceof TextSelection2) {
|
|
6947
|
+
const pos = (_a = findNodePosition({
|
|
6948
|
+
editor,
|
|
6949
|
+
node: state.selection.$anchor.node(1)
|
|
6950
|
+
})) == null ? void 0 : _a.pos;
|
|
6951
|
+
if (!isValidPosition(pos)) return false;
|
|
6952
|
+
}
|
|
6953
|
+
return true;
|
|
6954
|
+
} catch {
|
|
6955
|
+
return false;
|
|
6956
|
+
}
|
|
6957
|
+
}
|
|
6958
|
+
function toggleBlockquote(editor) {
|
|
6959
|
+
var _a, _b, _c;
|
|
6960
|
+
if (!editor || !editor.isEditable) return false;
|
|
6961
|
+
if (!canToggleBlockquote(editor)) return false;
|
|
6962
|
+
try {
|
|
6963
|
+
const view = editor.view;
|
|
6964
|
+
let state = view.state;
|
|
6965
|
+
let tr = state.tr;
|
|
6966
|
+
if (state.selection.empty || state.selection instanceof TextSelection2) {
|
|
6967
|
+
const pos = (_a = findNodePosition({
|
|
6968
|
+
editor,
|
|
6969
|
+
node: state.selection.$anchor.node(1)
|
|
6970
|
+
})) == null ? void 0 : _a.pos;
|
|
6971
|
+
if (!isValidPosition(pos)) return false;
|
|
6972
|
+
tr = tr.setSelection(NodeSelection2.create(state.doc, pos));
|
|
6973
|
+
view.dispatch(tr);
|
|
6974
|
+
state = view.state;
|
|
6975
|
+
}
|
|
6976
|
+
const selection = state.selection;
|
|
6977
|
+
let chain = editor.chain().focus();
|
|
6978
|
+
if (selection instanceof NodeSelection2) {
|
|
6979
|
+
const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
|
|
6980
|
+
const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
|
|
6981
|
+
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
6982
|
+
const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
|
|
6983
|
+
chain = chain.setTextSelection({ from, to }).clearNodes();
|
|
6984
|
+
}
|
|
6985
|
+
const toggle = editor.isActive("blockquote") ? chain.lift("blockquote") : chain.wrapIn("blockquote");
|
|
6986
|
+
toggle.run();
|
|
6987
|
+
editor.chain().focus().selectTextblockEnd().run();
|
|
6988
|
+
return true;
|
|
6989
|
+
} catch {
|
|
6990
|
+
return false;
|
|
6991
|
+
}
|
|
6992
|
+
}
|
|
6993
|
+
function shouldShowButton4(props) {
|
|
6994
|
+
const { editor, hideWhenUnavailable } = props;
|
|
6995
|
+
if (!editor || !editor.isEditable) return false;
|
|
6996
|
+
if (!isNodeInSchema5("blockquote", editor)) return false;
|
|
6997
|
+
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
6998
|
+
return canToggleBlockquote(editor);
|
|
6999
|
+
}
|
|
7000
|
+
return true;
|
|
7001
|
+
}
|
|
7002
|
+
function useBlockquote(config) {
|
|
7003
|
+
const {
|
|
7004
|
+
editor: providedEditor,
|
|
7005
|
+
hideWhenUnavailable = false,
|
|
7006
|
+
onToggled
|
|
7007
|
+
} = config || {};
|
|
7008
|
+
const { editor } = useTiptapEditor15(providedEditor);
|
|
7009
|
+
const [isVisible, setIsVisible] = React15.useState(true);
|
|
7010
|
+
const canToggle3 = canToggleBlockquote(editor);
|
|
7011
|
+
const isActive = (editor == null ? void 0 : editor.isActive("blockquote")) || false;
|
|
7012
|
+
React15.useEffect(() => {
|
|
7013
|
+
if (!editor) return;
|
|
7014
|
+
const handleSelectionUpdate = () => {
|
|
7015
|
+
setIsVisible(shouldShowButton4({ editor, hideWhenUnavailable }));
|
|
7016
|
+
};
|
|
7017
|
+
handleSelectionUpdate();
|
|
7018
|
+
editor.on("selectionUpdate", handleSelectionUpdate);
|
|
7019
|
+
return () => {
|
|
7020
|
+
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
7021
|
+
};
|
|
7022
|
+
}, [editor, hideWhenUnavailable]);
|
|
7023
|
+
const handleToggle = React15.useCallback(() => {
|
|
7024
|
+
if (!editor) return false;
|
|
7025
|
+
const success = toggleBlockquote(editor);
|
|
7026
|
+
if (success) {
|
|
7027
|
+
onToggled == null ? void 0 : onToggled();
|
|
7028
|
+
}
|
|
7029
|
+
return success;
|
|
7030
|
+
}, [editor, onToggled]);
|
|
7031
|
+
return {
|
|
7032
|
+
isVisible,
|
|
7033
|
+
isActive,
|
|
7034
|
+
handleToggle,
|
|
7035
|
+
canToggle: canToggle3,
|
|
7036
|
+
label: "Blockquote",
|
|
7037
|
+
shortcutKeys: BLOCKQUOTE_SHORTCUT_KEY,
|
|
7038
|
+
Icon: BlockquoteIcon2
|
|
7039
|
+
};
|
|
7040
|
+
}
|
|
7041
|
+
|
|
7042
|
+
// src/ui/blockquote-button/blockquote-button.tsx
|
|
7043
|
+
import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
7044
|
+
var BlockquoteButton = ({
|
|
7045
|
+
editor: providedEditor,
|
|
7046
|
+
text,
|
|
7047
|
+
hideWhenUnavailable = false,
|
|
7048
|
+
onToggled,
|
|
7049
|
+
showShortcut = false,
|
|
7050
|
+
onClick,
|
|
7051
|
+
children,
|
|
7052
|
+
...buttonProps
|
|
7053
|
+
}) => {
|
|
7054
|
+
const { editor } = useTiptapEditor16(providedEditor);
|
|
7055
|
+
const {
|
|
7056
|
+
isVisible,
|
|
7057
|
+
canToggle: canToggle3,
|
|
7058
|
+
isActive,
|
|
7059
|
+
handleToggle,
|
|
7060
|
+
label,
|
|
7061
|
+
shortcutKeys,
|
|
7062
|
+
Icon
|
|
7063
|
+
} = useBlockquote({
|
|
7064
|
+
editor,
|
|
7065
|
+
hideWhenUnavailable,
|
|
7066
|
+
onToggled
|
|
7067
|
+
});
|
|
7068
|
+
const handleClick = React16.useCallback(
|
|
7069
|
+
(event) => {
|
|
7070
|
+
onClick == null ? void 0 : onClick(event);
|
|
7071
|
+
if (event.defaultPrevented) return;
|
|
7072
|
+
handleToggle();
|
|
7073
|
+
},
|
|
7074
|
+
[handleToggle, onClick]
|
|
7075
|
+
);
|
|
7076
|
+
if (!isVisible) {
|
|
7077
|
+
return null;
|
|
7078
|
+
}
|
|
7079
|
+
return /* @__PURE__ */ jsx27(
|
|
7080
|
+
ToolbarButton5,
|
|
7081
|
+
{
|
|
7082
|
+
type: "button",
|
|
7083
|
+
variant: "ghost",
|
|
7084
|
+
color: "default",
|
|
7085
|
+
disabled: !canToggle3,
|
|
7086
|
+
"data-disabled": !canToggle3,
|
|
7087
|
+
"data-active-state": isActive ? "on" : "off",
|
|
7088
|
+
tabIndex: -1,
|
|
7089
|
+
"aria-label": "blockquote",
|
|
7090
|
+
"aria-pressed": isActive,
|
|
7091
|
+
title: label,
|
|
7092
|
+
shortcutKeys,
|
|
7093
|
+
onClick: handleClick,
|
|
7094
|
+
isIconOnly: !text && !children,
|
|
7095
|
+
...buttonProps,
|
|
7096
|
+
children: children != null ? children : /* @__PURE__ */ jsxs20(Fragment6, { children: [
|
|
7097
|
+
/* @__PURE__ */ jsx27(Icon, {}),
|
|
7098
|
+
text && /* @__PURE__ */ jsx27("span", { children: text })
|
|
7099
|
+
] })
|
|
7100
|
+
}
|
|
7101
|
+
);
|
|
7102
|
+
};
|
|
7103
|
+
|
|
7104
|
+
// src/ui/codeblock-button/code-block-button.tsx
|
|
7105
|
+
import { useTiptapEditor as useTiptapEditor18 } from "@kopexa/editor-utils";
|
|
7106
|
+
import { CodeblockIcon as CodeblockIcon2 } from "@kopexa/icons";
|
|
7107
|
+
import { ToolbarButton as ToolbarButton6 } from "@kopexa/toolbar";
|
|
7108
|
+
import { useCallback as useCallback31 } from "react";
|
|
7109
|
+
|
|
7110
|
+
// src/ui/codeblock-button/use-code-block.ts
|
|
7111
|
+
import {
|
|
7112
|
+
findNodePosition as findNodePosition2,
|
|
7113
|
+
isNodeInSchema as isNodeInSchema6,
|
|
7114
|
+
isNodeTypeSelected as isNodeTypeSelected6,
|
|
7115
|
+
isValidPosition as isValidPosition2,
|
|
7116
|
+
useTiptapEditor as useTiptapEditor17
|
|
7117
|
+
} from "@kopexa/editor-utils";
|
|
7118
|
+
import { CodeblockIcon } from "@kopexa/icons";
|
|
7119
|
+
import { NodeSelection as NodeSelection3, TextSelection as TextSelection3 } from "@tiptap/pm/state";
|
|
7120
|
+
import * as React17 from "react";
|
|
7121
|
+
var CODE_BLOCK_SHORTCUT_KEY = "mod+alt+c";
|
|
7122
|
+
function canToggle2(editor, turnInto = true) {
|
|
7123
|
+
var _a;
|
|
7124
|
+
if (!editor || !editor.isEditable) return false;
|
|
7125
|
+
if (!isNodeInSchema6("codeBlock", editor) || isNodeTypeSelected6(editor, ["image"]))
|
|
7126
|
+
return false;
|
|
7127
|
+
if (!turnInto) {
|
|
7128
|
+
return editor.can().toggleNode("codeBlock", "paragraph");
|
|
7129
|
+
}
|
|
7130
|
+
try {
|
|
7131
|
+
const view = editor.view;
|
|
7132
|
+
const state = view.state;
|
|
7133
|
+
const selection = state.selection;
|
|
7134
|
+
if (selection.empty || selection instanceof TextSelection3) {
|
|
7135
|
+
const pos = (_a = findNodePosition2({
|
|
7136
|
+
editor,
|
|
7137
|
+
node: state.selection.$anchor.node(1)
|
|
7138
|
+
})) == null ? void 0 : _a.pos;
|
|
7139
|
+
if (!isValidPosition2(pos)) return false;
|
|
6539
7140
|
}
|
|
7141
|
+
return true;
|
|
7142
|
+
} catch {
|
|
7143
|
+
return false;
|
|
7144
|
+
}
|
|
7145
|
+
}
|
|
7146
|
+
function toggleCodeBlock(editor) {
|
|
7147
|
+
var _a, _b, _c;
|
|
7148
|
+
if (!editor || !editor.isEditable) return false;
|
|
7149
|
+
if (!canToggle2(editor)) return false;
|
|
7150
|
+
try {
|
|
7151
|
+
const view = editor.view;
|
|
7152
|
+
let state = view.state;
|
|
7153
|
+
let tr = state.tr;
|
|
7154
|
+
if (state.selection.empty || state.selection instanceof TextSelection3) {
|
|
7155
|
+
const pos = (_a = findNodePosition2({
|
|
7156
|
+
editor,
|
|
7157
|
+
node: state.selection.$anchor.node(1)
|
|
7158
|
+
})) == null ? void 0 : _a.pos;
|
|
7159
|
+
if (!isValidPosition2(pos)) return false;
|
|
7160
|
+
tr = tr.setSelection(NodeSelection3.create(state.doc, pos));
|
|
7161
|
+
view.dispatch(tr);
|
|
7162
|
+
state = view.state;
|
|
7163
|
+
}
|
|
7164
|
+
const selection = state.selection;
|
|
7165
|
+
let chain = editor.chain().focus();
|
|
7166
|
+
if (selection instanceof NodeSelection3) {
|
|
7167
|
+
const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
|
|
7168
|
+
const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
|
|
7169
|
+
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
7170
|
+
const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
|
|
7171
|
+
chain = chain.setTextSelection({ from, to }).clearNodes();
|
|
7172
|
+
}
|
|
7173
|
+
const toggle = editor.isActive("codeBlock") ? chain.setNode("paragraph") : chain.toggleNode("codeBlock", "paragraph");
|
|
7174
|
+
toggle.run();
|
|
7175
|
+
editor.chain().focus().selectTextblockEnd().run();
|
|
7176
|
+
return true;
|
|
7177
|
+
} catch {
|
|
7178
|
+
return false;
|
|
7179
|
+
}
|
|
7180
|
+
}
|
|
7181
|
+
function shouldShowButton5(props) {
|
|
7182
|
+
const { editor, hideWhenUnavailable } = props;
|
|
7183
|
+
if (!editor || !editor.isEditable) return false;
|
|
7184
|
+
if (!isNodeInSchema6("codeBlock", editor)) return false;
|
|
7185
|
+
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
7186
|
+
return canToggle2(editor);
|
|
6540
7187
|
}
|
|
6541
7188
|
return true;
|
|
6542
7189
|
}
|
|
6543
|
-
function
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
};
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
7190
|
+
function useCodeBlock(config) {
|
|
7191
|
+
const {
|
|
7192
|
+
editor: providedEditor,
|
|
7193
|
+
hideWhenUnavailable = false,
|
|
7194
|
+
onToggled
|
|
7195
|
+
} = config || {};
|
|
7196
|
+
const { editor } = useTiptapEditor17(providedEditor);
|
|
7197
|
+
const [isVisible, setIsVisible] = React17.useState(true);
|
|
7198
|
+
const canToggleState = canToggle2(editor);
|
|
7199
|
+
const isActive = (editor == null ? void 0 : editor.isActive("codeBlock")) || false;
|
|
7200
|
+
React17.useEffect(() => {
|
|
7201
|
+
if (!editor) return;
|
|
7202
|
+
const handleSelectionUpdate = () => {
|
|
7203
|
+
setIsVisible(shouldShowButton5({ editor, hideWhenUnavailable }));
|
|
7204
|
+
};
|
|
7205
|
+
handleSelectionUpdate();
|
|
7206
|
+
editor.on("selectionUpdate", handleSelectionUpdate);
|
|
7207
|
+
return () => {
|
|
7208
|
+
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
7209
|
+
};
|
|
7210
|
+
}, [editor, hideWhenUnavailable]);
|
|
7211
|
+
const handleToggle = React17.useCallback(() => {
|
|
7212
|
+
if (!editor) return false;
|
|
7213
|
+
const success = toggleCodeBlock(editor);
|
|
7214
|
+
if (success) {
|
|
7215
|
+
onToggled == null ? void 0 : onToggled();
|
|
7216
|
+
}
|
|
7217
|
+
return success;
|
|
7218
|
+
}, [editor, onToggled]);
|
|
6564
7219
|
return {
|
|
6565
|
-
|
|
6566
|
-
isDisabled,
|
|
7220
|
+
isVisible,
|
|
6567
7221
|
isActive,
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
7222
|
+
handleToggle,
|
|
7223
|
+
canToggle: canToggleState,
|
|
7224
|
+
label: "Code Block",
|
|
7225
|
+
shortcutKeys: CODE_BLOCK_SHORTCUT_KEY,
|
|
7226
|
+
Icon: CodeblockIcon
|
|
6571
7227
|
};
|
|
6572
7228
|
}
|
|
6573
|
-
|
|
7229
|
+
|
|
7230
|
+
// src/ui/codeblock-button/code-block-button.tsx
|
|
7231
|
+
import { Fragment as Fragment7, jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
7232
|
+
var CodeBlockButton = ({
|
|
6574
7233
|
editor: providedEditor,
|
|
6575
|
-
level,
|
|
6576
7234
|
text,
|
|
6577
7235
|
hideWhenUnavailable = false,
|
|
6578
|
-
|
|
6579
|
-
|
|
7236
|
+
onToggled,
|
|
7237
|
+
showShortcut = false,
|
|
6580
7238
|
onClick,
|
|
6581
7239
|
children,
|
|
6582
|
-
ref,
|
|
6583
7240
|
...buttonProps
|
|
6584
7241
|
}) => {
|
|
6585
|
-
const { editor } =
|
|
6586
|
-
const {
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
onClick == null ? void 0 : onClick(e);
|
|
6597
|
-
if (!e.defaultPrevented && !isDisabled && editor) {
|
|
6598
|
-
toggleHeading(editor, level);
|
|
6599
|
-
}
|
|
7242
|
+
const { editor } = useTiptapEditor18(providedEditor);
|
|
7243
|
+
const { isVisible, canToggle: canToggle3, isActive, handleToggle, label, shortcutKeys } = useCodeBlock({
|
|
7244
|
+
editor,
|
|
7245
|
+
hideWhenUnavailable,
|
|
7246
|
+
onToggled
|
|
7247
|
+
});
|
|
7248
|
+
const handleClick = useCallback31(
|
|
7249
|
+
(event) => {
|
|
7250
|
+
onClick == null ? void 0 : onClick(event);
|
|
7251
|
+
if (event.defaultPrevented) return;
|
|
7252
|
+
handleToggle();
|
|
6600
7253
|
},
|
|
6601
|
-
[
|
|
7254
|
+
[handleToggle, onClick]
|
|
6602
7255
|
);
|
|
6603
|
-
|
|
6604
|
-
return shouldShowHeadingButton({
|
|
6605
|
-
editor,
|
|
6606
|
-
level,
|
|
6607
|
-
hideWhenUnavailable,
|
|
6608
|
-
headingInSchema
|
|
6609
|
-
});
|
|
6610
|
-
}, [editor, level, hideWhenUnavailable, headingInSchema]);
|
|
6611
|
-
if (!show || !editor || !editor.isEditable) {
|
|
7256
|
+
if (!isVisible) {
|
|
6612
7257
|
return null;
|
|
6613
7258
|
}
|
|
6614
|
-
return /* @__PURE__ */
|
|
6615
|
-
|
|
7259
|
+
return /* @__PURE__ */ jsx28(
|
|
7260
|
+
ToolbarButton6,
|
|
6616
7261
|
{
|
|
6617
7262
|
type: "button",
|
|
6618
|
-
className: className.trim(),
|
|
6619
|
-
disabled: isDisabled,
|
|
6620
7263
|
variant: "ghost",
|
|
6621
7264
|
color: "default",
|
|
7265
|
+
disabled: !canToggle3,
|
|
7266
|
+
"data-disabled": !canToggle3,
|
|
6622
7267
|
"data-active-state": isActive ? "on" : "off",
|
|
6623
|
-
"data-disabled": isDisabled,
|
|
6624
7268
|
tabIndex: -1,
|
|
6625
|
-
"aria-label":
|
|
7269
|
+
"aria-label": "codeBlock",
|
|
6626
7270
|
"aria-pressed": isActive,
|
|
6627
|
-
|
|
6628
|
-
shortcutKeys
|
|
7271
|
+
title: label,
|
|
7272
|
+
shortcutKeys,
|
|
6629
7273
|
onClick: handleClick,
|
|
6630
|
-
|
|
7274
|
+
isIconOnly: !text && !children,
|
|
6631
7275
|
...buttonProps,
|
|
6632
|
-
|
|
6633
|
-
|
|
7276
|
+
children: children != null ? children : /* @__PURE__ */ jsxs21(Fragment7, { children: [
|
|
7277
|
+
/* @__PURE__ */ jsx28(CodeblockIcon2, {}),
|
|
7278
|
+
text && /* @__PURE__ */ jsx28("span", { children: text })
|
|
7279
|
+
] })
|
|
6634
7280
|
}
|
|
6635
7281
|
);
|
|
6636
7282
|
};
|
|
6637
7283
|
|
|
6638
|
-
// src/ui/heading-
|
|
6639
|
-
import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
6640
|
-
function HeadingDropdownMenu({
|
|
6641
|
-
editor: providedEditor,
|
|
6642
|
-
levels = [1, 2, 3, 4, 5, 6],
|
|
6643
|
-
hideWhenUnavailable = false,
|
|
6644
|
-
onOpenChange,
|
|
6645
|
-
...props
|
|
6646
|
-
}) {
|
|
6647
|
-
var _a;
|
|
6648
|
-
const [isOpen, setIsOpen] = React19.useState(false);
|
|
6649
|
-
const { editor } = useTiptapEditor(providedEditor);
|
|
6650
|
-
const headingInSchema = isNodeInSchema6("heading", editor);
|
|
6651
|
-
const handleOnOpenChange = React19.useCallback(
|
|
6652
|
-
(open) => {
|
|
6653
|
-
setIsOpen(open);
|
|
6654
|
-
onOpenChange == null ? void 0 : onOpenChange(open);
|
|
6655
|
-
},
|
|
6656
|
-
[onOpenChange]
|
|
6657
|
-
);
|
|
6658
|
-
const getActiveIcon = React19.useCallback(() => {
|
|
6659
|
-
if (!editor) return /* @__PURE__ */ jsx26(HeadingIcon, {});
|
|
6660
|
-
const activeLevel = levels.find(
|
|
6661
|
-
(level) => editor.isActive("heading", { level })
|
|
6662
|
-
);
|
|
6663
|
-
if (!activeLevel) return /* @__PURE__ */ jsx26(HeadingIcon, {});
|
|
6664
|
-
const ActiveIcon = headingIcons[activeLevel];
|
|
6665
|
-
return /* @__PURE__ */ jsx26(ActiveIcon, {});
|
|
6666
|
-
}, [editor, levels]);
|
|
6667
|
-
const canToggleAnyHeading = React19.useCallback(() => {
|
|
6668
|
-
if (!editor) return false;
|
|
6669
|
-
return levels.some(
|
|
6670
|
-
(level) => editor.can().toggleNode("heading", "paragraph", { level })
|
|
6671
|
-
);
|
|
6672
|
-
}, [editor, levels]);
|
|
6673
|
-
const isDisabled = !canToggleAnyHeading();
|
|
6674
|
-
const isAnyHeadingActive = (_a = editor == null ? void 0 : editor.isActive("heading")) != null ? _a : false;
|
|
6675
|
-
const show = React19.useMemo(() => {
|
|
6676
|
-
if (!headingInSchema || !editor) {
|
|
6677
|
-
return false;
|
|
6678
|
-
}
|
|
6679
|
-
if (hideWhenUnavailable) {
|
|
6680
|
-
if (isNodeSelection6(editor.state.selection) || !canToggleAnyHeading()) {
|
|
6681
|
-
return false;
|
|
6682
|
-
}
|
|
6683
|
-
}
|
|
6684
|
-
return true;
|
|
6685
|
-
}, [headingInSchema, editor, hideWhenUnavailable, canToggleAnyHeading]);
|
|
6686
|
-
if (!show || !editor || !editor.isEditable) {
|
|
6687
|
-
return null;
|
|
6688
|
-
}
|
|
6689
|
-
return /* @__PURE__ */ jsxs19(DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
|
|
6690
|
-
/* @__PURE__ */ jsx26(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx26(
|
|
6691
|
-
Button8,
|
|
6692
|
-
{
|
|
6693
|
-
type: "button",
|
|
6694
|
-
disabled: isDisabled,
|
|
6695
|
-
variant: "ghost",
|
|
6696
|
-
color: "default",
|
|
6697
|
-
"data-active-state": isAnyHeadingActive ? "on" : "off",
|
|
6698
|
-
"data-disabled": isDisabled,
|
|
6699
|
-
tabIndex: -1,
|
|
6700
|
-
"aria-label": "Format text as heading",
|
|
6701
|
-
"aria-pressed": isAnyHeadingActive,
|
|
6702
|
-
tooltip: "Heading",
|
|
6703
|
-
endContent: /* @__PURE__ */ jsx26(ChevronDownIcon, {}),
|
|
6704
|
-
...props,
|
|
6705
|
-
children: getActiveIcon()
|
|
6706
|
-
}
|
|
6707
|
-
) }),
|
|
6708
|
-
/* @__PURE__ */ jsx26(DropdownMenu.Content, { children: /* @__PURE__ */ jsx26(DropdownMenu.Group, { children: levels.map((level) => /* @__PURE__ */ jsx26(DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ jsx26(
|
|
6709
|
-
HeadingButton,
|
|
6710
|
-
{
|
|
6711
|
-
editor,
|
|
6712
|
-
level,
|
|
6713
|
-
text: getFormattedHeadingName(level),
|
|
6714
|
-
tooltip: "",
|
|
6715
|
-
fullWidth: true,
|
|
6716
|
-
spacing: "start"
|
|
6717
|
-
}
|
|
6718
|
-
) }, `heading-${level}`)) }) })
|
|
6719
|
-
] });
|
|
6720
|
-
}
|
|
6721
|
-
|
|
6722
|
-
// src/ui/list-dropdown-menu/index.tsx
|
|
6723
|
-
import { Button as Button10 } from "@kopexa/button";
|
|
6724
|
-
import { DropdownMenu as DropdownMenu2 } from "@kopexa/dropdown-menu";
|
|
6725
|
-
import { isNodeInSchema as isNodeInSchema8 } from "@kopexa/editor-utils";
|
|
6726
|
-
import { ChevronDownIcon as ChevronDownIcon2, ListIcon as ListIcon4 } from "@kopexa/icons";
|
|
6727
|
-
import { isNodeSelection as isNodeSelection8 } from "@tiptap/react";
|
|
6728
|
-
import { useCallback as useCallback30, useMemo as useMemo21, useState as useState26 } from "react";
|
|
6729
|
-
|
|
6730
|
-
// src/ui/list-button/index.tsx
|
|
7284
|
+
// src/ui/heading-button/index.tsx
|
|
6731
7285
|
import { Button as Button9 } from "@kopexa/button";
|
|
6732
|
-
import { isNodeInSchema as isNodeInSchema7 } from "@kopexa/editor-utils";
|
|
6733
|
-
import {
|
|
7286
|
+
import { isNodeInSchema as isNodeInSchema7, useTiptapEditor as useTiptapEditor19 } from "@kopexa/editor-utils";
|
|
7287
|
+
import {
|
|
7288
|
+
HeadingFiveIcon,
|
|
7289
|
+
HeadingFourIcon,
|
|
7290
|
+
HeadingOneIcon as HeadingOneIcon2,
|
|
7291
|
+
HeadingSixIcon,
|
|
7292
|
+
HeadingThreeIcon as HeadingThreeIcon2,
|
|
7293
|
+
HeadingTwoIcon as HeadingTwoIcon2
|
|
7294
|
+
} from "@kopexa/icons";
|
|
7295
|
+
import * as React18 from "react";
|
|
7296
|
+
|
|
7297
|
+
// src/ui/heading-button/utils.ts
|
|
6734
7298
|
import { isNodeSelection as isNodeSelection7 } from "@tiptap/react";
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
},
|
|
6743
|
-
{
|
|
6744
|
-
label: "Ordered List",
|
|
6745
|
-
type: "orderedList",
|
|
6746
|
-
icon: ListOrderedIcon2
|
|
6747
|
-
},
|
|
6748
|
-
{
|
|
6749
|
-
label: "Task List",
|
|
6750
|
-
type: "taskList",
|
|
6751
|
-
icon: ListTodoIcon2
|
|
6752
|
-
}
|
|
6753
|
-
];
|
|
6754
|
-
var listShortcutKeys = {
|
|
6755
|
-
bulletList: "Ctrl-Shift-8",
|
|
6756
|
-
orderedList: "Ctrl-Shift-7",
|
|
6757
|
-
taskList: "Ctrl-Shift-9"
|
|
7299
|
+
var headingShortcutKeys = {
|
|
7300
|
+
1: "Ctrl-Alt-1",
|
|
7301
|
+
2: "Ctrl-Alt-2",
|
|
7302
|
+
3: "Ctrl-Alt-3",
|
|
7303
|
+
4: "Ctrl-Alt-4",
|
|
7304
|
+
5: "Ctrl-Alt-5",
|
|
7305
|
+
6: "Ctrl-Alt-6"
|
|
6758
7306
|
};
|
|
6759
|
-
function
|
|
6760
|
-
if (!editor)
|
|
7307
|
+
function canToggleHeading(editor, level) {
|
|
7308
|
+
if (!editor) return false;
|
|
7309
|
+
try {
|
|
7310
|
+
return editor.can().toggleNode("heading", "paragraph", { level });
|
|
7311
|
+
} catch {
|
|
6761
7312
|
return false;
|
|
6762
7313
|
}
|
|
6763
|
-
switch (type) {
|
|
6764
|
-
case "bulletList":
|
|
6765
|
-
return editor.can().toggleBulletList();
|
|
6766
|
-
case "orderedList":
|
|
6767
|
-
return editor.can().toggleOrderedList();
|
|
6768
|
-
case "taskList":
|
|
6769
|
-
return editor.can().toggleList("taskList", "taskItem");
|
|
6770
|
-
default:
|
|
6771
|
-
return false;
|
|
6772
|
-
}
|
|
6773
7314
|
}
|
|
6774
|
-
function
|
|
7315
|
+
function isHeadingActive(editor, level) {
|
|
6775
7316
|
if (!editor) return false;
|
|
6776
|
-
|
|
6777
|
-
case "bulletList":
|
|
6778
|
-
return editor.isActive("bulletList");
|
|
6779
|
-
case "orderedList":
|
|
6780
|
-
return editor.isActive("orderedList");
|
|
6781
|
-
case "taskList":
|
|
6782
|
-
return editor.isActive("taskList");
|
|
6783
|
-
default:
|
|
6784
|
-
return false;
|
|
6785
|
-
}
|
|
7317
|
+
return editor.isActive("heading", { level });
|
|
6786
7318
|
}
|
|
6787
|
-
function
|
|
7319
|
+
function toggleHeading(editor, level) {
|
|
6788
7320
|
if (!editor) return;
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
case "orderedList":
|
|
6794
|
-
editor.chain().focus().toggleOrderedList().run();
|
|
6795
|
-
break;
|
|
6796
|
-
case "taskList":
|
|
6797
|
-
editor.chain().focus().toggleList("taskList", "taskItem").run();
|
|
6798
|
-
break;
|
|
7321
|
+
if (editor.isActive("heading", { level })) {
|
|
7322
|
+
editor.chain().focus().setNode("paragraph").run();
|
|
7323
|
+
} else {
|
|
7324
|
+
editor.chain().focus().toggleNode("heading", "paragraph", { level }).run();
|
|
6799
7325
|
}
|
|
6800
7326
|
}
|
|
6801
|
-
function
|
|
6802
|
-
|
|
7327
|
+
function isHeadingButtonDisabled(editor, level, userDisabled = false) {
|
|
7328
|
+
if (!editor) return true;
|
|
7329
|
+
if (userDisabled) return true;
|
|
7330
|
+
if (!canToggleHeading(editor, level)) return true;
|
|
7331
|
+
return false;
|
|
6803
7332
|
}
|
|
6804
|
-
function
|
|
6805
|
-
const { editor,
|
|
6806
|
-
if (!
|
|
7333
|
+
function shouldShowHeadingButton(params) {
|
|
7334
|
+
const { editor, hideWhenUnavailable, headingInSchema } = params;
|
|
7335
|
+
if (!headingInSchema || !editor) {
|
|
6807
7336
|
return false;
|
|
6808
7337
|
}
|
|
6809
7338
|
if (hideWhenUnavailable) {
|
|
6810
|
-
if (isNodeSelection7(editor.state.selection)
|
|
7339
|
+
if (isNodeSelection7(editor.state.selection)) {
|
|
6811
7340
|
return false;
|
|
6812
7341
|
}
|
|
6813
7342
|
}
|
|
6814
7343
|
return true;
|
|
6815
7344
|
}
|
|
6816
|
-
function
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
7345
|
+
function getFormattedHeadingName(level) {
|
|
7346
|
+
return `Heading ${level}`;
|
|
7347
|
+
}
|
|
7348
|
+
|
|
7349
|
+
// src/ui/heading-button/index.tsx
|
|
7350
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
7351
|
+
var headingIcons = {
|
|
7352
|
+
1: HeadingOneIcon2,
|
|
7353
|
+
2: HeadingTwoIcon2,
|
|
7354
|
+
3: HeadingThreeIcon2,
|
|
7355
|
+
4: HeadingFourIcon,
|
|
7356
|
+
5: HeadingFiveIcon,
|
|
7357
|
+
6: HeadingSixIcon
|
|
7358
|
+
};
|
|
7359
|
+
function useHeadingState(editor, level, disabled = false) {
|
|
7360
|
+
const headingInSchema = isNodeInSchema7("heading", editor);
|
|
7361
|
+
const isDisabled = isHeadingButtonDisabled(editor, level, disabled);
|
|
7362
|
+
const isActive = isHeadingActive(editor, level);
|
|
7363
|
+
const Icon = headingIcons[level];
|
|
7364
|
+
const shortcutKey = headingShortcutKeys[level];
|
|
7365
|
+
const formattedName = getFormattedHeadingName(level);
|
|
6821
7366
|
return {
|
|
6822
|
-
|
|
6823
|
-
|
|
7367
|
+
headingInSchema,
|
|
7368
|
+
isDisabled,
|
|
6824
7369
|
isActive,
|
|
6825
|
-
|
|
7370
|
+
Icon,
|
|
7371
|
+
shortcutKey,
|
|
7372
|
+
formattedName
|
|
6826
7373
|
};
|
|
6827
7374
|
}
|
|
6828
|
-
var
|
|
7375
|
+
var HeadingButton = ({
|
|
6829
7376
|
editor: providedEditor,
|
|
6830
|
-
|
|
7377
|
+
level,
|
|
7378
|
+
text,
|
|
6831
7379
|
hideWhenUnavailable = false,
|
|
6832
7380
|
className = "",
|
|
7381
|
+
disabled,
|
|
6833
7382
|
onClick,
|
|
6834
|
-
text,
|
|
6835
7383
|
children,
|
|
6836
7384
|
ref,
|
|
6837
7385
|
...buttonProps
|
|
6838
7386
|
}) => {
|
|
6839
|
-
const { editor } =
|
|
6840
|
-
const {
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
7387
|
+
const { editor } = useTiptapEditor19(providedEditor);
|
|
7388
|
+
const {
|
|
7389
|
+
headingInSchema,
|
|
7390
|
+
isDisabled,
|
|
7391
|
+
isActive,
|
|
7392
|
+
Icon,
|
|
7393
|
+
shortcutKey,
|
|
7394
|
+
formattedName
|
|
7395
|
+
} = useHeadingState(editor, level, disabled);
|
|
7396
|
+
const handleClick = React18.useCallback(
|
|
6846
7397
|
(e) => {
|
|
6847
7398
|
onClick == null ? void 0 : onClick(e);
|
|
6848
|
-
if (!e.defaultPrevented && editor) {
|
|
6849
|
-
|
|
7399
|
+
if (!e.defaultPrevented && !isDisabled && editor) {
|
|
7400
|
+
toggleHeading(editor, level);
|
|
6850
7401
|
}
|
|
6851
7402
|
},
|
|
6852
|
-
[onClick, editor,
|
|
7403
|
+
[onClick, isDisabled, editor, level]
|
|
6853
7404
|
);
|
|
6854
|
-
const show =
|
|
6855
|
-
return
|
|
7405
|
+
const show = React18.useMemo(() => {
|
|
7406
|
+
return shouldShowHeadingButton({
|
|
6856
7407
|
editor,
|
|
6857
|
-
|
|
7408
|
+
level,
|
|
6858
7409
|
hideWhenUnavailable,
|
|
6859
|
-
|
|
7410
|
+
headingInSchema
|
|
6860
7411
|
});
|
|
6861
|
-
}, [editor,
|
|
7412
|
+
}, [editor, level, hideWhenUnavailable, headingInSchema]);
|
|
6862
7413
|
if (!show || !editor || !editor.isEditable) {
|
|
6863
7414
|
return null;
|
|
6864
7415
|
}
|
|
6865
|
-
return /* @__PURE__ */
|
|
7416
|
+
return /* @__PURE__ */ jsx29(
|
|
6866
7417
|
Button9,
|
|
6867
7418
|
{
|
|
6868
7419
|
type: "button",
|
|
6869
7420
|
className: className.trim(),
|
|
7421
|
+
disabled: isDisabled,
|
|
6870
7422
|
variant: "ghost",
|
|
6871
7423
|
color: "default",
|
|
6872
7424
|
"data-active-state": isActive ? "on" : "off",
|
|
7425
|
+
"data-disabled": isDisabled,
|
|
6873
7426
|
tabIndex: -1,
|
|
6874
|
-
"aria-label":
|
|
7427
|
+
"aria-label": formattedName,
|
|
6875
7428
|
"aria-pressed": isActive,
|
|
6876
|
-
tooltip:
|
|
7429
|
+
tooltip: formattedName,
|
|
6877
7430
|
shortcutKeys: shortcutKey,
|
|
6878
7431
|
onClick: handleClick,
|
|
6879
|
-
startContent: /* @__PURE__ */
|
|
7432
|
+
startContent: /* @__PURE__ */ jsx29(Icon, {}),
|
|
6880
7433
|
...buttonProps,
|
|
6881
7434
|
ref,
|
|
6882
7435
|
children: children || text
|
|
@@ -6884,161 +7437,196 @@ var ListButton = ({
|
|
|
6884
7437
|
);
|
|
6885
7438
|
};
|
|
6886
7439
|
|
|
6887
|
-
// src/ui/
|
|
6888
|
-
import {
|
|
6889
|
-
|
|
7440
|
+
// src/ui/text-button/text-button.tsx
|
|
7441
|
+
import { Button as Button10 } from "@kopexa/button";
|
|
7442
|
+
import { Chip } from "@kopexa/chip";
|
|
7443
|
+
import { useTiptapEditor as useTiptapEditor21 } from "@kopexa/editor-utils";
|
|
7444
|
+
import { parseShortcutKeys } from "@kopexa/shared-utils";
|
|
7445
|
+
import { useCallback as useCallback34 } from "react";
|
|
7446
|
+
|
|
7447
|
+
// src/ui/text-button/use-text.ts
|
|
7448
|
+
import {
|
|
7449
|
+
findNodePosition as findNodePosition3,
|
|
7450
|
+
getSelectedBlockNodes,
|
|
7451
|
+
isNodeInSchema as isNodeInSchema8,
|
|
7452
|
+
isValidPosition as isValidPosition3,
|
|
7453
|
+
selectionWithinConvertibleTypes,
|
|
7454
|
+
useTiptapEditor as useTiptapEditor20
|
|
7455
|
+
} from "@kopexa/editor-utils";
|
|
7456
|
+
import { TypeIcon as TypeIcon2 } from "@kopexa/icons";
|
|
7457
|
+
import { useIsMobile as useIsMobile2 } from "@kopexa/use-is-mobile";
|
|
7458
|
+
import { NodeSelection as NodeSelection4, TextSelection as TextSelection4 } from "@tiptap/pm/state";
|
|
7459
|
+
import { useCallback as useCallback33, useEffect as useEffect28, useState as useState27 } from "react";
|
|
7460
|
+
import { useHotkeys as useHotkeys2 } from "react-hotkeys-hook";
|
|
7461
|
+
var TEXT_SHORTCUT_KEY = "mod+alt+0";
|
|
7462
|
+
function canToggleText(editor, turnInto = true) {
|
|
6890
7463
|
if (!editor) return false;
|
|
6891
|
-
|
|
7464
|
+
if (!editor.schema.nodes.paragraph) return false;
|
|
7465
|
+
if (!turnInto) {
|
|
7466
|
+
return editor.can().setNode("paragraph");
|
|
7467
|
+
}
|
|
7468
|
+
if (!selectionWithinConvertibleTypes(editor, [
|
|
7469
|
+
"paragraph",
|
|
7470
|
+
"heading",
|
|
7471
|
+
"bulletList",
|
|
7472
|
+
"orderedList",
|
|
7473
|
+
"taskList",
|
|
7474
|
+
"blockquote",
|
|
7475
|
+
"codeBlock"
|
|
7476
|
+
]))
|
|
7477
|
+
return false;
|
|
7478
|
+
return editor.can().setNode("paragraph") || editor.can().clearNodes();
|
|
6892
7479
|
}
|
|
6893
|
-
function
|
|
7480
|
+
function isParagraphActive(editor) {
|
|
6894
7481
|
if (!editor) return false;
|
|
6895
|
-
return
|
|
7482
|
+
return editor.isActive("paragraph");
|
|
6896
7483
|
}
|
|
6897
|
-
function
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
);
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
7484
|
+
function toggleParagraph(editor) {
|
|
7485
|
+
var _a, _b, _c;
|
|
7486
|
+
if (!editor || !editor.isEditable) return false;
|
|
7487
|
+
if (!canToggleText(editor)) return false;
|
|
7488
|
+
try {
|
|
7489
|
+
const view = editor.view;
|
|
7490
|
+
let state = view.state;
|
|
7491
|
+
let tr = state.tr;
|
|
7492
|
+
const blocks = getSelectedBlockNodes(editor);
|
|
7493
|
+
const isPossibleToTurnInto = selectionWithinConvertibleTypes(editor, [
|
|
7494
|
+
"paragraph",
|
|
7495
|
+
"heading",
|
|
7496
|
+
"bulletList",
|
|
7497
|
+
"orderedList",
|
|
7498
|
+
"taskList",
|
|
7499
|
+
"blockquote",
|
|
7500
|
+
"codeBlock"
|
|
7501
|
+
]) && blocks.length === 1;
|
|
7502
|
+
if ((state.selection.empty || state.selection instanceof TextSelection4) && isPossibleToTurnInto) {
|
|
7503
|
+
const pos = (_a = findNodePosition3({
|
|
7504
|
+
editor,
|
|
7505
|
+
node: state.selection.$anchor.node(1)
|
|
7506
|
+
})) == null ? void 0 : _a.pos;
|
|
7507
|
+
if (!isValidPosition3(pos)) return false;
|
|
7508
|
+
tr = tr.setSelection(NodeSelection4.create(state.doc, pos));
|
|
7509
|
+
view.dispatch(tr);
|
|
7510
|
+
state = view.state;
|
|
7511
|
+
}
|
|
7512
|
+
const selection = state.selection;
|
|
7513
|
+
let chain = editor.chain().focus();
|
|
7514
|
+
if (selection instanceof NodeSelection4) {
|
|
7515
|
+
const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
|
|
7516
|
+
const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
|
|
7517
|
+
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
7518
|
+
const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
|
|
7519
|
+
const resolvedFrom = state.doc.resolve(from);
|
|
7520
|
+
const resolvedTo = state.doc.resolve(to);
|
|
7521
|
+
chain = chain.setTextSelection(TextSelection4.between(resolvedFrom, resolvedTo)).clearNodes();
|
|
7522
|
+
}
|
|
7523
|
+
if (!editor.isActive("paragraph")) {
|
|
7524
|
+
chain.setNode("paragraph").run();
|
|
7525
|
+
}
|
|
7526
|
+
editor.chain().focus().selectTextblockEnd().run();
|
|
7527
|
+
return true;
|
|
7528
|
+
} catch {
|
|
6905
7529
|
return false;
|
|
6906
7530
|
}
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
7531
|
+
}
|
|
7532
|
+
function shouldShowButton6(props) {
|
|
7533
|
+
const { editor, hideWhenUnavailable } = props;
|
|
7534
|
+
if (!editor || !editor.isEditable) return false;
|
|
7535
|
+
if (!hideWhenUnavailable) {
|
|
7536
|
+
return true;
|
|
7537
|
+
}
|
|
7538
|
+
if (!isNodeInSchema8("paragraph", editor)) return false;
|
|
7539
|
+
if (!editor.isActive("code")) {
|
|
7540
|
+
return canToggleText(editor);
|
|
6911
7541
|
}
|
|
6912
7542
|
return true;
|
|
6913
7543
|
}
|
|
6914
|
-
function
|
|
6915
|
-
const [isOpen, setIsOpen] = useState26(false);
|
|
6916
|
-
const listInSchema = availableTypes.some(
|
|
6917
|
-
(type) => isNodeInSchema8(type, editor)
|
|
6918
|
-
);
|
|
6919
|
-
const filteredLists = useMemo21(
|
|
6920
|
-
() => getFilteredListOptions(availableTypes),
|
|
6921
|
-
[availableTypes]
|
|
6922
|
-
);
|
|
6923
|
-
const canToggleAny = canToggleAnyList(editor, availableTypes);
|
|
6924
|
-
const isAnyActive = isAnyListActive(editor, availableTypes);
|
|
6925
|
-
const handleOpenChange = useCallback30(
|
|
6926
|
-
(open, callback) => {
|
|
6927
|
-
setIsOpen(open);
|
|
6928
|
-
callback == null ? void 0 : callback(open);
|
|
6929
|
-
},
|
|
6930
|
-
[]
|
|
6931
|
-
);
|
|
6932
|
-
return {
|
|
6933
|
-
isOpen,
|
|
6934
|
-
setIsOpen,
|
|
6935
|
-
listInSchema,
|
|
6936
|
-
filteredLists,
|
|
6937
|
-
canToggleAny,
|
|
6938
|
-
isAnyActive,
|
|
6939
|
-
handleOpenChange
|
|
6940
|
-
};
|
|
6941
|
-
}
|
|
6942
|
-
function useActiveListIcon(editor, filteredLists) {
|
|
6943
|
-
return useCallback30(() => {
|
|
6944
|
-
const activeOption = filteredLists.find(
|
|
6945
|
-
(option) => isListActive(editor, option.type)
|
|
6946
|
-
);
|
|
6947
|
-
return activeOption ? /* @__PURE__ */ jsx28(activeOption.icon, {}) : /* @__PURE__ */ jsx28(ListIcon4, {});
|
|
6948
|
-
}, [editor, filteredLists]);
|
|
6949
|
-
}
|
|
6950
|
-
function ListDropdownMenu({
|
|
6951
|
-
editor: providedEditor,
|
|
6952
|
-
types = ["bulletList", "orderedList", "taskList"],
|
|
6953
|
-
hideWhenUnavailable = false,
|
|
6954
|
-
onOpenChange,
|
|
6955
|
-
...props
|
|
6956
|
-
}) {
|
|
6957
|
-
const { editor } = useTiptapEditor(providedEditor);
|
|
7544
|
+
function useText(config) {
|
|
6958
7545
|
const {
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
const
|
|
6967
|
-
const
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
hideWhenUnavailable
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
)
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
spacing: "start"
|
|
7009
|
-
}
|
|
7010
|
-
) }, option.type)) }) })
|
|
7011
|
-
] });
|
|
7546
|
+
editor: providedEditor,
|
|
7547
|
+
hideWhenUnavailable = false,
|
|
7548
|
+
onToggled
|
|
7549
|
+
} = config || {};
|
|
7550
|
+
const { editor } = useTiptapEditor20(providedEditor);
|
|
7551
|
+
const isMobile = useIsMobile2();
|
|
7552
|
+
const [isVisible, setIsVisible] = useState27(true);
|
|
7553
|
+
const canToggle3 = canToggleText(editor);
|
|
7554
|
+
const isActive = isParagraphActive(editor);
|
|
7555
|
+
useEffect28(() => {
|
|
7556
|
+
if (!editor) return;
|
|
7557
|
+
const handleSelectionUpdate = () => {
|
|
7558
|
+
setIsVisible(shouldShowButton6({ editor, hideWhenUnavailable }));
|
|
7559
|
+
};
|
|
7560
|
+
handleSelectionUpdate();
|
|
7561
|
+
editor.on("selectionUpdate", handleSelectionUpdate);
|
|
7562
|
+
return () => {
|
|
7563
|
+
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
7564
|
+
};
|
|
7565
|
+
}, [editor, hideWhenUnavailable]);
|
|
7566
|
+
const handleToggle = useCallback33(() => {
|
|
7567
|
+
if (!editor) return false;
|
|
7568
|
+
const success = toggleParagraph(editor);
|
|
7569
|
+
if (success) {
|
|
7570
|
+
onToggled == null ? void 0 : onToggled();
|
|
7571
|
+
}
|
|
7572
|
+
return success;
|
|
7573
|
+
}, [editor, onToggled]);
|
|
7574
|
+
useHotkeys2(
|
|
7575
|
+
TEXT_SHORTCUT_KEY,
|
|
7576
|
+
(event) => {
|
|
7577
|
+
event.preventDefault();
|
|
7578
|
+
handleToggle();
|
|
7579
|
+
},
|
|
7580
|
+
{
|
|
7581
|
+
enabled: isVisible && canToggle3,
|
|
7582
|
+
enableOnContentEditable: !isMobile,
|
|
7583
|
+
enableOnFormTags: true
|
|
7584
|
+
}
|
|
7585
|
+
);
|
|
7586
|
+
return {
|
|
7587
|
+
isVisible,
|
|
7588
|
+
isActive,
|
|
7589
|
+
handleToggle,
|
|
7590
|
+
canToggle: canToggle3,
|
|
7591
|
+
label: "Text",
|
|
7592
|
+
shortcutKeys: TEXT_SHORTCUT_KEY,
|
|
7593
|
+
Icon: TypeIcon2
|
|
7594
|
+
};
|
|
7012
7595
|
}
|
|
7013
7596
|
|
|
7014
|
-
// src/ui/
|
|
7015
|
-
import {
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7597
|
+
// src/ui/text-button/text-button.tsx
|
|
7598
|
+
import { Fragment as Fragment8, jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
7599
|
+
function TextShortcutBadge({
|
|
7600
|
+
shortcutKeys = TEXT_SHORTCUT_KEY
|
|
7601
|
+
}) {
|
|
7602
|
+
return /* @__PURE__ */ jsx30(Chip, { children: parseShortcutKeys({ shortcutKeys }) });
|
|
7603
|
+
}
|
|
7604
|
+
var TextButton = ({
|
|
7019
7605
|
editor: providedEditor,
|
|
7020
7606
|
text,
|
|
7021
7607
|
hideWhenUnavailable = false,
|
|
7022
7608
|
onToggled,
|
|
7609
|
+
showShortcut = false,
|
|
7023
7610
|
onClick,
|
|
7024
7611
|
children,
|
|
7612
|
+
ref,
|
|
7025
7613
|
...buttonProps
|
|
7026
7614
|
}) => {
|
|
7027
|
-
const { editor } =
|
|
7615
|
+
const { editor } = useTiptapEditor21(providedEditor);
|
|
7028
7616
|
const {
|
|
7029
7617
|
isVisible,
|
|
7030
7618
|
canToggle: canToggle3,
|
|
7031
7619
|
isActive,
|
|
7032
7620
|
handleToggle,
|
|
7033
7621
|
label,
|
|
7034
|
-
|
|
7622
|
+
shortcutKeys,
|
|
7035
7623
|
Icon
|
|
7036
|
-
} =
|
|
7624
|
+
} = useText({
|
|
7037
7625
|
editor,
|
|
7038
7626
|
hideWhenUnavailable,
|
|
7039
7627
|
onToggled
|
|
7040
7628
|
});
|
|
7041
|
-
const handleClick =
|
|
7629
|
+
const handleClick = useCallback34(
|
|
7042
7630
|
(event) => {
|
|
7043
7631
|
onClick == null ? void 0 : onClick(event);
|
|
7044
7632
|
if (event.defaultPrevented) return;
|
|
@@ -7049,201 +7637,343 @@ var TableButton = ({
|
|
|
7049
7637
|
if (!isVisible) {
|
|
7050
7638
|
return null;
|
|
7051
7639
|
}
|
|
7052
|
-
return /* @__PURE__ */
|
|
7053
|
-
|
|
7640
|
+
return /* @__PURE__ */ jsx30(
|
|
7641
|
+
Button10,
|
|
7054
7642
|
{
|
|
7055
7643
|
type: "button",
|
|
7056
7644
|
variant: "ghost",
|
|
7057
7645
|
color: "default",
|
|
7058
7646
|
"data-active-state": isActive ? "on" : "off",
|
|
7647
|
+
tabIndex: -1,
|
|
7059
7648
|
disabled: !canToggle3,
|
|
7060
7649
|
"data-disabled": !canToggle3,
|
|
7061
|
-
tabIndex: -1,
|
|
7062
7650
|
"aria-label": label,
|
|
7063
7651
|
"aria-pressed": isActive,
|
|
7064
|
-
|
|
7652
|
+
tooltip: "Text",
|
|
7653
|
+
shortcutKeys,
|
|
7065
7654
|
onClick: handleClick,
|
|
7066
|
-
|
|
7655
|
+
startContent: /* @__PURE__ */ jsx30(Icon, {}),
|
|
7067
7656
|
...buttonProps,
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
text
|
|
7657
|
+
ref,
|
|
7658
|
+
children: children != null ? children : /* @__PURE__ */ jsxs22(Fragment8, { children: [
|
|
7659
|
+
text,
|
|
7660
|
+
showShortcut && /* @__PURE__ */ jsx30(TextShortcutBadge, { shortcutKeys })
|
|
7071
7661
|
] })
|
|
7072
7662
|
}
|
|
7073
7663
|
);
|
|
7074
7664
|
};
|
|
7075
7665
|
|
|
7076
|
-
// src/ui/
|
|
7077
|
-
import {
|
|
7078
|
-
import {
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
}
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
}
|
|
7107
|
-
|
|
7666
|
+
// src/ui/turn-into-dropdown/use-turn-into-dropdown.ts
|
|
7667
|
+
import { useTiptapEditor as useTiptapEditor22 } from "@kopexa/editor-utils";
|
|
7668
|
+
import { ChevronDownIcon as ChevronDownIcon2 } from "@kopexa/icons";
|
|
7669
|
+
import { NodeSelection as NodeSelection5 } from "@tiptap/pm/state";
|
|
7670
|
+
import { useCallback as useCallback35, useEffect as useEffect29, useState as useState28 } from "react";
|
|
7671
|
+
var TURN_INTO_BLOCKS = [
|
|
7672
|
+
"paragraph",
|
|
7673
|
+
"heading",
|
|
7674
|
+
"bulletList",
|
|
7675
|
+
"orderedList",
|
|
7676
|
+
"taskList",
|
|
7677
|
+
"blockquote",
|
|
7678
|
+
"codeBlock"
|
|
7679
|
+
];
|
|
7680
|
+
var blockTypeOptions = [
|
|
7681
|
+
{
|
|
7682
|
+
type: "paragraph",
|
|
7683
|
+
label: "Text",
|
|
7684
|
+
isActive: (editor) => editor.isActive("paragraph") && !editor.isActive("heading") && !editor.isActive("bulletList") && !editor.isActive("orderedList") && !editor.isActive("taskList") && !editor.isActive("blockquote") && !editor.isActive("codeBlock")
|
|
7685
|
+
},
|
|
7686
|
+
{
|
|
7687
|
+
type: "heading",
|
|
7688
|
+
label: "Heading 1",
|
|
7689
|
+
level: 1,
|
|
7690
|
+
isActive: (editor) => editor.isActive("heading", { level: 1 })
|
|
7691
|
+
},
|
|
7692
|
+
{
|
|
7693
|
+
type: "heading",
|
|
7694
|
+
label: "Heading 2",
|
|
7695
|
+
level: 2,
|
|
7696
|
+
isActive: (editor) => editor.isActive("heading", { level: 2 })
|
|
7697
|
+
},
|
|
7698
|
+
{
|
|
7699
|
+
type: "heading",
|
|
7700
|
+
label: "Heading 3",
|
|
7701
|
+
level: 3,
|
|
7702
|
+
isActive: (editor) => editor.isActive("heading", { level: 3 })
|
|
7703
|
+
},
|
|
7704
|
+
{
|
|
7705
|
+
type: "heading",
|
|
7706
|
+
label: "Heading 4",
|
|
7707
|
+
level: 4,
|
|
7708
|
+
isActive: (editor) => editor.isActive("heading", { level: 4 })
|
|
7709
|
+
},
|
|
7710
|
+
{
|
|
7711
|
+
type: "bulletList",
|
|
7712
|
+
label: "Bulleted list",
|
|
7713
|
+
isActive: (editor) => editor.isActive("bulletList")
|
|
7714
|
+
},
|
|
7715
|
+
{
|
|
7716
|
+
type: "orderedList",
|
|
7717
|
+
label: "Numbered list",
|
|
7718
|
+
isActive: (editor) => editor.isActive("orderedList")
|
|
7719
|
+
},
|
|
7720
|
+
{
|
|
7721
|
+
type: "taskList",
|
|
7722
|
+
label: "To-do list",
|
|
7723
|
+
isActive: (editor) => editor.isActive("taskList")
|
|
7724
|
+
},
|
|
7725
|
+
{
|
|
7726
|
+
type: "blockquote",
|
|
7727
|
+
label: "Blockquote",
|
|
7728
|
+
isActive: (editor) => editor.isActive("blockquote")
|
|
7729
|
+
},
|
|
7730
|
+
{
|
|
7731
|
+
type: "codeBlock",
|
|
7732
|
+
label: "Code block",
|
|
7733
|
+
isActive: (editor) => editor.isActive("codeBlock")
|
|
7734
|
+
}
|
|
7735
|
+
];
|
|
7736
|
+
function canTurnInto(editor, allowedBlockTypes) {
|
|
7108
7737
|
if (!editor || !editor.isEditable) return false;
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
|
|
7114
|
-
|
|
7738
|
+
const blockTypes = allowedBlockTypes || TURN_INTO_BLOCKS;
|
|
7739
|
+
const { selection } = editor.state;
|
|
7740
|
+
if (selection instanceof NodeSelection5) {
|
|
7741
|
+
const nodeType2 = selection.node.type.name;
|
|
7742
|
+
return blockTypes.includes(nodeType2);
|
|
7743
|
+
}
|
|
7744
|
+
const { $anchor } = selection;
|
|
7745
|
+
const nodeType = $anchor.parent.type.name;
|
|
7746
|
+
return blockTypes.includes(nodeType);
|
|
7115
7747
|
}
|
|
7116
|
-
function
|
|
7117
|
-
if (!
|
|
7118
|
-
return
|
|
7748
|
+
function getFilteredBlockTypeOptions(blockTypes) {
|
|
7749
|
+
if (!blockTypes) return blockTypeOptions;
|
|
7750
|
+
return blockTypeOptions.filter((option) => {
|
|
7751
|
+
return blockTypes.includes(option.type);
|
|
7752
|
+
});
|
|
7119
7753
|
}
|
|
7120
|
-
function
|
|
7121
|
-
if (!editor
|
|
7122
|
-
|
|
7123
|
-
const
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
return false;
|
|
7754
|
+
function getActiveBlockType(editor, blockTypes) {
|
|
7755
|
+
if (!editor) return getFilteredBlockTypeOptions(blockTypes)[0];
|
|
7756
|
+
const filteredOptions = getFilteredBlockTypeOptions(blockTypes);
|
|
7757
|
+
const activeOption = filteredOptions.find(
|
|
7758
|
+
(option) => option.isActive(editor)
|
|
7759
|
+
);
|
|
7760
|
+
return activeOption || filteredOptions[0];
|
|
7128
7761
|
}
|
|
7129
|
-
function
|
|
7130
|
-
const { editor, hideWhenUnavailable,
|
|
7762
|
+
function shouldShowTurnInto(params) {
|
|
7763
|
+
const { editor, hideWhenUnavailable, blockTypes } = params;
|
|
7131
7764
|
if (!editor || !editor.isEditable) return false;
|
|
7132
|
-
if (!isExtensionAvailable2(editor, "textAlign")) return false;
|
|
7133
7765
|
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
7134
|
-
return
|
|
7766
|
+
return canTurnInto(editor, blockTypes);
|
|
7135
7767
|
}
|
|
7136
7768
|
return true;
|
|
7137
7769
|
}
|
|
7138
|
-
function
|
|
7770
|
+
function useTurnIntoDropdown(config) {
|
|
7139
7771
|
const {
|
|
7140
7772
|
editor: providedEditor,
|
|
7141
|
-
align,
|
|
7142
7773
|
hideWhenUnavailable = false,
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
const
|
|
7147
|
-
const
|
|
7148
|
-
const
|
|
7149
|
-
|
|
7774
|
+
blockTypes,
|
|
7775
|
+
onOpenChange
|
|
7776
|
+
} = config || {};
|
|
7777
|
+
const { editor } = useTiptapEditor22(providedEditor);
|
|
7778
|
+
const [isOpen, setIsOpen] = useState28(false);
|
|
7779
|
+
const [isVisible, setIsVisible] = useState28(true);
|
|
7780
|
+
const canToggle3 = canTurnInto(editor, blockTypes);
|
|
7781
|
+
const activeBlockType = getActiveBlockType(editor, blockTypes);
|
|
7782
|
+
const handleOpenChange = useCallback35(
|
|
7783
|
+
(open) => {
|
|
7784
|
+
if (!editor || !canToggle3) return;
|
|
7785
|
+
setIsOpen(open);
|
|
7786
|
+
onOpenChange == null ? void 0 : onOpenChange(open);
|
|
7787
|
+
},
|
|
7788
|
+
[canToggle3, editor, onOpenChange]
|
|
7789
|
+
);
|
|
7790
|
+
useEffect29(() => {
|
|
7150
7791
|
if (!editor) return;
|
|
7151
7792
|
const handleSelectionUpdate = () => {
|
|
7152
|
-
setIsVisible(
|
|
7793
|
+
setIsVisible(
|
|
7794
|
+
shouldShowTurnInto({
|
|
7795
|
+
editor,
|
|
7796
|
+
hideWhenUnavailable,
|
|
7797
|
+
blockTypes
|
|
7798
|
+
})
|
|
7799
|
+
);
|
|
7153
7800
|
};
|
|
7154
7801
|
handleSelectionUpdate();
|
|
7155
7802
|
editor.on("selectionUpdate", handleSelectionUpdate);
|
|
7156
7803
|
return () => {
|
|
7157
7804
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
7158
7805
|
};
|
|
7159
|
-
}, [editor, hideWhenUnavailable,
|
|
7160
|
-
const handleTextAlign = useCallback32(() => {
|
|
7161
|
-
if (!editor) return false;
|
|
7162
|
-
const success = setTextAlign(editor, align);
|
|
7163
|
-
if (success) {
|
|
7164
|
-
onAligned == null ? void 0 : onAligned();
|
|
7165
|
-
}
|
|
7166
|
-
return success;
|
|
7167
|
-
}, [editor, align, onAligned]);
|
|
7806
|
+
}, [editor, hideWhenUnavailable, blockTypes]);
|
|
7168
7807
|
return {
|
|
7169
7808
|
isVisible,
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7809
|
+
canToggle: canToggle3,
|
|
7810
|
+
isOpen,
|
|
7811
|
+
setIsOpen,
|
|
7812
|
+
activeBlockType,
|
|
7813
|
+
handleOpenChange,
|
|
7814
|
+
filteredOptions: getFilteredBlockTypeOptions(blockTypes),
|
|
7815
|
+
label: `Turn into (current: ${(activeBlockType == null ? void 0 : activeBlockType.label) || "Text"})`,
|
|
7816
|
+
Icon: ChevronDownIcon2
|
|
7176
7817
|
};
|
|
7177
7818
|
}
|
|
7178
7819
|
|
|
7179
|
-
// src/ui/
|
|
7180
|
-
import { jsx as
|
|
7181
|
-
var
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
...buttonProps
|
|
7191
|
-
}) => {
|
|
7192
|
-
const { editor } = useTiptapEditor(providedEditor);
|
|
7193
|
-
const {
|
|
7194
|
-
isVisible,
|
|
7195
|
-
handleTextAlign,
|
|
7196
|
-
label,
|
|
7197
|
-
canAlign,
|
|
7198
|
-
isActive,
|
|
7199
|
-
Icon,
|
|
7200
|
-
shortcutKeys
|
|
7201
|
-
} = useTextAlign({
|
|
7202
|
-
editor,
|
|
7203
|
-
align,
|
|
7204
|
-
hideWhenUnavailable,
|
|
7205
|
-
onAligned
|
|
7206
|
-
});
|
|
7207
|
-
const handleClick = useCallback33(
|
|
7208
|
-
(e) => {
|
|
7209
|
-
onClick == null ? void 0 : onClick(e);
|
|
7210
|
-
if (e.defaultPrevented) return;
|
|
7211
|
-
handleTextAlign();
|
|
7212
|
-
},
|
|
7213
|
-
[handleTextAlign, onClick]
|
|
7214
|
-
);
|
|
7215
|
-
if (!isVisible) {
|
|
7216
|
-
return null;
|
|
7217
|
-
}
|
|
7218
|
-
return /* @__PURE__ */ jsx30(
|
|
7219
|
-
IconButton9,
|
|
7220
|
-
{
|
|
7221
|
-
type: "button",
|
|
7222
|
-
disabled: canAlign,
|
|
7223
|
-
variant: "ghost",
|
|
7224
|
-
color: "default",
|
|
7225
|
-
"data-active-state": isActive ? "on" : "off",
|
|
7226
|
-
"data-disabled": canAlign,
|
|
7227
|
-
tabIndex: -1,
|
|
7228
|
-
"aria-label": label,
|
|
7229
|
-
"aria-pressed": isActive,
|
|
7230
|
-
tooltip: label,
|
|
7231
|
-
shortcutKeys,
|
|
7232
|
-
onClick: handleClick,
|
|
7233
|
-
...buttonProps,
|
|
7234
|
-
children: /* @__PURE__ */ jsx30(Icon, {})
|
|
7820
|
+
// src/ui/turn-into-dropdown/turn-into-dropdown.tsx
|
|
7821
|
+
import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
7822
|
+
var TurnIntoDropdownContent = ({ blockTypes }) => {
|
|
7823
|
+
const filteredOptions = getFilteredBlockTypeOptions(blockTypes);
|
|
7824
|
+
return /* @__PURE__ */ jsx31(DropdownMenu2.Group, { children: filteredOptions.map(
|
|
7825
|
+
(option, index) => {
|
|
7826
|
+
var _a;
|
|
7827
|
+
return renderBlockTypeButton(
|
|
7828
|
+
option,
|
|
7829
|
+
`${option.type}-${(_a = option.level) != null ? _a : index}`
|
|
7830
|
+
);
|
|
7235
7831
|
}
|
|
7236
|
-
);
|
|
7832
|
+
) });
|
|
7237
7833
|
};
|
|
7834
|
+
function renderBlockTypeButton(option, key) {
|
|
7835
|
+
switch (option.type) {
|
|
7836
|
+
case "paragraph":
|
|
7837
|
+
return /* @__PURE__ */ jsx31(DropdownMenu2.Item, { asChild: true, children: /* @__PURE__ */ jsx31(
|
|
7838
|
+
TextButton,
|
|
7839
|
+
{
|
|
7840
|
+
fullWidth: true,
|
|
7841
|
+
spacing: "start",
|
|
7842
|
+
tooltip: "",
|
|
7843
|
+
text: option.label
|
|
7844
|
+
}
|
|
7845
|
+
) }, key);
|
|
7846
|
+
case "heading":
|
|
7847
|
+
if (!option.level) {
|
|
7848
|
+
return null;
|
|
7849
|
+
}
|
|
7850
|
+
return /* @__PURE__ */ jsx31(DropdownMenu2.Item, { asChild: true, children: /* @__PURE__ */ jsx31(
|
|
7851
|
+
HeadingButton,
|
|
7852
|
+
{
|
|
7853
|
+
level: option.level || 1,
|
|
7854
|
+
fullWidth: true,
|
|
7855
|
+
spacing: "start",
|
|
7856
|
+
tooltip: "",
|
|
7857
|
+
text: option.label
|
|
7858
|
+
}
|
|
7859
|
+
) }, key);
|
|
7860
|
+
case "bulletList":
|
|
7861
|
+
return /* @__PURE__ */ jsx31(DropdownMenu2.Item, { asChild: true, children: /* @__PURE__ */ jsx31(
|
|
7862
|
+
ListButton,
|
|
7863
|
+
{
|
|
7864
|
+
type: "bulletList",
|
|
7865
|
+
fullWidth: true,
|
|
7866
|
+
spacing: "start",
|
|
7867
|
+
tooltip: "",
|
|
7868
|
+
text: option.label
|
|
7869
|
+
}
|
|
7870
|
+
) }, key);
|
|
7871
|
+
case "orderedList":
|
|
7872
|
+
return /* @__PURE__ */ jsx31(DropdownMenu2.Item, { asChild: true, children: /* @__PURE__ */ jsx31(
|
|
7873
|
+
ListButton,
|
|
7874
|
+
{
|
|
7875
|
+
type: "orderedList",
|
|
7876
|
+
fullWidth: true,
|
|
7877
|
+
spacing: "start",
|
|
7878
|
+
tooltip: "",
|
|
7879
|
+
text: option.label
|
|
7880
|
+
}
|
|
7881
|
+
) }, key);
|
|
7882
|
+
case "taskList":
|
|
7883
|
+
return /* @__PURE__ */ jsx31(DropdownMenu2.Item, { asChild: true, children: /* @__PURE__ */ jsx31(
|
|
7884
|
+
ListButton,
|
|
7885
|
+
{
|
|
7886
|
+
type: "taskList",
|
|
7887
|
+
fullWidth: true,
|
|
7888
|
+
spacing: "start",
|
|
7889
|
+
tooltip: "",
|
|
7890
|
+
text: option.label
|
|
7891
|
+
}
|
|
7892
|
+
) }, key);
|
|
7893
|
+
case "blockquote":
|
|
7894
|
+
return /* @__PURE__ */ jsx31(DropdownMenu2.Item, { asChild: true, children: /* @__PURE__ */ jsx31(
|
|
7895
|
+
BlockquoteButton,
|
|
7896
|
+
{
|
|
7897
|
+
className: "w-full justify-start",
|
|
7898
|
+
title: "",
|
|
7899
|
+
tooltip: "",
|
|
7900
|
+
text: option.label
|
|
7901
|
+
}
|
|
7902
|
+
) }, key);
|
|
7903
|
+
case "codeBlock":
|
|
7904
|
+
return /* @__PURE__ */ jsx31(DropdownMenu2.Item, { asChild: true, children: /* @__PURE__ */ jsx31(
|
|
7905
|
+
CodeBlockButton,
|
|
7906
|
+
{
|
|
7907
|
+
className: "w-full justify-start",
|
|
7908
|
+
title: "",
|
|
7909
|
+
tooltip: "",
|
|
7910
|
+
text: option.label
|
|
7911
|
+
}
|
|
7912
|
+
) }, key);
|
|
7913
|
+
default:
|
|
7914
|
+
return null;
|
|
7915
|
+
}
|
|
7916
|
+
}
|
|
7917
|
+
var TurnIntoDropdown = forwardRef(
|
|
7918
|
+
({
|
|
7919
|
+
editor: providedEditor,
|
|
7920
|
+
hideWhenUnavailable = false,
|
|
7921
|
+
blockTypes,
|
|
7922
|
+
onOpenChange,
|
|
7923
|
+
children,
|
|
7924
|
+
...buttonProps
|
|
7925
|
+
}, ref) => {
|
|
7926
|
+
const { editor } = useTiptapEditor23(providedEditor);
|
|
7927
|
+
const {
|
|
7928
|
+
isVisible,
|
|
7929
|
+
canToggle: canToggle3,
|
|
7930
|
+
isOpen,
|
|
7931
|
+
activeBlockType,
|
|
7932
|
+
handleOpenChange,
|
|
7933
|
+
label,
|
|
7934
|
+
Icon
|
|
7935
|
+
} = useTurnIntoDropdown({
|
|
7936
|
+
editor,
|
|
7937
|
+
hideWhenUnavailable,
|
|
7938
|
+
blockTypes,
|
|
7939
|
+
onOpenChange
|
|
7940
|
+
});
|
|
7941
|
+
if (!isVisible) {
|
|
7942
|
+
return null;
|
|
7943
|
+
}
|
|
7944
|
+
return /* @__PURE__ */ jsxs23(DropdownMenu2.Root, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
7945
|
+
/* @__PURE__ */ jsx31(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx31(
|
|
7946
|
+
Button11,
|
|
7947
|
+
{
|
|
7948
|
+
type: "button",
|
|
7949
|
+
variant: "ghost",
|
|
7950
|
+
color: "default",
|
|
7951
|
+
disabled: !canToggle3,
|
|
7952
|
+
"data-disabled": !canToggle3,
|
|
7953
|
+
tabIndex: -1,
|
|
7954
|
+
"aria-label": label,
|
|
7955
|
+
tooltip: "Turn into",
|
|
7956
|
+
endContent: /* @__PURE__ */ jsx31(Icon, {}),
|
|
7957
|
+
...buttonProps,
|
|
7958
|
+
ref,
|
|
7959
|
+
children: children != null ? children : /* @__PURE__ */ jsx31("span", { children: (activeBlockType == null ? void 0 : activeBlockType.label) || "Text" })
|
|
7960
|
+
}
|
|
7961
|
+
) }),
|
|
7962
|
+
/* @__PURE__ */ jsx31(DropdownMenu2.Content, { align: "start", children: /* @__PURE__ */ jsx31(TurnIntoDropdownContent, { blockTypes }) })
|
|
7963
|
+
] });
|
|
7964
|
+
}
|
|
7965
|
+
);
|
|
7966
|
+
TurnIntoDropdown.displayName = "TurnIntoDropdown";
|
|
7238
7967
|
|
|
7239
7968
|
// src/ui/undo-redo-button/undo-redo-button.tsx
|
|
7969
|
+
import { useTiptapEditor as useTiptapEditor25 } from "@kopexa/editor-utils";
|
|
7240
7970
|
import { ToolbarButton as ToolbarButton7 } from "@kopexa/toolbar";
|
|
7241
|
-
import { useCallback as
|
|
7971
|
+
import { useCallback as useCallback37 } from "react";
|
|
7242
7972
|
|
|
7243
7973
|
// src/ui/undo-redo-button/use-undo-redo.ts
|
|
7244
|
-
import { isNodeTypeSelected as isNodeTypeSelected7 } from "@kopexa/editor-utils";
|
|
7974
|
+
import { isNodeTypeSelected as isNodeTypeSelected7, useTiptapEditor as useTiptapEditor24 } from "@kopexa/editor-utils";
|
|
7245
7975
|
import { RedoIcon, UndoIcon } from "@kopexa/icons";
|
|
7246
|
-
import { useCallback as
|
|
7976
|
+
import { useCallback as useCallback36, useEffect as useEffect30, useState as useState29 } from "react";
|
|
7247
7977
|
var UNDO_REDO_SHORTCUT_KEYS = {
|
|
7248
7978
|
undo: "mod+z",
|
|
7249
7979
|
redo: "mod+shift+z"
|
|
@@ -7267,7 +7997,7 @@ function executeUndoRedoAction(editor, action) {
|
|
|
7267
7997
|
const chain = editor.chain().focus();
|
|
7268
7998
|
return action === "undo" ? chain.undo().run() : chain.redo().run();
|
|
7269
7999
|
}
|
|
7270
|
-
function
|
|
8000
|
+
function shouldShowButton7(props) {
|
|
7271
8001
|
const { editor, hideWhenUnavailable, action } = props;
|
|
7272
8002
|
if (!editor || !editor.isEditable) return false;
|
|
7273
8003
|
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
@@ -7282,13 +8012,13 @@ function useUndoRedo(config) {
|
|
|
7282
8012
|
hideWhenUnavailable = false,
|
|
7283
8013
|
onExecuted
|
|
7284
8014
|
} = config;
|
|
7285
|
-
const { editor } =
|
|
7286
|
-
const [isVisible, setIsVisible] =
|
|
8015
|
+
const { editor } = useTiptapEditor24(providedEditor);
|
|
8016
|
+
const [isVisible, setIsVisible] = useState29(true);
|
|
7287
8017
|
const canExecute = canExecuteUndoRedoAction(editor, action);
|
|
7288
|
-
|
|
8018
|
+
useEffect30(() => {
|
|
7289
8019
|
if (!editor) return;
|
|
7290
8020
|
const handleUpdate = () => {
|
|
7291
|
-
setIsVisible(
|
|
8021
|
+
setIsVisible(shouldShowButton7({ editor, hideWhenUnavailable, action }));
|
|
7292
8022
|
};
|
|
7293
8023
|
handleUpdate();
|
|
7294
8024
|
editor.on("transaction", handleUpdate);
|
|
@@ -7296,7 +8026,7 @@ function useUndoRedo(config) {
|
|
|
7296
8026
|
editor.off("transaction", handleUpdate);
|
|
7297
8027
|
};
|
|
7298
8028
|
}, [editor, hideWhenUnavailable, action]);
|
|
7299
|
-
const handleAction =
|
|
8029
|
+
const handleAction = useCallback36(() => {
|
|
7300
8030
|
if (!editor) return false;
|
|
7301
8031
|
const success = executeUndoRedoAction(editor, action);
|
|
7302
8032
|
if (success) {
|
|
@@ -7315,7 +8045,7 @@ function useUndoRedo(config) {
|
|
|
7315
8045
|
}
|
|
7316
8046
|
|
|
7317
8047
|
// src/ui/undo-redo-button/undo-redo-button.tsx
|
|
7318
|
-
import { jsx as
|
|
8048
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
7319
8049
|
var UndoRedoButton = ({
|
|
7320
8050
|
editor: providedEditor,
|
|
7321
8051
|
action,
|
|
@@ -7327,14 +8057,14 @@ var UndoRedoButton = ({
|
|
|
7327
8057
|
children,
|
|
7328
8058
|
...buttonProps
|
|
7329
8059
|
}) => {
|
|
7330
|
-
const { editor } =
|
|
8060
|
+
const { editor } = useTiptapEditor25(providedEditor);
|
|
7331
8061
|
const { isVisible, handleAction, label, canExecute, Icon, shortcutKeys } = useUndoRedo({
|
|
7332
8062
|
editor,
|
|
7333
8063
|
action,
|
|
7334
8064
|
hideWhenUnavailable,
|
|
7335
8065
|
onExecuted
|
|
7336
8066
|
});
|
|
7337
|
-
const handleClick =
|
|
8067
|
+
const handleClick = useCallback37(
|
|
7338
8068
|
(event) => {
|
|
7339
8069
|
onClick == null ? void 0 : onClick(event);
|
|
7340
8070
|
if (event.defaultPrevented) return;
|
|
@@ -7345,7 +8075,7 @@ var UndoRedoButton = ({
|
|
|
7345
8075
|
if (!isVisible) {
|
|
7346
8076
|
return null;
|
|
7347
8077
|
}
|
|
7348
|
-
return /* @__PURE__ */
|
|
8078
|
+
return /* @__PURE__ */ jsx32(
|
|
7349
8079
|
ToolbarButton7,
|
|
7350
8080
|
{
|
|
7351
8081
|
type: "button",
|
|
@@ -7360,20 +8090,20 @@ var UndoRedoButton = ({
|
|
|
7360
8090
|
onClick: handleClick,
|
|
7361
8091
|
isIconOnly: true,
|
|
7362
8092
|
...buttonProps,
|
|
7363
|
-
children: /* @__PURE__ */
|
|
8093
|
+
children: /* @__PURE__ */ jsx32(Icon, {})
|
|
7364
8094
|
}
|
|
7365
8095
|
);
|
|
7366
8096
|
};
|
|
7367
8097
|
|
|
7368
8098
|
// src/presets/basic/editor-header.tsx
|
|
7369
|
-
import { Fragment as
|
|
8099
|
+
import { Fragment as Fragment9, jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
7370
8100
|
var EditorHeader = ({
|
|
7371
8101
|
editor: providedEditor,
|
|
7372
8102
|
variant
|
|
7373
8103
|
}) => {
|
|
7374
8104
|
var _a, _b;
|
|
7375
|
-
const { editor } =
|
|
7376
|
-
const isMobile =
|
|
8105
|
+
const { editor } = useTiptapEditor26(providedEditor);
|
|
8106
|
+
const isMobile = useIsMobile3();
|
|
7377
8107
|
const windowSize = useWindowSize();
|
|
7378
8108
|
const { styles } = useEditorUIContext();
|
|
7379
8109
|
const toolbarRef = useRef11(null);
|
|
@@ -7385,7 +8115,7 @@ var EditorHeader = ({
|
|
|
7385
8115
|
return null;
|
|
7386
8116
|
}
|
|
7387
8117
|
const ToolbarContent = variant === "comment" ? CommentToolbarContent : variant === "field" ? FieldToolbarContent : MainToolbarContent;
|
|
7388
|
-
return /* @__PURE__ */
|
|
8118
|
+
return /* @__PURE__ */ jsx33("div", { className: styles.toolbarContainer(), "data-slot": "editor-toolbar", children: /* @__PURE__ */ jsx33(
|
|
7389
8119
|
Toolbar2,
|
|
7390
8120
|
{
|
|
7391
8121
|
sticky: true,
|
|
@@ -7395,63 +8125,58 @@ var EditorHeader = ({
|
|
|
7395
8125
|
bottom: `calc(100% - ${windowSize.height - bodyRect.y}px)`
|
|
7396
8126
|
} : {},
|
|
7397
8127
|
className: styles.toolbar(),
|
|
7398
|
-
children: /* @__PURE__ */
|
|
8128
|
+
children: /* @__PURE__ */ jsx33(ToolbarContent, {})
|
|
7399
8129
|
}
|
|
7400
8130
|
) });
|
|
7401
8131
|
};
|
|
7402
|
-
var MainToolbarContent = () => /* @__PURE__ */
|
|
7403
|
-
/* @__PURE__ */
|
|
7404
|
-
/* @__PURE__ */
|
|
7405
|
-
/* @__PURE__ */
|
|
8132
|
+
var MainToolbarContent = () => /* @__PURE__ */ jsxs24(Fragment9, { children: [
|
|
8133
|
+
/* @__PURE__ */ jsxs24(ToolbarGroup2, { children: [
|
|
8134
|
+
/* @__PURE__ */ jsx33(UndoRedoButton, { action: "undo" }),
|
|
8135
|
+
/* @__PURE__ */ jsx33(UndoRedoButton, { action: "redo" })
|
|
7406
8136
|
] }),
|
|
7407
|
-
/* @__PURE__ */
|
|
7408
|
-
/* @__PURE__ */
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
/* @__PURE__ */
|
|
7412
|
-
/* @__PURE__ */
|
|
8137
|
+
/* @__PURE__ */ jsx33(ToolbarSeparator3, {}),
|
|
8138
|
+
/* @__PURE__ */ jsx33(ToolbarGroup2, { children: /* @__PURE__ */ jsx33(TurnIntoDropdown, {}) }),
|
|
8139
|
+
/* @__PURE__ */ jsx33(ToolbarSeparator3, {}),
|
|
8140
|
+
/* @__PURE__ */ jsxs24(ToolbarGroup2, { children: [
|
|
8141
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "bold" }),
|
|
8142
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "italic" }),
|
|
8143
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "strike" }),
|
|
8144
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "code" }),
|
|
8145
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "underline" }),
|
|
8146
|
+
/* @__PURE__ */ jsx33(ColorHighlightPopover, {}),
|
|
8147
|
+
/* @__PURE__ */ jsx33(LinkPopover, {})
|
|
7413
8148
|
] }),
|
|
7414
|
-
/* @__PURE__ */
|
|
7415
|
-
/* @__PURE__ */
|
|
7416
|
-
|
|
7417
|
-
/* @__PURE__ */ jsx32(MarkButton, { type: "italic" }),
|
|
7418
|
-
/* @__PURE__ */ jsx32(MarkButton, { type: "strike" }),
|
|
7419
|
-
/* @__PURE__ */ jsx32(MarkButton, { type: "code" }),
|
|
7420
|
-
/* @__PURE__ */ jsx32(MarkButton, { type: "underline" }),
|
|
7421
|
-
/* @__PURE__ */ jsx32(ColorHighlightPopover, {}),
|
|
7422
|
-
/* @__PURE__ */ jsx32(LinkPopover, {})
|
|
7423
|
-
] }),
|
|
7424
|
-
/* @__PURE__ */ jsx32(ToolbarSeparator3, {}),
|
|
7425
|
-
/* @__PURE__ */ jsx32(ToolbarGroup2, { children: /* @__PURE__ */ jsx32(TableButton, {}) }),
|
|
7426
|
-
/* @__PURE__ */ jsx32(MoreOptions, { hideWhenUnavailable: true })
|
|
8149
|
+
/* @__PURE__ */ jsx33(ToolbarSeparator3, {}),
|
|
8150
|
+
/* @__PURE__ */ jsx33(ToolbarGroup2, { children: /* @__PURE__ */ jsx33(TableButton, {}) }),
|
|
8151
|
+
/* @__PURE__ */ jsx33(MoreOptions, { hideWhenUnavailable: true })
|
|
7427
8152
|
] });
|
|
7428
|
-
var CommentToolbarContent = () => /* @__PURE__ */
|
|
7429
|
-
/* @__PURE__ */
|
|
7430
|
-
/* @__PURE__ */
|
|
7431
|
-
/* @__PURE__ */
|
|
7432
|
-
/* @__PURE__ */
|
|
7433
|
-
/* @__PURE__ */
|
|
8153
|
+
var CommentToolbarContent = () => /* @__PURE__ */ jsxs24(Fragment9, { children: [
|
|
8154
|
+
/* @__PURE__ */ jsxs24(ToolbarGroup2, { children: [
|
|
8155
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "bold" }),
|
|
8156
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "italic" }),
|
|
8157
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "strike" }),
|
|
8158
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "code" })
|
|
7434
8159
|
] }),
|
|
7435
|
-
/* @__PURE__ */
|
|
7436
|
-
/* @__PURE__ */
|
|
7437
|
-
/* @__PURE__ */
|
|
7438
|
-
/* @__PURE__ */
|
|
8160
|
+
/* @__PURE__ */ jsx33(ToolbarSeparator3, {}),
|
|
8161
|
+
/* @__PURE__ */ jsxs24(ToolbarGroup2, { children: [
|
|
8162
|
+
/* @__PURE__ */ jsx33(LinkPopover, {}),
|
|
8163
|
+
/* @__PURE__ */ jsx33(ListDropdownMenu, { types: ["bulletList", "orderedList"] })
|
|
7439
8164
|
] })
|
|
7440
8165
|
] });
|
|
7441
|
-
var FieldToolbarContent = () => /* @__PURE__ */
|
|
7442
|
-
/* @__PURE__ */
|
|
7443
|
-
/* @__PURE__ */
|
|
7444
|
-
/* @__PURE__ */
|
|
7445
|
-
/* @__PURE__ */
|
|
8166
|
+
var FieldToolbarContent = () => /* @__PURE__ */ jsxs24(ToolbarGroup2, { children: [
|
|
8167
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "bold" }),
|
|
8168
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "italic" }),
|
|
8169
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "strike" }),
|
|
8170
|
+
/* @__PURE__ */ jsx33(LinkPopover, {})
|
|
7446
8171
|
] });
|
|
7447
8172
|
function MoreOptions({
|
|
7448
8173
|
editor: providedEditor,
|
|
7449
8174
|
hideWhenUnavailable = false,
|
|
7450
8175
|
...props
|
|
7451
8176
|
}) {
|
|
7452
|
-
const { editor } =
|
|
7453
|
-
const [show, setShow] =
|
|
7454
|
-
|
|
8177
|
+
const { editor } = useTiptapEditor26(providedEditor);
|
|
8178
|
+
const [show, setShow] = useState30(false);
|
|
8179
|
+
useEffect31(() => {
|
|
7455
8180
|
if (!editor) return;
|
|
7456
8181
|
const handleSelectionUpdate = () => {
|
|
7457
8182
|
setShow(
|
|
@@ -7470,13 +8195,13 @@ function MoreOptions({
|
|
|
7470
8195
|
if (!show || !editor || !editor.isEditable) {
|
|
7471
8196
|
return null;
|
|
7472
8197
|
}
|
|
7473
|
-
return /* @__PURE__ */
|
|
7474
|
-
/* @__PURE__ */
|
|
7475
|
-
/* @__PURE__ */
|
|
7476
|
-
/* @__PURE__ */
|
|
8198
|
+
return /* @__PURE__ */ jsxs24(Fragment9, { children: [
|
|
8199
|
+
/* @__PURE__ */ jsx33(ToolbarSeparator3, {}),
|
|
8200
|
+
/* @__PURE__ */ jsx33(ToolbarGroup2, { children: /* @__PURE__ */ jsxs24(Popover3.Root, { spacing: "dense", width: "auto", children: [
|
|
8201
|
+
/* @__PURE__ */ jsx33(
|
|
7477
8202
|
Popover3.Trigger,
|
|
7478
8203
|
{
|
|
7479
|
-
render: /* @__PURE__ */
|
|
8204
|
+
render: /* @__PURE__ */ jsx33(
|
|
7480
8205
|
ToolbarButton8,
|
|
7481
8206
|
{
|
|
7482
8207
|
type: "button",
|
|
@@ -7488,29 +8213,29 @@ function MoreOptions({
|
|
|
7488
8213
|
title: "More options",
|
|
7489
8214
|
isIconOnly: true,
|
|
7490
8215
|
...props,
|
|
7491
|
-
children: /* @__PURE__ */
|
|
8216
|
+
children: /* @__PURE__ */ jsx33(MoreVerticalIcon, {})
|
|
7492
8217
|
}
|
|
7493
8218
|
)
|
|
7494
8219
|
}
|
|
7495
8220
|
),
|
|
7496
|
-
/* @__PURE__ */
|
|
8221
|
+
/* @__PURE__ */ jsx33(
|
|
7497
8222
|
Popover3.Content,
|
|
7498
8223
|
{
|
|
7499
8224
|
side: "top",
|
|
7500
8225
|
align: "end",
|
|
7501
8226
|
alignOffset: 4,
|
|
7502
8227
|
sideOffset: 4,
|
|
7503
|
-
children: /* @__PURE__ */
|
|
7504
|
-
/* @__PURE__ */
|
|
7505
|
-
/* @__PURE__ */
|
|
7506
|
-
/* @__PURE__ */
|
|
8228
|
+
children: /* @__PURE__ */ jsxs24(Toolbar2, { children: [
|
|
8229
|
+
/* @__PURE__ */ jsxs24(ToolbarGroup2, { children: [
|
|
8230
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "superscript" }),
|
|
8231
|
+
/* @__PURE__ */ jsx33(MarkButton, { type: "subscript" })
|
|
7507
8232
|
] }),
|
|
7508
|
-
/* @__PURE__ */
|
|
7509
|
-
/* @__PURE__ */
|
|
7510
|
-
/* @__PURE__ */
|
|
7511
|
-
/* @__PURE__ */
|
|
7512
|
-
/* @__PURE__ */
|
|
7513
|
-
/* @__PURE__ */
|
|
8233
|
+
/* @__PURE__ */ jsx33(ToolbarSeparator3, {}),
|
|
8234
|
+
/* @__PURE__ */ jsxs24(ToolbarGroup2, { children: [
|
|
8235
|
+
/* @__PURE__ */ jsx33(TextAlignButton, { align: "left" }),
|
|
8236
|
+
/* @__PURE__ */ jsx33(TextAlignButton, { align: "center" }),
|
|
8237
|
+
/* @__PURE__ */ jsx33(TextAlignButton, { align: "right" }),
|
|
8238
|
+
/* @__PURE__ */ jsx33(TextAlignButton, { align: "justify" })
|
|
7514
8239
|
] })
|
|
7515
8240
|
] })
|
|
7516
8241
|
}
|
|
@@ -7542,7 +8267,7 @@ function shouldShowMoreOptions(params) {
|
|
|
7542
8267
|
}
|
|
7543
8268
|
|
|
7544
8269
|
// src/presets/basic/index.tsx
|
|
7545
|
-
import { jsx as
|
|
8270
|
+
import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
7546
8271
|
var BasicEditor = ({
|
|
7547
8272
|
variant,
|
|
7548
8273
|
bordered,
|
|
@@ -7560,19 +8285,19 @@ var BasicEditor = ({
|
|
|
7560
8285
|
...options
|
|
7561
8286
|
});
|
|
7562
8287
|
const styles = editorBasic({ variant, bordered });
|
|
7563
|
-
const resolveVariable =
|
|
8288
|
+
const resolveVariable = useCallback38(
|
|
7564
8289
|
(name) => variableValues == null ? void 0 : variableValues[name],
|
|
7565
8290
|
[variableValues]
|
|
7566
8291
|
);
|
|
7567
8292
|
if (!editor) {
|
|
7568
|
-
return /* @__PURE__ */
|
|
8293
|
+
return /* @__PURE__ */ jsx34(LoadingSpinner, {});
|
|
7569
8294
|
}
|
|
7570
8295
|
const isBottomToolbar = variant === "field";
|
|
7571
8296
|
const hasVariables = variables && variables.length > 0;
|
|
7572
8297
|
const hasPagination = !!pagesOptions;
|
|
7573
|
-
const editorContent = /* @__PURE__ */
|
|
7574
|
-
showToolbar && !isBottomToolbar && /* @__PURE__ */
|
|
7575
|
-
/* @__PURE__ */
|
|
8298
|
+
const editorContent = /* @__PURE__ */ jsx34(EditorUIProvider, { value: { styles }, children: /* @__PURE__ */ jsx34("div", { className: styles.root(), "data-slot": "editor", children: /* @__PURE__ */ jsxs25(EditorContext.Provider, { value: { editor }, children: [
|
|
8299
|
+
showToolbar && !isBottomToolbar && /* @__PURE__ */ jsx34(EditorHeader, { editor, variant }),
|
|
8300
|
+
/* @__PURE__ */ jsx34(
|
|
7576
8301
|
EditorContentArea,
|
|
7577
8302
|
{
|
|
7578
8303
|
variant,
|
|
@@ -7580,10 +8305,10 @@ var BasicEditor = ({
|
|
|
7580
8305
|
hasPagination
|
|
7581
8306
|
}
|
|
7582
8307
|
),
|
|
7583
|
-
showToolbar && isBottomToolbar && /* @__PURE__ */
|
|
8308
|
+
showToolbar && isBottomToolbar && /* @__PURE__ */ jsx34(EditorHeader, { editor, variant })
|
|
7584
8309
|
] }) }) });
|
|
7585
8310
|
if (hasVariables) {
|
|
7586
|
-
return /* @__PURE__ */
|
|
8311
|
+
return /* @__PURE__ */ jsx34(VariableProvider, { variables, resolveVariable, children: editorContent });
|
|
7587
8312
|
}
|
|
7588
8313
|
return editorContent;
|
|
7589
8314
|
};
|
|
@@ -7596,7 +8321,7 @@ var EditorContentArea = ({
|
|
|
7596
8321
|
const { editor } = useContext4(EditorContext);
|
|
7597
8322
|
const { isDragging } = useUiEditorState(editor);
|
|
7598
8323
|
useScrollToHash();
|
|
7599
|
-
const handleKeyDown =
|
|
8324
|
+
const handleKeyDown = useCallback38(
|
|
7600
8325
|
(e) => {
|
|
7601
8326
|
if (!(editor == null ? void 0 : editor.isFocused)) return;
|
|
7602
8327
|
const isMod = e.metaKey || e.ctrlKey;
|
|
@@ -7638,8 +8363,8 @@ var EditorContentArea = ({
|
|
|
7638
8363
|
const contentClassName = hasPagination ? "w-full min-w-0 h-auto min-h-0" : styles.content();
|
|
7639
8364
|
return (
|
|
7640
8365
|
// biome-ignore lint/a11y/noStaticElementInteractions: Wrapper intercepts keyboard shortcuts to prevent propagation
|
|
7641
|
-
/* @__PURE__ */
|
|
7642
|
-
/* @__PURE__ */
|
|
8366
|
+
/* @__PURE__ */ jsxs25("div", { className: styles.wrapper(), onKeyDown: handleKeyDown, children: [
|
|
8367
|
+
/* @__PURE__ */ jsxs25(
|
|
7643
8368
|
EditorContent,
|
|
7644
8369
|
{
|
|
7645
8370
|
editor,
|
|
@@ -7649,20 +8374,36 @@ var EditorContentArea = ({
|
|
|
7649
8374
|
cursor: isDragging ? "grabbing" : "auto"
|
|
7650
8375
|
},
|
|
7651
8376
|
children: [
|
|
7652
|
-
isEditable && /* @__PURE__ */
|
|
7653
|
-
isEditable && variables && variables.length > 0 && /* @__PURE__ */
|
|
8377
|
+
isEditable && /* @__PURE__ */ jsx34(SlashDropdownMenu, {}),
|
|
8378
|
+
isEditable && variables && variables.length > 0 && /* @__PURE__ */ jsx34(VariableSuggestion, { editor, variables })
|
|
7654
8379
|
]
|
|
7655
8380
|
}
|
|
7656
8381
|
),
|
|
7657
|
-
isEditable && /* @__PURE__ */
|
|
7658
|
-
isEditable && /* @__PURE__ */
|
|
8382
|
+
isEditable && /* @__PURE__ */ jsx34(BubbleMenu, { editor }),
|
|
8383
|
+
isEditable && /* @__PURE__ */ jsx34(LinkBubble, { editor }),
|
|
8384
|
+
isEditable && /* @__PURE__ */ jsxs25(Fragment10, { children: [
|
|
8385
|
+
/* @__PURE__ */ jsx34(TableHandle, { editor }),
|
|
8386
|
+
/* @__PURE__ */ jsx34(
|
|
8387
|
+
TableSelectionOverlay,
|
|
8388
|
+
{
|
|
8389
|
+
showResizeHandles: true,
|
|
8390
|
+
cellMenu: (props) => /* @__PURE__ */ jsx34(
|
|
8391
|
+
TableCellHandleMenu,
|
|
8392
|
+
{
|
|
8393
|
+
editor: props.editor,
|
|
8394
|
+
onOpenChange: props.onOpenChange
|
|
8395
|
+
}
|
|
8396
|
+
)
|
|
8397
|
+
}
|
|
8398
|
+
)
|
|
8399
|
+
] })
|
|
7659
8400
|
] })
|
|
7660
8401
|
);
|
|
7661
8402
|
};
|
|
7662
8403
|
function LoadingSpinner({ text = "Connecting..." }) {
|
|
7663
8404
|
const styles = editorSpinner();
|
|
7664
|
-
return /* @__PURE__ */
|
|
7665
|
-
/* @__PURE__ */
|
|
8405
|
+
return /* @__PURE__ */ jsx34("div", { className: styles.root(), children: /* @__PURE__ */ jsxs25("div", { className: styles.content(), children: [
|
|
8406
|
+
/* @__PURE__ */ jsxs25(
|
|
7666
8407
|
"svg",
|
|
7667
8408
|
{
|
|
7668
8409
|
className: styles.svg(),
|
|
@@ -7670,9 +8411,9 @@ function LoadingSpinner({ text = "Connecting..." }) {
|
|
|
7670
8411
|
fill: "none",
|
|
7671
8412
|
viewBox: "0 0 24 24",
|
|
7672
8413
|
children: [
|
|
7673
|
-
/* @__PURE__ */
|
|
7674
|
-
/* @__PURE__ */
|
|
7675
|
-
/* @__PURE__ */
|
|
8414
|
+
/* @__PURE__ */ jsx34("title", { children: "Loading Spinner" }),
|
|
8415
|
+
/* @__PURE__ */ jsx34("circle", { className: styles.circle(), cx: "12", cy: "12", r: "10" }),
|
|
8416
|
+
/* @__PURE__ */ jsx34(
|
|
7676
8417
|
"path",
|
|
7677
8418
|
{
|
|
7678
8419
|
className: styles.path(),
|
|
@@ -7682,7 +8423,7 @@ function LoadingSpinner({ text = "Connecting..." }) {
|
|
|
7682
8423
|
]
|
|
7683
8424
|
}
|
|
7684
8425
|
),
|
|
7685
|
-
/* @__PURE__ */
|
|
8426
|
+
/* @__PURE__ */ jsx34("div", { className: styles.text(), children: text })
|
|
7686
8427
|
] }) });
|
|
7687
8428
|
}
|
|
7688
8429
|
export {
|