@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.
Files changed (3) hide show
  1. package/dist/index.js +2059 -1347
  2. package/dist/index.mjs +2063 -1322
  3. package/package.json +24 -24
package/dist/index.js CHANGED
@@ -1023,7 +1023,7 @@ var ImageNode = import_extension_image.Image.extend({
1023
1023
  return (0, import_react11.ReactNodeViewRenderer)(ImageNodeView, {
1024
1024
  stopEvent: ({ event }) => {
1025
1025
  const target = event.target;
1026
- if (target.closest("button, [role='button'], input, a")) {
1026
+ if (target instanceof HTMLElement && target.closest("button, [role='button'], input, a")) {
1027
1027
  return true;
1028
1028
  }
1029
1029
  return false;
@@ -1374,7 +1374,7 @@ var ImageUploadNode = import_core2.Node.create({
1374
1374
  return (0, import_react14.ReactNodeViewRenderer)(ImageUploadNodeView, {
1375
1375
  stopEvent: ({ event }) => {
1376
1376
  const target = event.target;
1377
- if (target.closest("button, [role='button'], input, a")) {
1377
+ if (target instanceof HTMLElement && target.closest("button, [role='button'], input, a")) {
1378
1378
  return true;
1379
1379
  }
1380
1380
  return false;
@@ -2751,13 +2751,14 @@ function VariableFillerDialog({
2751
2751
  }
2752
2752
 
2753
2753
  // src/extensions/variable/variable-suggestion.tsx
2754
- var import_editor_utils = require("@kopexa/editor-utils");
2754
+ var import_editor_utils2 = require("@kopexa/editor-utils");
2755
2755
  var import_theme6 = require("@kopexa/theme");
2756
2756
  var import_state2 = require("@tiptap/pm/state");
2757
2757
  var React6 = __toESM(require("react"));
2758
2758
 
2759
2759
  // src/ui/suggestion-menu/suggestion-menu.tsx
2760
- var import_react30 = require("@floating-ui/react");
2760
+ var import_react28 = require("@floating-ui/react");
2761
+ var import_editor_utils = require("@kopexa/editor-utils");
2761
2762
  var import_state = require("@tiptap/pm/state");
2762
2763
  var import_suggestion = require("@tiptap/suggestion");
2763
2764
  var React5 = __toESM(require("react"));
@@ -2935,35 +2936,6 @@ function useMenuNavigation({
2935
2936
  };
2936
2937
  }
2937
2938
 
2938
- // src/hooks/use-tiptap-editor.ts
2939
- var import_react28 = require("@tiptap/react");
2940
- var import_react29 = require("react");
2941
- function useTiptapEditor(providedEditor) {
2942
- const { editor: coreEditor } = (0, import_react28.useCurrentEditor)();
2943
- const mainEditor = (0, import_react29.useMemo)(
2944
- () => providedEditor || coreEditor,
2945
- [providedEditor, coreEditor]
2946
- );
2947
- const editorState = (0, import_react28.useEditorState)({
2948
- editor: mainEditor,
2949
- selector(context) {
2950
- if (!context.editor) {
2951
- return {
2952
- editor: null,
2953
- editorState: void 0,
2954
- canCommand: void 0
2955
- };
2956
- }
2957
- return {
2958
- editor: context.editor,
2959
- editorState: context.editor.state,
2960
- canCommand: context.editor.can
2961
- };
2962
- }
2963
- });
2964
- return editorState || { editor: null };
2965
- }
2966
-
2967
2939
  // src/ui/suggestion-menu/suggestion-menu-utils.ts
2968
2940
  function calculateStartPosition(cursorPosition, previousNode, triggerChar) {
2969
2941
  if (!(previousNode == null ? void 0 : previousNode.text) || !triggerChar) {
@@ -3020,7 +2992,7 @@ var SuggestionMenu = ({
3020
2992
  pluginKey = import_suggestion.SuggestionPluginKey,
3021
2993
  ...internalSuggestionProps
3022
2994
  }) => {
3023
- const { editor } = useTiptapEditor(providedEditor);
2995
+ const { editor } = (0, import_editor_utils.useTiptapEditor)(providedEditor);
3024
2996
  const [show, setShow] = React5.useState(false);
3025
2997
  const [internalClientRect, setInternalClientRect] = React5.useState(null);
3026
2998
  const [internalCommand, setInternalCommand] = React5.useState(null);
@@ -3036,13 +3008,13 @@ var SuggestionMenu = ({
3036
3008
  {
3037
3009
  placement: "bottom-start",
3038
3010
  middleware: [
3039
- (0, import_react30.offset)(10),
3040
- (0, import_react30.flip)({
3011
+ (0, import_react28.offset)(10),
3012
+ (0, import_react28.flip)({
3041
3013
  mainAxis: true,
3042
3014
  crossAxis: false
3043
3015
  }),
3044
- (0, import_react30.shift)(),
3045
- (0, import_react30.size)({
3016
+ (0, import_react28.shift)(),
3017
+ (0, import_react28.size)({
3046
3018
  apply({ availableHeight, elements }) {
3047
3019
  if (elements.floating) {
3048
3020
  const maxHeightValue = maxHeight ? Math.min(maxHeight, availableHeight) : availableHeight;
@@ -3181,7 +3153,7 @@ var SuggestionMenu = ({
3181
3153
  if (!isMounted || !show || !editor) {
3182
3154
  return null;
3183
3155
  }
3184
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react30.FloatingPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3156
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react28.FloatingPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3185
3157
  "div",
3186
3158
  {
3187
3159
  ref,
@@ -3276,7 +3248,7 @@ var VariableItem = ({
3276
3248
  '[data-selector="tiptap-variable-suggestion-menu"]'
3277
3249
  );
3278
3250
  if (!itemRef.current || !isSelected || !selector) return;
3279
- const overflow = (0, import_editor_utils.getElementOverflowPosition)(itemRef.current, selector);
3251
+ const overflow = (0, import_editor_utils2.getElementOverflowPosition)(itemRef.current, selector);
3280
3252
  if (overflow === "top") {
3281
3253
  itemRef.current.scrollIntoView(true);
3282
3254
  } else if (overflow === "bottom") {
@@ -3376,14 +3348,14 @@ var import_extension_text_style = require("@tiptap/extension-text-style");
3376
3348
  var import_extension_typography = require("@tiptap/extension-typography");
3377
3349
  var import_extension_unique_id = require("@tiptap/extension-unique-id");
3378
3350
  var import_extensions = require("@tiptap/extensions");
3379
- var import_react34 = require("@tiptap/react");
3351
+ var import_react32 = require("@tiptap/react");
3380
3352
  var import_starter_kit = require("@tiptap/starter-kit");
3381
- var import_react35 = require("react");
3353
+ var import_react33 = require("react");
3382
3354
 
3383
3355
  // src/extensions/link/index.ts
3384
3356
  var import_extension_link = __toESM(require("@tiptap/extension-link"));
3385
3357
  var import_state3 = require("@tiptap/pm/state");
3386
- var import_react31 = require("@tiptap/react");
3358
+ var import_react29 = require("@tiptap/react");
3387
3359
  var Link = import_extension_link.default.extend({
3388
3360
  inclusive: false,
3389
3361
  parseHTML() {
@@ -3412,7 +3384,7 @@ var Link = import_extension_link.default.extend({
3412
3384
  const { schema, doc, tr } = view.state;
3413
3385
  let range;
3414
3386
  if (schema.marks.link) {
3415
- range = (0, import_react31.getMarkRange)(doc.resolve(pos), schema.marks.link);
3387
+ range = (0, import_react29.getMarkRange)(doc.resolve(pos), schema.marks.link);
3416
3388
  }
3417
3389
  if (!range) {
3418
3390
  return;
@@ -3436,11 +3408,290 @@ var Link = import_extension_link.default.extend({
3436
3408
  }
3437
3409
  });
3438
3410
 
3411
+ // src/extensions/node-alignment/index.ts
3412
+ var import_editor_utils3 = require("@kopexa/editor-utils");
3413
+ var import_core7 = require("@tiptap/core");
3414
+ function getToggleValue(targets, attributeName, inputValue) {
3415
+ var _a, _b;
3416
+ if (targets.length === 0) return null;
3417
+ for (const target of targets) {
3418
+ const currentValue = (_b = (_a = target.node.attrs) == null ? void 0 : _a[attributeName]) != null ? _b : null;
3419
+ if (currentValue !== inputValue) {
3420
+ return inputValue;
3421
+ }
3422
+ }
3423
+ return null;
3424
+ }
3425
+ var NodeAlignment = import_core7.Extension.create({
3426
+ name: "nodeAlignment",
3427
+ addOptions() {
3428
+ return {
3429
+ types: ["paragraph", "heading", "blockquote", "tableCell", "tableHeader"],
3430
+ useStyle: true,
3431
+ textAlignValues: ["left", "center", "right", "justify"],
3432
+ verticalAlignValues: ["top", "middle", "bottom"]
3433
+ };
3434
+ },
3435
+ addGlobalAttributes() {
3436
+ return [
3437
+ {
3438
+ types: this.options.types,
3439
+ attributes: {
3440
+ nodeTextAlign: {
3441
+ default: null,
3442
+ parseHTML: (element) => {
3443
+ var _a;
3444
+ const styleAlign = (_a = element.style) == null ? void 0 : _a.textAlign;
3445
+ if (styleAlign && this.options.textAlignValues.includes(styleAlign)) {
3446
+ return styleAlign;
3447
+ }
3448
+ const dataAlign = element.getAttribute("data-node-text-align");
3449
+ if (dataAlign && this.options.textAlignValues.includes(dataAlign)) {
3450
+ return dataAlign;
3451
+ }
3452
+ return null;
3453
+ },
3454
+ renderHTML: (attributes) => {
3455
+ const align = attributes.nodeTextAlign;
3456
+ if (!align || !this.options.textAlignValues.includes(align))
3457
+ return {};
3458
+ if (this.options.useStyle) {
3459
+ return { style: `text-align: ${align}` };
3460
+ } else {
3461
+ return { "data-node-text-align": align };
3462
+ }
3463
+ }
3464
+ },
3465
+ nodeVerticalAlign: {
3466
+ default: null,
3467
+ parseHTML: (element) => {
3468
+ var _a;
3469
+ const styleVAlign = (_a = element.style) == null ? void 0 : _a.verticalAlign;
3470
+ if (styleVAlign && this.options.verticalAlignValues.includes(styleVAlign)) {
3471
+ return styleVAlign;
3472
+ }
3473
+ const dataVAlign = element.getAttribute(
3474
+ "data-node-vertical-align"
3475
+ );
3476
+ if (dataVAlign && this.options.verticalAlignValues.includes(dataVAlign)) {
3477
+ return dataVAlign;
3478
+ }
3479
+ return null;
3480
+ },
3481
+ renderHTML: (attributes) => {
3482
+ const vAlign = attributes.nodeVerticalAlign;
3483
+ if (!vAlign || !this.options.verticalAlignValues.includes(vAlign))
3484
+ return {};
3485
+ if (this.options.useStyle) {
3486
+ return { style: `vertical-align: ${vAlign}` };
3487
+ } else {
3488
+ return { "data-node-vertical-align": vAlign };
3489
+ }
3490
+ }
3491
+ }
3492
+ }
3493
+ }
3494
+ ];
3495
+ },
3496
+ addCommands() {
3497
+ const executeAlignmentCommand = (attributeName, getTargetValue) => {
3498
+ return (inputValue) => ({ state, tr }) => {
3499
+ const targets = (0, import_editor_utils3.getSelectedNodesOfType)(
3500
+ state.selection,
3501
+ this.options.types
3502
+ );
3503
+ if (targets.length === 0) return false;
3504
+ const targetValue = getTargetValue(targets, inputValue);
3505
+ return (0, import_editor_utils3.updateNodesAttr)(tr, targets, attributeName, targetValue);
3506
+ };
3507
+ };
3508
+ return {
3509
+ // TEXT ALIGN
3510
+ setNodeTextAlign: executeAlignmentCommand(
3511
+ "nodeTextAlign",
3512
+ (_, inputValue) => {
3513
+ if (!inputValue || !this.options.textAlignValues.includes(inputValue))
3514
+ return null;
3515
+ return inputValue;
3516
+ }
3517
+ ),
3518
+ unsetNodeTextAlign: executeAlignmentCommand("nodeTextAlign", () => null),
3519
+ toggleNodeTextAlign: executeAlignmentCommand(
3520
+ "nodeTextAlign",
3521
+ (targets, inputValue) => {
3522
+ if (!inputValue || !this.options.textAlignValues.includes(inputValue))
3523
+ return null;
3524
+ return getToggleValue(targets, "nodeTextAlign", inputValue);
3525
+ }
3526
+ ),
3527
+ // VERTICAL ALIGN
3528
+ setNodeVAlign: executeAlignmentCommand(
3529
+ "nodeVerticalAlign",
3530
+ (_, inputValue) => {
3531
+ if (!inputValue || !this.options.verticalAlignValues.includes(inputValue))
3532
+ return null;
3533
+ return inputValue;
3534
+ }
3535
+ ),
3536
+ unsetNodeVAlign: executeAlignmentCommand("nodeVerticalAlign", () => null),
3537
+ toggleNodeVAlign: executeAlignmentCommand(
3538
+ "nodeVerticalAlign",
3539
+ (targets, inputValue) => {
3540
+ if (!inputValue || !this.options.verticalAlignValues.includes(inputValue))
3541
+ return null;
3542
+ return getToggleValue(targets, "nodeVerticalAlign", inputValue);
3543
+ }
3544
+ ),
3545
+ // BOTH
3546
+ setNodeAlignment: (textAlign, verticalAlign) => ({ state, tr }) => {
3547
+ const targets = (0, import_editor_utils3.getSelectedNodesOfType)(
3548
+ state.selection,
3549
+ this.options.types
3550
+ );
3551
+ if (targets.length === 0) return false;
3552
+ let hasChanges = false;
3553
+ for (const { node, pos } of targets) {
3554
+ const newAttrs = { ...node.attrs };
3555
+ if (textAlign && this.options.textAlignValues.includes(textAlign)) {
3556
+ newAttrs.nodeTextAlign = textAlign;
3557
+ hasChanges = true;
3558
+ }
3559
+ if (verticalAlign && this.options.verticalAlignValues.includes(verticalAlign)) {
3560
+ newAttrs.nodeVerticalAlign = verticalAlign;
3561
+ hasChanges = true;
3562
+ }
3563
+ if (hasChanges) tr.setNodeMarkup(pos, void 0, newAttrs);
3564
+ }
3565
+ return hasChanges;
3566
+ },
3567
+ unsetNodeAlignment: () => ({ state, tr }) => {
3568
+ var _a, _b, _c, _d;
3569
+ const targets = (0, import_editor_utils3.getSelectedNodesOfType)(
3570
+ state.selection,
3571
+ this.options.types
3572
+ );
3573
+ if (targets.length === 0) return false;
3574
+ let hasChanges = false;
3575
+ for (const { node, pos } of targets) {
3576
+ const hasText = (_b = (_a = node.attrs) == null ? void 0 : _a.nodeTextAlign) != null ? _b : null;
3577
+ const hasV = (_d = (_c = node.attrs) == null ? void 0 : _c.nodeVerticalAlign) != null ? _d : null;
3578
+ if (hasText || hasV) {
3579
+ const newAttrs = {
3580
+ ...node.attrs,
3581
+ nodeTextAlign: null,
3582
+ nodeVerticalAlign: null
3583
+ };
3584
+ tr.setNodeMarkup(pos, void 0, newAttrs);
3585
+ hasChanges = true;
3586
+ }
3587
+ }
3588
+ return hasChanges;
3589
+ }
3590
+ };
3591
+ }
3592
+ });
3593
+
3594
+ // src/extensions/node-background/index.ts
3595
+ var import_editor_utils4 = require("@kopexa/editor-utils");
3596
+ var import_core8 = require("@tiptap/core");
3597
+ function getToggleColor(targets, inputColor) {
3598
+ var _a, _b;
3599
+ if (targets.length === 0) return null;
3600
+ for (const target of targets) {
3601
+ const currentColor = (_b = (_a = target.node.attrs) == null ? void 0 : _a.backgroundColor) != null ? _b : null;
3602
+ if (currentColor !== inputColor) {
3603
+ return inputColor;
3604
+ }
3605
+ }
3606
+ return null;
3607
+ }
3608
+ var NodeBackground = import_core8.Extension.create({
3609
+ name: "nodeBackground",
3610
+ addOptions() {
3611
+ return {
3612
+ types: [
3613
+ "paragraph",
3614
+ "heading",
3615
+ "blockquote",
3616
+ "taskList",
3617
+ "bulletList",
3618
+ "orderedList",
3619
+ "tableCell",
3620
+ "tableHeader"
3621
+ ],
3622
+ useStyle: true
3623
+ };
3624
+ },
3625
+ addGlobalAttributes() {
3626
+ return [
3627
+ {
3628
+ types: this.options.types,
3629
+ attributes: {
3630
+ backgroundColor: {
3631
+ default: null,
3632
+ parseHTML: (element) => {
3633
+ var _a;
3634
+ const styleColor = (_a = element.style) == null ? void 0 : _a.backgroundColor;
3635
+ if (styleColor) return styleColor;
3636
+ const dataColor = element.getAttribute("data-background-color");
3637
+ return dataColor || null;
3638
+ },
3639
+ renderHTML: (attributes) => {
3640
+ const color = attributes.backgroundColor;
3641
+ if (!color) return {};
3642
+ if (this.options.useStyle) {
3643
+ return {
3644
+ style: `background-color: ${color}`
3645
+ };
3646
+ } else {
3647
+ return {
3648
+ "data-background-color": color
3649
+ };
3650
+ }
3651
+ }
3652
+ }
3653
+ }
3654
+ }
3655
+ ];
3656
+ },
3657
+ addCommands() {
3658
+ const executeBackgroundCommand = (getTargetColor) => {
3659
+ return (inputColor) => ({ state, tr }) => {
3660
+ const targets = (0, import_editor_utils4.getSelectedNodesOfType)(
3661
+ state.selection,
3662
+ this.options.types
3663
+ );
3664
+ if (targets.length === 0) return false;
3665
+ const targetColor = getTargetColor(targets, inputColor);
3666
+ return (0, import_editor_utils4.updateNodesAttr)(tr, targets, "backgroundColor", targetColor);
3667
+ };
3668
+ };
3669
+ return {
3670
+ /**
3671
+ * Set background color to specific value
3672
+ */
3673
+ setNodeBackgroundColor: executeBackgroundCommand(
3674
+ (_, inputColor) => inputColor || null
3675
+ ),
3676
+ /**
3677
+ * Remove background color
3678
+ */
3679
+ unsetNodeBackgroundColor: executeBackgroundCommand(() => null),
3680
+ /**
3681
+ * Toggle background color (set if different/missing, unset if all have it)
3682
+ */
3683
+ toggleNodeBackgroundColor: executeBackgroundCommand(
3684
+ (targets, inputColor) => getToggleColor(targets, inputColor || "")
3685
+ )
3686
+ };
3687
+ }
3688
+ });
3689
+
3439
3690
  // src/extensions/selection/index.ts
3440
3691
  var import_state4 = require("@tiptap/pm/state");
3441
3692
  var import_view = require("@tiptap/pm/view");
3442
- var import_react32 = require("@tiptap/react");
3443
- var Selection = import_react32.Extension.create({
3693
+ var import_react30 = require("@tiptap/react");
3694
+ var Selection = import_react30.Extension.create({
3444
3695
  name: "selection",
3445
3696
  addProseMirrorPlugins() {
3446
3697
  const { editor } = this;
@@ -3455,7 +3706,7 @@ var Selection = import_react32.Extension.create({
3455
3706
  if (editor.isFocused === true || !editor.isEditable) {
3456
3707
  return null;
3457
3708
  }
3458
- if ((0, import_react32.isNodeSelection)(state.selection)) {
3709
+ if ((0, import_react30.isNodeSelection)(state.selection)) {
3459
3710
  return null;
3460
3711
  }
3461
3712
  return import_view.DecorationSet.create(state.doc, [
@@ -3472,7 +3723,7 @@ var Selection = import_react32.Extension.create({
3472
3723
 
3473
3724
  // src/extensions/trailing-node/index.ts
3474
3725
  var import_state5 = require("@tiptap/pm/state");
3475
- var import_react33 = require("@tiptap/react");
3726
+ var import_react31 = require("@tiptap/react");
3476
3727
  function nodeEqualsType({
3477
3728
  types,
3478
3729
  node
@@ -3483,7 +3734,7 @@ function nodeEqualsType({
3483
3734
  }
3484
3735
  return node.type === types;
3485
3736
  }
3486
- var TrailingNode = import_react33.Extension.create({
3737
+ var TrailingNode = import_react31.Extension.create({
3487
3738
  name: "trailingNode",
3488
3739
  addOptions() {
3489
3740
  return {
@@ -3529,7 +3780,7 @@ var TrailingNode = import_react33.Extension.create({
3529
3780
  });
3530
3781
 
3531
3782
  // src/extensions/ui-state/index.ts
3532
- var import_core7 = require("@tiptap/core");
3783
+ var import_core9 = require("@tiptap/core");
3533
3784
  var defaultUiState = {
3534
3785
  aiGenerationIsSelection: false,
3535
3786
  aiGenerationIsLoading: false,
@@ -3539,7 +3790,7 @@ var defaultUiState = {
3539
3790
  lockDragHandle: false,
3540
3791
  isDragging: false
3541
3792
  };
3542
- var UiState = import_core7.Extension.create({
3793
+ var UiState = import_core9.Extension.create({
3543
3794
  name: "uiState",
3544
3795
  addStorage() {
3545
3796
  return {
@@ -3764,7 +4015,7 @@ var useCreateEditor = ({
3764
4015
  const fileHandlerFromContext = useEditorFile();
3765
4016
  const fileHandler = fileHandlerProp != null ? fileHandlerProp : fileHandlerFromContext;
3766
4017
  const collaboration = useCollaboration();
3767
- const [extensions] = (0, import_react35.useState)(
4018
+ const [extensions] = (0, import_react33.useState)(
3768
4019
  () => getExtensions({
3769
4020
  editable,
3770
4021
  placeholder,
@@ -3778,7 +4029,7 @@ var useCreateEditor = ({
3778
4029
  disabled
3779
4030
  })
3780
4031
  );
3781
- const editor = (0, import_react34.useEditor)({
4032
+ const editor = (0, import_react32.useEditor)({
3782
4033
  editorProps: {
3783
4034
  attributes: {
3784
4035
  autocomplete: "off",
@@ -3797,7 +4048,7 @@ var useCreateEditor = ({
3797
4048
  content: safeParseContent(content),
3798
4049
  ...options
3799
4050
  });
3800
- (0, import_react35.useEffect)(() => {
4051
+ (0, import_react33.useEffect)(() => {
3801
4052
  if (editor && editor.isEditable !== editable) {
3802
4053
  editor.setEditable(editable);
3803
4054
  }
@@ -3864,6 +4115,8 @@ function getExtensions({
3864
4115
  }),
3865
4116
  UiState,
3866
4117
  import_extension_table.TableKit,
4118
+ NodeAlignment,
4119
+ NodeBackground,
3867
4120
  TocNode,
3868
4121
  CalloutNode,
3869
4122
  MathBlock,
@@ -4012,19 +4265,20 @@ async function handleFileUpload(editor, file, fileHandler, pos) {
4012
4265
  }
4013
4266
 
4014
4267
  // src/presets/basic/index.tsx
4268
+ var import_extension_table2 = require("@kopexa/extension-table");
4015
4269
  var import_theme9 = require("@kopexa/theme");
4016
- var import_react59 = require("@tiptap/react");
4017
- var import_react60 = require("react");
4270
+ var import_react60 = require("@tiptap/react");
4271
+ var import_react61 = require("react");
4018
4272
 
4019
4273
  // src/context/editor-context.ts
4020
4274
  var import_react_utils = require("@kopexa/react-utils");
4021
4275
  var [EditorUIProvider, useEditorUIContext] = (0, import_react_utils.createContext)();
4022
4276
 
4023
4277
  // src/hooks/use-ui-editor-state.ts
4024
- var import_react36 = require("@tiptap/react");
4278
+ var import_react34 = require("@tiptap/react");
4025
4279
  function useUiEditorState(editor) {
4026
4280
  var _a;
4027
- return (_a = (0, import_react36.useEditorState)({
4281
+ return (_a = (0, import_react34.useEditorState)({
4028
4282
  editor,
4029
4283
  selector: ({ editor: editor2 }) => {
4030
4284
  if (!editor2) return defaultUiState;
@@ -4046,14 +4300,15 @@ var import_menus = require("@tiptap/react/menus");
4046
4300
 
4047
4301
  // src/ui/link-popover/link-popover.tsx
4048
4302
  var import_button8 = require("@kopexa/button");
4303
+ var import_editor_utils6 = require("@kopexa/editor-utils");
4049
4304
  var import_icons9 = require("@kopexa/icons");
4050
4305
  var import_input3 = require("@kopexa/input");
4051
4306
  var import_popover = require("@kopexa/popover");
4052
4307
  var import_toolbar = require("@kopexa/toolbar");
4053
- var import_react37 = require("react");
4308
+ var import_react35 = require("react");
4054
4309
 
4055
4310
  // src/ui/link-popover/use-link-popover.ts
4056
- var import_editor_utils2 = require("@kopexa/editor-utils");
4311
+ var import_editor_utils5 = require("@kopexa/editor-utils");
4057
4312
  var import_icons8 = require("@kopexa/icons");
4058
4313
  var React7 = __toESM(require("react"));
4059
4314
 
@@ -4160,7 +4415,7 @@ function isLinkActive(editor) {
4160
4415
  }
4161
4416
  function shouldShowLinkButton(props) {
4162
4417
  const { editor, hideWhenUnavailable } = props;
4163
- const linkInSchema = (0, import_editor_utils2.isMarkInSchema)("link", editor);
4418
+ const linkInSchema = (0, import_editor_utils5.isMarkInSchema)("link", editor);
4164
4419
  if (!linkInSchema || !editor) {
4165
4420
  return false;
4166
4421
  }
@@ -4259,7 +4514,7 @@ function useLinkPopover(config) {
4259
4514
  hideWhenUnavailable = false,
4260
4515
  onSetLink
4261
4516
  } = config || {};
4262
- const { editor } = useTiptapEditor(providedEditor);
4517
+ const { editor } = (0, import_editor_utils5.useTiptapEditor)(providedEditor);
4263
4518
  const { isVisible, canSet, isActive } = useLinkState({
4264
4519
  editor,
4265
4520
  hideWhenUnavailable
@@ -4306,8 +4561,8 @@ var LinkMain = ({
4306
4561
  isActive,
4307
4562
  onSave
4308
4563
  }) => {
4309
- const [isEditing, setIsEditing] = (0, import_react37.useState)(!isActive || !url);
4310
- (0, import_react37.useEffect)(() => {
4564
+ const [isEditing, setIsEditing] = (0, import_react35.useState)(!isActive || !url);
4565
+ (0, import_react35.useEffect)(() => {
4311
4566
  setIsEditing(!isActive || !url);
4312
4567
  }, [isActive, url]);
4313
4568
  const handleKeyDown = (event) => {
@@ -4422,8 +4677,8 @@ function LinkPopover({
4422
4677
  children,
4423
4678
  ...buttonProps
4424
4679
  }) {
4425
- const { editor } = useTiptapEditor(providedEditor);
4426
- const [isOpen, setIsOpen] = (0, import_react37.useState)(false);
4680
+ const { editor } = (0, import_editor_utils6.useTiptapEditor)(providedEditor);
4681
+ const [isOpen, setIsOpen] = (0, import_react35.useState)(false);
4427
4682
  const {
4428
4683
  isVisible,
4429
4684
  canSet,
@@ -4439,18 +4694,18 @@ function LinkPopover({
4439
4694
  hideWhenUnavailable,
4440
4695
  onSetLink
4441
4696
  });
4442
- const handleOnOpenChange = (0, import_react37.useCallback)(
4697
+ const handleOnOpenChange = (0, import_react35.useCallback)(
4443
4698
  (nextIsOpen) => {
4444
4699
  setIsOpen(nextIsOpen);
4445
4700
  onOpenChange == null ? void 0 : onOpenChange(nextIsOpen);
4446
4701
  },
4447
4702
  [onOpenChange]
4448
4703
  );
4449
- const handleSetLink = (0, import_react37.useCallback)(() => {
4704
+ const handleSetLink = (0, import_react35.useCallback)(() => {
4450
4705
  setLink();
4451
4706
  setIsOpen(false);
4452
4707
  }, [setLink]);
4453
- const handleClick = (0, import_react37.useCallback)(
4708
+ const handleClick = (0, import_react35.useCallback)(
4454
4709
  (event) => {
4455
4710
  onClick == null ? void 0 : onClick(event);
4456
4711
  if (event.defaultPrevented) return;
@@ -4458,7 +4713,7 @@ function LinkPopover({
4458
4713
  },
4459
4714
  [onClick, isOpen]
4460
4715
  );
4461
- (0, import_react37.useEffect)(() => {
4716
+ (0, import_react35.useEffect)(() => {
4462
4717
  if (autoOpenOnLinkActive && isActive) {
4463
4718
  setIsOpen(true);
4464
4719
  }
@@ -4509,11 +4764,11 @@ function LinkPopover({
4509
4764
  LinkButton.displayName = "LinkButton";
4510
4765
 
4511
4766
  // src/ui/mark-button/index.tsx
4512
- var import_editor_utils3 = require("@kopexa/editor-utils");
4767
+ var import_editor_utils7 = require("@kopexa/editor-utils");
4513
4768
  var import_icons10 = require("@kopexa/icons");
4514
4769
  var import_toolbar2 = require("@kopexa/toolbar");
4515
- var import_react38 = require("@tiptap/react");
4516
- var import_react39 = require("react");
4770
+ var import_react36 = require("@tiptap/react");
4771
+ var import_react37 = require("react");
4517
4772
  var import_jsx_runtime17 = require("react/jsx-runtime");
4518
4773
  var markIcons = {
4519
4774
  bold: import_icons10.BoldIcon,
@@ -4535,7 +4790,7 @@ var markShortcutKeys = {
4535
4790
  };
4536
4791
  function canToggleMark(editor, type) {
4537
4792
  if (!editor || !editor.isEditable) return false;
4538
- if (!(0, import_editor_utils3.isMarkInSchema)(type, editor) || (0, import_editor_utils3.isNodeTypeSelected)(editor, ["image"]))
4793
+ if (!(0, import_editor_utils7.isMarkInSchema)(type, editor) || (0, import_editor_utils7.isNodeTypeSelected)(editor, ["image"]))
4539
4794
  return false;
4540
4795
  return editor.can().toggleMark(type);
4541
4796
  }
@@ -4560,7 +4815,7 @@ function shouldShowMarkButton(params) {
4560
4815
  return false;
4561
4816
  }
4562
4817
  if (hideWhenUnavailable) {
4563
- if ((0, import_react38.isNodeSelection)(editor.state.selection) || !canToggleMark(editor, type)) {
4818
+ if ((0, import_react36.isNodeSelection)(editor.state.selection) || !canToggleMark(editor, type)) {
4564
4819
  return false;
4565
4820
  }
4566
4821
  }
@@ -4570,7 +4825,7 @@ function getFormattedMarkName(type) {
4570
4825
  return type.charAt(0).toUpperCase() + type.slice(1);
4571
4826
  }
4572
4827
  function useMarkState(editor, type, disabled = false) {
4573
- const markInSchema = (0, import_editor_utils3.isMarkInSchema)(type, editor);
4828
+ const markInSchema = (0, import_editor_utils7.isMarkInSchema)(type, editor);
4574
4829
  const isDisabled = isMarkButtonDisabled(editor, type, disabled);
4575
4830
  const isActive = isMarkActive(editor, type);
4576
4831
  const Icon = markIcons[type];
@@ -4596,7 +4851,7 @@ var MarkButton = ({
4596
4851
  children,
4597
4852
  ...buttonProps
4598
4853
  }) => {
4599
- const { editor } = useTiptapEditor(providedEditor);
4854
+ const { editor } = (0, import_editor_utils7.useTiptapEditor)(providedEditor);
4600
4855
  const {
4601
4856
  markInSchema,
4602
4857
  isDisabled,
@@ -4605,7 +4860,7 @@ var MarkButton = ({
4605
4860
  shortcutKey,
4606
4861
  formattedName
4607
4862
  } = useMarkState(editor, type, disabled);
4608
- const handleClick = (0, import_react39.useCallback)(
4863
+ const handleClick = (0, import_react37.useCallback)(
4609
4864
  (e) => {
4610
4865
  onClick == null ? void 0 : onClick(e);
4611
4866
  if (!e.defaultPrevented && !isDisabled && editor) {
@@ -4614,7 +4869,7 @@ var MarkButton = ({
4614
4869
  },
4615
4870
  [onClick, isDisabled, editor, type]
4616
4871
  );
4617
- const show = (0, import_react39.useMemo)(() => {
4872
+ const show = (0, import_react37.useMemo)(() => {
4618
4873
  return shouldShowMarkButton({
4619
4874
  editor,
4620
4875
  type,
@@ -4689,12 +4944,12 @@ function BubbleMenu({ editor }) {
4689
4944
  }
4690
4945
 
4691
4946
  // src/ui/copy-anchor-link-button/use-scroll-to-hash.ts
4692
- var import_editor_utils4 = require("@kopexa/editor-utils");
4947
+ var import_editor_utils8 = require("@kopexa/editor-utils");
4693
4948
  var React9 = __toESM(require("react"));
4694
4949
 
4695
4950
  // src/hooks/use-floating-toolbar-visibility.ts
4696
4951
  var import_state6 = require("@tiptap/pm/state");
4697
- var import_react40 = require("@tiptap/react");
4952
+ var import_react38 = require("@tiptap/react");
4698
4953
  var React8 = __toESM(require("react"));
4699
4954
  var HIDE_FLOATING_META = "hideFloatingToolbar";
4700
4955
  var selectNodeAndHideFloating = (editor, pos) => {
@@ -4714,12 +4969,12 @@ function useScrollToHash(config = {}) {
4714
4969
  onTargetNotFound = () => {
4715
4970
  }
4716
4971
  } = config;
4717
- const { editor } = useTiptapEditor(providedEditor);
4972
+ const { editor } = (0, import_editor_utils8.useTiptapEditor)(providedEditor);
4718
4973
  const scrollToNode = React9.useCallback(
4719
4974
  (id) => {
4720
4975
  var _a, _b, _c;
4721
4976
  if (!editor) return false;
4722
- const attributeName = (_c = (_b = (_a = (0, import_editor_utils4.getEditorExtension)(editor, "uniqueID")) == null ? void 0 : _a.options) == null ? void 0 : _b.attributeName) != null ? _c : "data-id";
4977
+ const attributeName = (_c = (_b = (_a = (0, import_editor_utils8.getEditorExtension)(editor, "uniqueID")) == null ? void 0 : _a.options) == null ? void 0 : _b.attributeName) != null ? _c : "data-id";
4723
4978
  let position = null;
4724
4979
  editor.state.doc.descendants((node, pos) => {
4725
4980
  var _a2;
@@ -4796,37 +5051,37 @@ var import_button9 = require("@kopexa/button");
4796
5051
  var import_icons11 = require("@kopexa/icons");
4797
5052
  var import_input4 = require("@kopexa/input");
4798
5053
  var import_menus2 = require("@tiptap/react/menus");
4799
- var import_react41 = require("react");
5054
+ var import_react39 = require("react");
4800
5055
  var import_jsx_runtime19 = require("react/jsx-runtime");
4801
5056
  function LinkBubble({ editor }) {
4802
- const [isEditing, setIsEditing] = (0, import_react41.useState)(false);
4803
- const [url, setUrl] = (0, import_react41.useState)("");
4804
- const getCurrentUrl = (0, import_react41.useCallback)(() => {
5057
+ const [isEditing, setIsEditing] = (0, import_react39.useState)(false);
5058
+ const [url, setUrl] = (0, import_react39.useState)("");
5059
+ const getCurrentUrl = (0, import_react39.useCallback)(() => {
4805
5060
  if (!editor) return "";
4806
5061
  const attrs = editor.getAttributes("link");
4807
5062
  return attrs.href || "";
4808
5063
  }, [editor]);
4809
- (0, import_react41.useEffect)(() => {
5064
+ (0, import_react39.useEffect)(() => {
4810
5065
  const isLinkActive2 = editor == null ? void 0 : editor.isActive("link");
4811
5066
  if (isLinkActive2) {
4812
5067
  setUrl(getCurrentUrl());
4813
5068
  setIsEditing(false);
4814
5069
  }
4815
5070
  }, [editor, getCurrentUrl]);
4816
- const handleOpenLink = (0, import_react41.useCallback)(() => {
5071
+ const handleOpenLink = (0, import_react39.useCallback)(() => {
4817
5072
  const href = getCurrentUrl();
4818
5073
  if (href) {
4819
5074
  window.open(href, "_blank", "noopener,noreferrer");
4820
5075
  }
4821
5076
  }, [getCurrentUrl]);
4822
- const handleRemoveLink = (0, import_react41.useCallback)(() => {
5077
+ const handleRemoveLink = (0, import_react39.useCallback)(() => {
4823
5078
  editor == null ? void 0 : editor.chain().focus().unsetLink().run();
4824
5079
  }, [editor]);
4825
- const handleEdit = (0, import_react41.useCallback)(() => {
5080
+ const handleEdit = (0, import_react39.useCallback)(() => {
4826
5081
  setUrl(getCurrentUrl());
4827
5082
  setIsEditing(true);
4828
5083
  }, [getCurrentUrl]);
4829
- const handleSave = (0, import_react41.useCallback)(() => {
5084
+ const handleSave = (0, import_react39.useCallback)(() => {
4830
5085
  if (url) {
4831
5086
  editor == null ? void 0 : editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
4832
5087
  } else {
@@ -4834,7 +5089,7 @@ function LinkBubble({ editor }) {
4834
5089
  }
4835
5090
  setIsEditing(false);
4836
5091
  }, [editor, url]);
4837
- const handleKeyDown = (0, import_react41.useCallback)(
5092
+ const handleKeyDown = (0, import_react39.useCallback)(
4838
5093
  (e) => {
4839
5094
  if (e.key === "Enter") {
4840
5095
  e.preventDefault();
@@ -4945,24 +5200,24 @@ function LinkBubble({ editor }) {
4945
5200
 
4946
5201
  // src/ui/slash-dropdown-menu/slash-dropdown-menu.tsx
4947
5202
  var import_button10 = require("@kopexa/button");
4948
- var import_editor_utils7 = require("@kopexa/editor-utils");
5203
+ var import_editor_utils11 = require("@kopexa/editor-utils");
4949
5204
  var import_separator = require("@kopexa/separator");
4950
5205
  var import_theme7 = require("@kopexa/theme");
4951
5206
  var React11 = __toESM(require("react"));
4952
5207
 
4953
5208
  // src/ui/slash-dropdown-menu/use-slash-dropdown-menu.ts
4954
- var import_editor_utils6 = require("@kopexa/editor-utils");
5209
+ var import_editor_utils10 = require("@kopexa/editor-utils");
4955
5210
  var import_icons13 = require("@kopexa/icons");
4956
5211
  var React10 = __toESM(require("react"));
4957
5212
 
4958
5213
  // src/ui/table-button/use-table.ts
4959
- var import_editor_utils5 = require("@kopexa/editor-utils");
5214
+ var import_editor_utils9 = require("@kopexa/editor-utils");
4960
5215
  var import_icons12 = require("@kopexa/icons");
4961
- var import_react42 = require("@tiptap/react");
4962
- var import_react43 = require("react");
5216
+ var import_react40 = require("@tiptap/react");
5217
+ var import_react41 = require("react");
4963
5218
  function canToggle(editor) {
4964
5219
  if (!editor || !editor.isEditable) return false;
4965
- if (!(0, import_editor_utils5.isNodeInSchema)("table", editor) || (0, import_editor_utils5.isNodeTypeSelected)(editor, ["image"])) {
5220
+ if (!(0, import_editor_utils9.isNodeInSchema)("table", editor) || (0, import_editor_utils9.isNodeTypeSelected)(editor, ["image"])) {
4966
5221
  return false;
4967
5222
  }
4968
5223
  try {
@@ -4988,9 +5243,9 @@ function toggleTable(editor, config) {
4988
5243
  function shouldShowButton(props) {
4989
5244
  const { editor, hideWhenUnavailable } = props;
4990
5245
  if (!editor || !editor.isEditable) return false;
4991
- if (!(0, import_editor_utils5.isNodeInSchema)("table", editor)) return false;
5246
+ if (!(0, import_editor_utils9.isNodeInSchema)("table", editor)) return false;
4992
5247
  if (hideWhenUnavailable) {
4993
- if ((0, import_react42.isNodeSelection)(editor.state.selection) || !canToggle) {
5248
+ if ((0, import_react40.isNodeSelection)(editor.state.selection) || !canToggle) {
4994
5249
  return false;
4995
5250
  }
4996
5251
  }
@@ -5002,11 +5257,11 @@ function useTableBlock(config) {
5002
5257
  hideWhenUnavailable = false,
5003
5258
  onToggled
5004
5259
  } = config || {};
5005
- const { editor } = useTiptapEditor(providedEditor);
5006
- const [isVisible, setIsVisible] = (0, import_react43.useState)(true);
5260
+ const { editor } = (0, import_editor_utils9.useTiptapEditor)(providedEditor);
5261
+ const [isVisible, setIsVisible] = (0, import_react41.useState)(true);
5007
5262
  const canToggleState = canToggle(editor);
5008
5263
  const isActive = (editor == null ? void 0 : editor.isActive("table")) || false;
5009
- (0, import_react43.useEffect)(() => {
5264
+ (0, import_react41.useEffect)(() => {
5010
5265
  if (!editor) return;
5011
5266
  const handleSelectionUpdate = () => {
5012
5267
  setIsVisible(shouldShowButton({ editor, hideWhenUnavailable }));
@@ -5017,7 +5272,7 @@ function useTableBlock(config) {
5017
5272
  editor.off("selectionUpdate", handleSelectionUpdate);
5018
5273
  };
5019
5274
  }, [editor, hideWhenUnavailable]);
5020
- const handleToggle = (0, import_react43.useCallback)(() => {
5275
+ const handleToggle = (0, import_react41.useCallback)(() => {
5021
5276
  if (!editor) return false;
5022
5277
  const success = toggleTable(editor);
5023
5278
  if (success) {
@@ -5203,8 +5458,8 @@ var getItemImplementations = () => {
5203
5458
  // AI
5204
5459
  continue_writing: {
5205
5460
  check: (editor) => {
5206
- const { hasContent } = (0, import_editor_utils6.hasContentAbove)(editor);
5207
- const extensionsReady = (0, import_editor_utils6.isExtensionAvailable)(editor, [
5461
+ const { hasContent } = (0, import_editor_utils10.hasContentAbove)(editor);
5462
+ const extensionsReady = (0, import_editor_utils10.isExtensionAvailable)(editor, [
5208
5463
  "ai",
5209
5464
  "aiAdvanced"
5210
5465
  ]);
@@ -5212,14 +5467,14 @@ var getItemImplementations = () => {
5212
5467
  },
5213
5468
  action: ({ editor }) => {
5214
5469
  const editorChain = editor.chain().focus();
5215
- const nodeSelectionPosition = (0, import_editor_utils6.findSelectionPosition)({ editor });
5470
+ const nodeSelectionPosition = (0, import_editor_utils10.findSelectionPosition)({ editor });
5216
5471
  if (nodeSelectionPosition !== null) {
5217
5472
  editorChain.setNodeSelection(nodeSelectionPosition);
5218
5473
  }
5219
5474
  editorChain.run();
5220
5475
  editor.chain().focus().aiGenerationShow().run();
5221
5476
  requestAnimationFrame(() => {
5222
- const { hasContent, content } = (0, import_editor_utils6.hasContentAbove)(editor);
5477
+ const { hasContent, content } = (0, import_editor_utils10.hasContentAbove)(editor);
5223
5478
  const snippet = content.length > 500 ? `...${content.slice(-500)}` : content;
5224
5479
  const prompt = hasContent ? `Context: ${snippet}
5225
5480
 
@@ -5233,10 +5488,10 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
5233
5488
  }
5234
5489
  },
5235
5490
  ai_ask_button: {
5236
- check: (editor) => (0, import_editor_utils6.isExtensionAvailable)(editor, ["ai", "aiAdvanced"]),
5491
+ check: (editor) => (0, import_editor_utils10.isExtensionAvailable)(editor, ["ai", "aiAdvanced"]),
5237
5492
  action: ({ editor }) => {
5238
5493
  const editorChain = editor.chain().focus();
5239
- const nodeSelectionPosition = (0, import_editor_utils6.findSelectionPosition)({ editor });
5494
+ const nodeSelectionPosition = (0, import_editor_utils10.findSelectionPosition)({ editor });
5240
5495
  if (nodeSelectionPosition !== null) {
5241
5496
  editorChain.setNodeSelection(nodeSelectionPosition);
5242
5497
  }
@@ -5246,55 +5501,55 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
5246
5501
  },
5247
5502
  // Style
5248
5503
  text: {
5249
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("paragraph", editor),
5504
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("paragraph", editor),
5250
5505
  action: ({ editor }) => {
5251
5506
  editor.chain().focus().setParagraph().run();
5252
5507
  }
5253
5508
  },
5254
5509
  heading_1: {
5255
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("heading", editor),
5510
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("heading", editor),
5256
5511
  action: ({ editor }) => {
5257
5512
  editor.chain().focus().toggleHeading({ level: 1 }).run();
5258
5513
  }
5259
5514
  },
5260
5515
  heading_2: {
5261
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("heading", editor),
5516
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("heading", editor),
5262
5517
  action: ({ editor }) => {
5263
5518
  editor.chain().focus().toggleHeading({ level: 2 }).run();
5264
5519
  }
5265
5520
  },
5266
5521
  heading_3: {
5267
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("heading", editor),
5522
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("heading", editor),
5268
5523
  action: ({ editor }) => {
5269
5524
  editor.chain().focus().toggleHeading({ level: 3 }).run();
5270
5525
  }
5271
5526
  },
5272
5527
  bullet_list: {
5273
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("bulletList", editor),
5528
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("bulletList", editor),
5274
5529
  action: ({ editor }) => {
5275
5530
  editor.chain().focus().toggleBulletList().run();
5276
5531
  }
5277
5532
  },
5278
5533
  ordered_list: {
5279
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("orderedList", editor),
5534
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("orderedList", editor),
5280
5535
  action: ({ editor }) => {
5281
5536
  editor.chain().focus().toggleOrderedList().run();
5282
5537
  }
5283
5538
  },
5284
5539
  task_list: {
5285
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("taskList", editor),
5540
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("taskList", editor),
5286
5541
  action: ({ editor }) => {
5287
5542
  editor.chain().focus().toggleTaskList().run();
5288
5543
  }
5289
5544
  },
5290
5545
  quote: {
5291
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("blockquote", editor),
5546
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("blockquote", editor),
5292
5547
  action: ({ editor }) => {
5293
5548
  editor.chain().focus().toggleBlockquote().run();
5294
5549
  }
5295
5550
  },
5296
5551
  code_block: {
5297
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("codeBlock", editor),
5552
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("codeBlock", editor),
5298
5553
  action: ({ editor }) => {
5299
5554
  editor.chain().focus().toggleNode("codeBlock", "paragraph").run();
5300
5555
  }
@@ -5311,17 +5566,17 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
5311
5566
  // action: ({ editor }: { editor: Editor }) => addEmojiTrigger(editor),
5312
5567
  // },
5313
5568
  divider: {
5314
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("horizontalRule", editor),
5569
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("horizontalRule", editor),
5315
5570
  action: ({ editor }) => {
5316
5571
  editor.chain().focus().setHorizontalRule().run();
5317
5572
  }
5318
5573
  },
5319
5574
  table: {
5320
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("table", editor),
5575
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("table", editor),
5321
5576
  action: ({ editor }) => toggleTable(editor, { rows: 3, cols: 3, withHeaderRow: true })
5322
5577
  },
5323
5578
  control: {
5324
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("controlBlock", editor),
5579
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("controlBlock", editor),
5325
5580
  action: ({ editor }) => {
5326
5581
  try {
5327
5582
  return editor.chain().focus().insertControlBlock().run();
@@ -5331,32 +5586,32 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
5331
5586
  }
5332
5587
  },
5333
5588
  table_of_contents: {
5334
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("tableOfContentsNode", editor),
5589
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("tableOfContentsNode", editor),
5335
5590
  action: ({ editor }) => {
5336
5591
  editor.chain().focus().insertTableOfContents().run();
5337
5592
  }
5338
5593
  },
5339
5594
  callout: {
5340
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("calloutNode", editor),
5595
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("calloutNode", editor),
5341
5596
  action: ({ editor }) => {
5342
5597
  editor.chain().focus().insertCallout("info").run();
5343
5598
  }
5344
5599
  },
5345
5600
  callout_warning: {
5346
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("calloutNode", editor),
5601
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("calloutNode", editor),
5347
5602
  action: ({ editor }) => {
5348
5603
  editor.chain().focus().insertCallout("warning").run();
5349
5604
  }
5350
5605
  },
5351
5606
  math: {
5352
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("mathBlock", editor),
5607
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("mathBlock", editor),
5353
5608
  action: ({ editor }) => {
5354
5609
  editor.chain().focus().insertMathBlock().run();
5355
5610
  }
5356
5611
  },
5357
5612
  // Upload
5358
5613
  image: {
5359
- check: (editor) => (0, import_editor_utils6.isNodeInSchema)("imageUpload", editor),
5614
+ check: (editor) => (0, import_editor_utils10.isNodeInSchema)("imageUpload", editor),
5360
5615
  action: ({ editor }) => {
5361
5616
  editor.chain().focus().setImageUpload().run();
5362
5617
  }
@@ -5445,7 +5700,7 @@ var Item = (props) => {
5445
5700
  '[data-selector="tiptap-slash-dropdown-menu"]'
5446
5701
  );
5447
5702
  if (!itemRef.current || !isSelected || !selector) return;
5448
- const overflow = (0, import_editor_utils7.getElementOverflowPosition)(itemRef.current, selector);
5703
+ const overflow = (0, import_editor_utils11.getElementOverflowPosition)(itemRef.current, selector);
5449
5704
  if (overflow === "top") {
5450
5705
  itemRef.current.scrollIntoView(true);
5451
5706
  } else if (overflow === "bottom") {
@@ -5563,11 +5818,12 @@ var List = ({
5563
5818
  };
5564
5819
 
5565
5820
  // src/presets/basic/editor-header.tsx
5566
- var import_icons25 = require("@kopexa/icons");
5821
+ var import_editor_utils31 = require("@kopexa/editor-utils");
5822
+ var import_icons26 = require("@kopexa/icons");
5567
5823
  var import_popover3 = require("@kopexa/popover");
5568
5824
  var import_toolbar10 = require("@kopexa/toolbar");
5569
- var import_use_is_mobile2 = require("@kopexa/use-is-mobile");
5570
- var import_react58 = require("react");
5825
+ var import_use_is_mobile3 = require("@kopexa/use-is-mobile");
5826
+ var import_react59 = require("react");
5571
5827
 
5572
5828
  // src/hooks/use-cursor-visibility.ts
5573
5829
  var React13 = __toESM(require("react"));
@@ -5671,94 +5927,122 @@ function useCursorVisibility({
5671
5927
  return rect;
5672
5928
  }
5673
5929
 
5674
- // src/ui/blockquote-button/blockquote-button.tsx
5930
+ // src/ui/color-highlight-popover/color-highlight-popover.tsx
5931
+ var import_button11 = require("@kopexa/button");
5932
+ var import_editor_utils14 = require("@kopexa/editor-utils");
5933
+ var import_icons15 = require("@kopexa/icons");
5934
+ var import_popover2 = require("@kopexa/popover");
5935
+ var import_toolbar5 = require("@kopexa/toolbar");
5936
+ var import_react43 = require("react");
5937
+
5938
+ // src/ui/color-highlight-button/color-highlight-button.tsx
5939
+ var import_editor_utils13 = require("@kopexa/editor-utils");
5940
+ var import_theme8 = require("@kopexa/theme");
5675
5941
  var import_toolbar4 = require("@kopexa/toolbar");
5676
- var React15 = __toESM(require("react"));
5942
+ var import_react42 = require("react");
5677
5943
 
5678
- // src/ui/blockquote-button/use-blockquote.ts
5679
- var import_editor_utils8 = require("@kopexa/editor-utils");
5944
+ // src/ui/color-highlight-button/use-color-highlight.ts
5945
+ var import_editor_utils12 = require("@kopexa/editor-utils");
5680
5946
  var import_icons14 = require("@kopexa/icons");
5681
- var import_state7 = require("@tiptap/pm/state");
5947
+ var import_use_is_mobile = require("@kopexa/use-is-mobile");
5682
5948
  var React14 = __toESM(require("react"));
5683
- var BLOCKQUOTE_SHORTCUT_KEY = "mod+shift+b";
5684
- function canToggleBlockquote(editor, turnInto = true) {
5685
- var _a;
5686
- if (!editor || !editor.isEditable) return false;
5687
- if (!(0, import_editor_utils8.isNodeInSchema)("blockquote", editor) || (0, import_editor_utils8.isNodeTypeSelected)(editor, ["image"]))
5688
- return false;
5689
- if (!turnInto) {
5690
- return editor.can().toggleWrap("blockquote");
5691
- }
5692
- try {
5693
- const view = editor.view;
5694
- const state = view.state;
5695
- const selection = state.selection;
5696
- if (selection.empty || selection instanceof import_state7.TextSelection) {
5697
- const pos = (_a = (0, import_editor_utils8.findNodePosition)({
5698
- editor,
5699
- node: state.selection.$anchor.node(1)
5700
- })) == null ? void 0 : _a.pos;
5701
- if (!(0, import_editor_utils8.isValidPosition)(pos)) return false;
5702
- }
5703
- return true;
5704
- } catch {
5705
- return false;
5949
+ var import_react_hotkeys_hook = require("react-hotkeys-hook");
5950
+ var COLOR_HIGHLIGHT_SHORTCUT_KEY = "mod+shift+h";
5951
+ var HIGHLIGHT_COLORS = [
5952
+ {
5953
+ label: "Default background",
5954
+ value: "var(--tt-bg-color)",
5955
+ border: "var(--tt-bg-color-contrast)"
5956
+ },
5957
+ {
5958
+ label: "Gray background",
5959
+ value: "var(--tt-color-highlight-gray)",
5960
+ border: "var(--tt-color-highlight-gray-contrast)"
5961
+ },
5962
+ {
5963
+ label: "Brown background",
5964
+ value: "var(--tt-color-highlight-brown)",
5965
+ border: "var(--tt-color-highlight-brown-contrast)"
5966
+ },
5967
+ {
5968
+ label: "Orange background",
5969
+ value: "var(--tt-color-highlight-orange)",
5970
+ border: "var(--tt-color-highlight-orange-contrast)"
5971
+ },
5972
+ {
5973
+ label: "Yellow background",
5974
+ value: "var(--tt-color-highlight-yellow)",
5975
+ border: "var(--tt-color-highlight-yellow-contrast)"
5976
+ },
5977
+ {
5978
+ label: "Green background",
5979
+ value: "var(--tt-color-highlight-green)",
5980
+ border: "var(--tt-color-highlight-green-contrast)"
5981
+ },
5982
+ {
5983
+ label: "Blue background",
5984
+ value: "var(--tt-color-highlight-blue)",
5985
+ border: "var(--tt-color-highlight-blue-contrast)"
5986
+ },
5987
+ {
5988
+ label: "Purple background",
5989
+ value: "var(--tt-color-highlight-purple)",
5990
+ border: "var(--tt-color-highlight-purple-contrast)"
5991
+ },
5992
+ {
5993
+ label: "Pink background",
5994
+ value: "var(--tt-color-highlight-pink)",
5995
+ border: "var(--tt-color-highlight-pink-contrast)"
5996
+ },
5997
+ {
5998
+ label: "Red background",
5999
+ value: "var(--tt-color-highlight-red)",
6000
+ border: "var(--tt-color-highlight-red-contrast)"
5706
6001
  }
6002
+ ];
6003
+ function pickHighlightColorsByValue(values) {
6004
+ const colorMap = new Map(
6005
+ HIGHLIGHT_COLORS.map((color) => [color.value, color])
6006
+ );
6007
+ return values.map((value) => colorMap.get(value)).filter((color) => !!color);
5707
6008
  }
5708
- function toggleBlockquote(editor) {
5709
- var _a, _b, _c;
6009
+ function canColorHighlight(editor) {
5710
6010
  if (!editor || !editor.isEditable) return false;
5711
- if (!canToggleBlockquote(editor)) return false;
5712
- try {
5713
- const view = editor.view;
5714
- let state = view.state;
5715
- let tr = state.tr;
5716
- if (state.selection.empty || state.selection instanceof import_state7.TextSelection) {
5717
- const pos = (_a = (0, import_editor_utils8.findNodePosition)({
5718
- editor,
5719
- node: state.selection.$anchor.node(1)
5720
- })) == null ? void 0 : _a.pos;
5721
- if (!(0, import_editor_utils8.isValidPosition)(pos)) return false;
5722
- tr = tr.setSelection(import_state7.NodeSelection.create(state.doc, pos));
5723
- view.dispatch(tr);
5724
- state = view.state;
5725
- }
5726
- const selection = state.selection;
5727
- let chain = editor.chain().focus();
5728
- if (selection instanceof import_state7.NodeSelection) {
5729
- const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
5730
- const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
5731
- const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
5732
- const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
5733
- chain = chain.setTextSelection({ from, to }).clearNodes();
5734
- }
5735
- const toggle = editor.isActive("blockquote") ? chain.lift("blockquote") : chain.wrapIn("blockquote");
5736
- toggle.run();
5737
- editor.chain().focus().selectTextblockEnd().run();
5738
- return true;
5739
- } catch {
6011
+ if (!(0, import_editor_utils12.isMarkInSchema)("highlight", editor) || (0, import_editor_utils12.isNodeTypeSelected)(editor, ["image"]))
5740
6012
  return false;
5741
- }
6013
+ return editor.can().setMark("highlight");
6014
+ }
6015
+ function isColorHighlightActive(editor, highlightColor) {
6016
+ if (!editor || !editor.isEditable) return false;
6017
+ return highlightColor ? editor.isActive("highlight", { color: highlightColor }) : editor.isActive("highlight");
6018
+ }
6019
+ function removeHighlight(editor) {
6020
+ if (!editor || !editor.isEditable) return false;
6021
+ if (!canColorHighlight(editor)) return false;
6022
+ return editor.chain().focus().unsetMark("highlight").run();
5742
6023
  }
5743
6024
  function shouldShowButton2(props) {
5744
6025
  const { editor, hideWhenUnavailable } = props;
5745
6026
  if (!editor || !editor.isEditable) return false;
5746
- if (!(0, import_editor_utils8.isNodeInSchema)("blockquote", editor)) return false;
6027
+ if (!(0, import_editor_utils12.isMarkInSchema)("highlight", editor)) return false;
5747
6028
  if (hideWhenUnavailable && !editor.isActive("code")) {
5748
- return canToggleBlockquote(editor);
6029
+ return canColorHighlight(editor);
5749
6030
  }
5750
6031
  return true;
5751
6032
  }
5752
- function useBlockquote(config) {
6033
+ function useColorHighlight(config) {
5753
6034
  const {
5754
6035
  editor: providedEditor,
6036
+ label,
6037
+ highlightColor,
5755
6038
  hideWhenUnavailable = false,
5756
- onToggled
5757
- } = config || {};
5758
- const { editor } = useTiptapEditor(providedEditor);
6039
+ onApplied
6040
+ } = config;
6041
+ const { editor } = (0, import_editor_utils12.useTiptapEditor)(providedEditor);
6042
+ const isMobile = (0, import_use_is_mobile.useIsMobile)();
5759
6043
  const [isVisible, setIsVisible] = React14.useState(true);
5760
- const canToggle3 = canToggleBlockquote(editor);
5761
- const isActive = (editor == null ? void 0 : editor.isActive("blockquote")) || false;
6044
+ const canColorHighlightState = canColorHighlight(editor);
6045
+ const isActive = isColorHighlightActive(editor, highlightColor);
5762
6046
  React14.useEffect(() => {
5763
6047
  if (!editor) return;
5764
6048
  const handleSelectionUpdate = () => {
@@ -5770,372 +6054,885 @@ function useBlockquote(config) {
5770
6054
  editor.off("selectionUpdate", handleSelectionUpdate);
5771
6055
  };
5772
6056
  }, [editor, hideWhenUnavailable]);
5773
- const handleToggle = React14.useCallback(() => {
5774
- if (!editor) return false;
5775
- const success = toggleBlockquote(editor);
6057
+ const handleColorHighlight = React14.useCallback(() => {
6058
+ if (!editor || !canColorHighlightState || !highlightColor || !label)
6059
+ return false;
6060
+ if (editor.state.storedMarks) {
6061
+ const highlightMarkType = editor.schema.marks.highlight;
6062
+ if (highlightMarkType) {
6063
+ editor.view.dispatch(
6064
+ editor.state.tr.removeStoredMark(highlightMarkType)
6065
+ );
6066
+ }
6067
+ }
6068
+ setTimeout(() => {
6069
+ const success = editor.chain().focus().toggleMark("highlight", { color: highlightColor }).run();
6070
+ if (success) {
6071
+ onApplied == null ? void 0 : onApplied({ color: highlightColor, label });
6072
+ }
6073
+ return success;
6074
+ }, 0);
6075
+ }, [canColorHighlightState, highlightColor, editor, label, onApplied]);
6076
+ const handleRemoveHighlight = React14.useCallback(() => {
6077
+ const success = removeHighlight(editor);
5776
6078
  if (success) {
5777
- onToggled == null ? void 0 : onToggled();
6079
+ onApplied == null ? void 0 : onApplied({ color: "", label: "Remove highlight" });
5778
6080
  }
5779
6081
  return success;
5780
- }, [editor, onToggled]);
6082
+ }, [editor, onApplied]);
6083
+ (0, import_react_hotkeys_hook.useHotkeys)(
6084
+ COLOR_HIGHLIGHT_SHORTCUT_KEY,
6085
+ (event) => {
6086
+ event.preventDefault();
6087
+ handleColorHighlight();
6088
+ },
6089
+ {
6090
+ enabled: isVisible && canColorHighlightState,
6091
+ enableOnContentEditable: !isMobile,
6092
+ enableOnFormTags: true
6093
+ }
6094
+ );
5781
6095
  return {
5782
6096
  isVisible,
5783
6097
  isActive,
5784
- handleToggle,
5785
- canToggle: canToggle3,
5786
- label: "Blockquote",
5787
- shortcutKeys: BLOCKQUOTE_SHORTCUT_KEY,
5788
- Icon: import_icons14.BlockquoteIcon
6098
+ handleColorHighlight,
6099
+ handleRemoveHighlight,
6100
+ canColorHighlight: canColorHighlightState,
6101
+ label: label || `Highlight`,
6102
+ shortcutKeys: COLOR_HIGHLIGHT_SHORTCUT_KEY,
6103
+ Icon: import_icons14.HighlighterIcon
5789
6104
  };
5790
6105
  }
5791
6106
 
5792
- // src/ui/blockquote-button/blockquote-button.tsx
6107
+ // src/ui/color-highlight-button/color-highlight-button.tsx
5793
6108
  var import_jsx_runtime21 = require("react/jsx-runtime");
5794
- var BlockquoteButton = ({
6109
+ var ColorHighlightButton = ({
5795
6110
  editor: providedEditor,
6111
+ highlightColor,
5796
6112
  text,
5797
6113
  hideWhenUnavailable = false,
5798
- onToggled,
6114
+ onApplied,
5799
6115
  showShortcut = false,
5800
6116
  onClick,
5801
6117
  children,
6118
+ style,
6119
+ className,
5802
6120
  ...buttonProps
5803
6121
  }) => {
5804
- const { editor } = useTiptapEditor(providedEditor);
6122
+ const { editor } = (0, import_editor_utils13.useTiptapEditor)(providedEditor);
5805
6123
  const {
5806
6124
  isVisible,
5807
- canToggle: canToggle3,
6125
+ canColorHighlight: canColorHighlight2,
5808
6126
  isActive,
5809
- handleToggle,
6127
+ handleColorHighlight,
5810
6128
  label,
5811
- shortcutKeys,
5812
- Icon
5813
- } = useBlockquote({
6129
+ shortcutKeys
6130
+ } = useColorHighlight({
5814
6131
  editor,
6132
+ highlightColor,
6133
+ label: text || `Toggle highlight (${highlightColor})`,
5815
6134
  hideWhenUnavailable,
5816
- onToggled
6135
+ onApplied
5817
6136
  });
5818
- const handleClick = React15.useCallback(
6137
+ const handleClick = (0, import_react42.useCallback)(
5819
6138
  (event) => {
5820
6139
  onClick == null ? void 0 : onClick(event);
5821
6140
  if (event.defaultPrevented) return;
5822
- handleToggle();
6141
+ handleColorHighlight();
5823
6142
  },
5824
- [handleToggle, onClick]
6143
+ [handleColorHighlight, onClick]
6144
+ );
6145
+ const buttonStyle = (0, import_react42.useMemo)(
6146
+ () => ({
6147
+ ...style,
6148
+ "--highlight-color": highlightColor
6149
+ }),
6150
+ [highlightColor, style]
5825
6151
  );
5826
6152
  if (!isVisible) {
5827
6153
  return null;
5828
6154
  }
5829
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6155
+ const styles = (0, import_theme8.colorHighlightButton)();
6156
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5830
6157
  import_toolbar4.ToolbarButton,
5831
6158
  {
5832
6159
  type: "button",
6160
+ disabled: !canColorHighlight2,
6161
+ "data-disabled": !canColorHighlight2,
5833
6162
  variant: "ghost",
5834
6163
  color: "default",
5835
- disabled: !canToggle3,
5836
- "data-disabled": !canToggle3,
5837
6164
  "data-active-state": isActive ? "on" : "off",
5838
6165
  tabIndex: -1,
5839
- "aria-label": "blockquote",
5840
- "aria-pressed": isActive,
5841
- title: label,
6166
+ "aria-label": label,
5842
6167
  shortcutKeys,
6168
+ "aria-pressed": isActive,
5843
6169
  onClick: handleClick,
5844
- isIconOnly: !text && !children,
6170
+ style: buttonStyle,
6171
+ className: styles.button({ className }),
6172
+ isIconOnly: true,
5845
6173
  ...buttonProps,
5846
- children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5847
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, {}),
5848
- text && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: text })
5849
- ] })
6174
+ children: [
6175
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6176
+ "span",
6177
+ {
6178
+ "data-active-state": isActive ? "on" : "off",
6179
+ className: styles.mark()
6180
+ }
6181
+ ),
6182
+ children || /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
6183
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6184
+ "span",
6185
+ {
6186
+ style: { "--highlight-color": highlightColor }
6187
+ }
6188
+ ),
6189
+ text
6190
+ ] })
6191
+ ]
5850
6192
  }
5851
6193
  );
5852
6194
  };
5853
6195
 
5854
- // src/ui/codeblock-button/code-block-button.tsx
5855
- var import_icons16 = require("@kopexa/icons");
5856
- var import_toolbar5 = require("@kopexa/toolbar");
5857
- var import_react44 = require("react");
5858
-
5859
- // src/ui/codeblock-button/use-code-block.ts
5860
- var import_editor_utils9 = require("@kopexa/editor-utils");
5861
- var import_icons15 = require("@kopexa/icons");
5862
- var import_state8 = require("@tiptap/pm/state");
5863
- var React16 = __toESM(require("react"));
5864
- var CODE_BLOCK_SHORTCUT_KEY = "mod+alt+c";
5865
- function canToggle2(editor, turnInto = true) {
5866
- var _a;
5867
- if (!editor || !editor.isEditable) return false;
5868
- if (!(0, import_editor_utils9.isNodeInSchema)("codeBlock", editor) || (0, import_editor_utils9.isNodeTypeSelected)(editor, ["image"]))
5869
- return false;
5870
- if (!turnInto) {
5871
- return editor.can().toggleNode("codeBlock", "paragraph");
5872
- }
5873
- try {
5874
- const view = editor.view;
5875
- const state = view.state;
5876
- const selection = state.selection;
5877
- if (selection.empty || selection instanceof import_state8.TextSelection) {
5878
- const pos = (_a = (0, import_editor_utils9.findNodePosition)({
5879
- editor,
5880
- node: state.selection.$anchor.node(1)
5881
- })) == null ? void 0 : _a.pos;
5882
- if (!(0, import_editor_utils9.isValidPosition)(pos)) return false;
5883
- }
5884
- return true;
5885
- } catch {
5886
- return false;
5887
- }
5888
- }
5889
- function toggleCodeBlock(editor) {
5890
- var _a, _b, _c;
5891
- if (!editor || !editor.isEditable) return false;
5892
- if (!canToggle2(editor)) return false;
5893
- try {
5894
- const view = editor.view;
5895
- let state = view.state;
5896
- let tr = state.tr;
5897
- if (state.selection.empty || state.selection instanceof import_state8.TextSelection) {
5898
- const pos = (_a = (0, import_editor_utils9.findNodePosition)({
5899
- editor,
5900
- node: state.selection.$anchor.node(1)
5901
- })) == null ? void 0 : _a.pos;
5902
- if (!(0, import_editor_utils9.isValidPosition)(pos)) return false;
5903
- tr = tr.setSelection(import_state8.NodeSelection.create(state.doc, pos));
5904
- view.dispatch(tr);
5905
- state = view.state;
5906
- }
5907
- const selection = state.selection;
5908
- let chain = editor.chain().focus();
5909
- if (selection instanceof import_state8.NodeSelection) {
5910
- const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
5911
- const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
5912
- const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
5913
- const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
5914
- chain = chain.setTextSelection({ from, to }).clearNodes();
5915
- }
5916
- const toggle = editor.isActive("codeBlock") ? chain.setNode("paragraph") : chain.toggleNode("codeBlock", "paragraph");
5917
- toggle.run();
5918
- editor.chain().focus().selectTextblockEnd().run();
5919
- return true;
5920
- } catch {
5921
- return false;
5922
- }
5923
- }
5924
- function shouldShowButton3(props) {
5925
- const { editor, hideWhenUnavailable } = props;
5926
- if (!editor || !editor.isEditable) return false;
5927
- if (!(0, import_editor_utils9.isNodeInSchema)("codeBlock", editor)) return false;
5928
- if (hideWhenUnavailable && !editor.isActive("code")) {
5929
- return canToggle2(editor);
6196
+ // src/ui/color-highlight-popover/color-highlight-popover.tsx
6197
+ var import_jsx_runtime22 = require("react/jsx-runtime");
6198
+ var ColorHighlightPopoverButton = ({
6199
+ className,
6200
+ children,
6201
+ ...props
6202
+ }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6203
+ import_button11.IconButton,
6204
+ {
6205
+ type: "button",
6206
+ className,
6207
+ variant: "ghost",
6208
+ color: "default",
6209
+ tabIndex: -1,
6210
+ "aria-label": "Highlight text",
6211
+ tooltip: "Highlight",
6212
+ isIconOnly: !children,
6213
+ ...props,
6214
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons15.HighlighterIcon, {})
5930
6215
  }
5931
- return true;
5932
- }
5933
- function useCodeBlock(config) {
5934
- const {
5935
- editor: providedEditor,
5936
- hideWhenUnavailable = false,
6216
+ );
6217
+ function ColorHighlightPopoverContent({
6218
+ editor,
6219
+ colors = pickHighlightColorsByValue([
6220
+ "var(--tt-color-highlight-green)",
6221
+ "var(--tt-color-highlight-blue)",
6222
+ "var(--tt-color-highlight-red)",
6223
+ "var(--tt-color-highlight-purple)",
6224
+ "var(--tt-color-highlight-yellow)"
6225
+ ])
6226
+ }) {
6227
+ const { handleRemoveHighlight } = useColorHighlight({ editor });
6228
+ const containerRef = (0, import_react43.useRef)(null);
6229
+ const menuItems = (0, import_react43.useMemo)(
6230
+ () => [...colors, { label: "Remove highlight", value: "none" }],
6231
+ [colors]
6232
+ );
6233
+ const { selectedIndex } = useMenuNavigation({
6234
+ containerRef,
6235
+ items: menuItems,
6236
+ orientation: "both",
6237
+ onSelect: (item) => {
6238
+ if (!containerRef.current) return false;
6239
+ const highlightedElement = containerRef.current.querySelector(
6240
+ '[data-highlighted="true"]'
6241
+ );
6242
+ if (highlightedElement) highlightedElement.click();
6243
+ if (item.value === "none") handleRemoveHighlight();
6244
+ },
6245
+ autoSelectFirstItem: false
6246
+ });
6247
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { ref: containerRef, className: "flex gap-1 items-center", children: [
6248
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6249
+ "div",
6250
+ {
6251
+ className: "flex items-center gap-1 outline-none",
6252
+ "data-orientation": "horizontal",
6253
+ children: colors.map((color, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6254
+ ColorHighlightButton,
6255
+ {
6256
+ editor,
6257
+ highlightColor: color.value,
6258
+ "aria-label": `${color.label} highlight color`,
6259
+ tabIndex: index === selectedIndex ? 0 : -1,
6260
+ "data-highlighted": selectedIndex === index
6261
+ },
6262
+ color.value
6263
+ ))
6264
+ }
6265
+ ),
6266
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_toolbar5.ToolbarSeparator, { orientation: "vertical" }),
6267
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "tiptap-button-group", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6268
+ import_button11.IconButton,
6269
+ {
6270
+ onClick: handleRemoveHighlight,
6271
+ "aria-label": "Remove highlight",
6272
+ tabIndex: selectedIndex === colors.length ? 0 : -1,
6273
+ type: "button",
6274
+ role: "menuitem",
6275
+ variant: "ghost",
6276
+ color: "default",
6277
+ "data-highlighted": selectedIndex === colors.length,
6278
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons15.BanIcon, {})
6279
+ }
6280
+ ) })
6281
+ ] });
6282
+ }
6283
+ function ColorHighlightPopover({
6284
+ editor: providedEditor,
6285
+ colors = pickHighlightColorsByValue([
6286
+ "var(--tt-color-highlight-green)",
6287
+ "var(--tt-color-highlight-blue)",
6288
+ "var(--tt-color-highlight-red)",
6289
+ "var(--tt-color-highlight-purple)",
6290
+ "var(--tt-color-highlight-yellow)"
6291
+ ]),
6292
+ hideWhenUnavailable = false,
6293
+ onApplied,
6294
+ ...props
6295
+ }) {
6296
+ const { editor } = (0, import_editor_utils14.useTiptapEditor)(providedEditor);
6297
+ const [isOpen, setIsOpen] = (0, import_react43.useState)(false);
6298
+ const { isVisible, canColorHighlight: canColorHighlight2, isActive, label } = useColorHighlight({
6299
+ editor,
6300
+ hideWhenUnavailable,
6301
+ onApplied
6302
+ });
6303
+ if (!isVisible) return null;
6304
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_popover2.Popover.Root, { open: isOpen, onOpenChange: setIsOpen, spacing: "dense", children: [
6305
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6306
+ import_popover2.Popover.Trigger,
6307
+ {
6308
+ render: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6309
+ ColorHighlightPopoverButton,
6310
+ {
6311
+ disabled: !canColorHighlight2,
6312
+ "data-disabled": !canColorHighlight2,
6313
+ "data-active-state": isActive ? "on" : "off",
6314
+ "aria-pressed": isActive,
6315
+ "aria-label": label,
6316
+ title: label,
6317
+ ...props
6318
+ }
6319
+ )
6320
+ }
6321
+ ),
6322
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_popover2.Popover.Content, { "aria-label": "Highlight colors", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ColorHighlightPopoverContent, { editor, colors }) })
6323
+ ] });
6324
+ }
6325
+
6326
+ // src/ui/list-dropdown-menu/index.tsx
6327
+ var import_button13 = require("@kopexa/button");
6328
+ var import_dropdown_menu = require("@kopexa/dropdown-menu");
6329
+ var import_editor_utils16 = require("@kopexa/editor-utils");
6330
+ var import_icons17 = require("@kopexa/icons");
6331
+ var import_react46 = require("@tiptap/react");
6332
+ var import_react47 = require("react");
6333
+
6334
+ // src/ui/list-button/index.tsx
6335
+ var import_button12 = require("@kopexa/button");
6336
+ var import_editor_utils15 = require("@kopexa/editor-utils");
6337
+ var import_icons16 = require("@kopexa/icons");
6338
+ var import_react44 = require("@tiptap/react");
6339
+ var import_react45 = require("react");
6340
+ var import_jsx_runtime23 = require("react/jsx-runtime");
6341
+ var listOptions = [
6342
+ {
6343
+ label: "Bullet List",
6344
+ type: "bulletList",
6345
+ icon: import_icons16.ListIcon
6346
+ },
6347
+ {
6348
+ label: "Ordered List",
6349
+ type: "orderedList",
6350
+ icon: import_icons16.ListOrderedIcon
6351
+ },
6352
+ {
6353
+ label: "Task List",
6354
+ type: "taskList",
6355
+ icon: import_icons16.ListTodoIcon
6356
+ }
6357
+ ];
6358
+ var listShortcutKeys = {
6359
+ bulletList: "Ctrl-Shift-8",
6360
+ orderedList: "Ctrl-Shift-7",
6361
+ taskList: "Ctrl-Shift-9"
6362
+ };
6363
+ function canToggleList(editor, type) {
6364
+ if (!editor) {
6365
+ return false;
6366
+ }
6367
+ switch (type) {
6368
+ case "bulletList":
6369
+ return editor.can().toggleBulletList();
6370
+ case "orderedList":
6371
+ return editor.can().toggleOrderedList();
6372
+ case "taskList":
6373
+ return editor.can().toggleList("taskList", "taskItem");
6374
+ default:
6375
+ return false;
6376
+ }
6377
+ }
6378
+ function isListActive(editor, type) {
6379
+ if (!editor) return false;
6380
+ switch (type) {
6381
+ case "bulletList":
6382
+ return editor.isActive("bulletList");
6383
+ case "orderedList":
6384
+ return editor.isActive("orderedList");
6385
+ case "taskList":
6386
+ return editor.isActive("taskList");
6387
+ default:
6388
+ return false;
6389
+ }
6390
+ }
6391
+ function toggleList(editor, type) {
6392
+ if (!editor) return;
6393
+ switch (type) {
6394
+ case "bulletList":
6395
+ editor.chain().focus().toggleBulletList().run();
6396
+ break;
6397
+ case "orderedList":
6398
+ editor.chain().focus().toggleOrderedList().run();
6399
+ break;
6400
+ case "taskList":
6401
+ editor.chain().focus().toggleList("taskList", "taskItem").run();
6402
+ break;
6403
+ }
6404
+ }
6405
+ function getListOption(type) {
6406
+ return listOptions.find((option) => option.type === type);
6407
+ }
6408
+ function shouldShowListButton(params) {
6409
+ const { editor, type, hideWhenUnavailable, listInSchema } = params;
6410
+ if (!listInSchema || !editor) {
6411
+ return false;
6412
+ }
6413
+ if (hideWhenUnavailable) {
6414
+ if ((0, import_react44.isNodeSelection)(editor.state.selection) || !canToggleList(editor, type)) {
6415
+ return false;
6416
+ }
6417
+ }
6418
+ return true;
6419
+ }
6420
+ function useListState(editor, type) {
6421
+ const listInSchema = (0, import_editor_utils15.isNodeInSchema)(type, editor);
6422
+ const listOption = getListOption(type);
6423
+ const isActive = isListActive(editor, type);
6424
+ const shortcutKey = listShortcutKeys[type];
6425
+ return {
6426
+ listInSchema,
6427
+ listOption,
6428
+ isActive,
6429
+ shortcutKey
6430
+ };
6431
+ }
6432
+ var ListButton = ({
6433
+ editor: providedEditor,
6434
+ type,
6435
+ hideWhenUnavailable = false,
6436
+ className = "",
6437
+ onClick,
6438
+ text,
6439
+ children,
6440
+ ref,
6441
+ ...buttonProps
6442
+ }) => {
6443
+ const { editor } = (0, import_editor_utils15.useTiptapEditor)(providedEditor);
6444
+ const { listInSchema, listOption, isActive, shortcutKey } = useListState(
6445
+ editor,
6446
+ type
6447
+ );
6448
+ const Icon = (listOption == null ? void 0 : listOption.icon) || import_icons16.ListIcon;
6449
+ const handleClick = (0, import_react45.useCallback)(
6450
+ (e) => {
6451
+ onClick == null ? void 0 : onClick(e);
6452
+ if (!e.defaultPrevented && editor) {
6453
+ toggleList(editor, type);
6454
+ }
6455
+ },
6456
+ [onClick, editor, type]
6457
+ );
6458
+ const show = (0, import_react45.useMemo)(() => {
6459
+ return shouldShowListButton({
6460
+ editor,
6461
+ type,
6462
+ hideWhenUnavailable,
6463
+ listInSchema
6464
+ });
6465
+ }, [editor, type, hideWhenUnavailable, listInSchema]);
6466
+ if (!show || !editor || !editor.isEditable) {
6467
+ return null;
6468
+ }
6469
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6470
+ import_button12.Button,
6471
+ {
6472
+ type: "button",
6473
+ className: className.trim(),
6474
+ variant: "ghost",
6475
+ color: "default",
6476
+ "data-active-state": isActive ? "on" : "off",
6477
+ tabIndex: -1,
6478
+ "aria-label": (listOption == null ? void 0 : listOption.label) || type,
6479
+ "aria-pressed": isActive,
6480
+ tooltip: (listOption == null ? void 0 : listOption.label) || type,
6481
+ shortcutKeys: shortcutKey,
6482
+ onClick: handleClick,
6483
+ startContent: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, {}),
6484
+ ...buttonProps,
6485
+ ref,
6486
+ children: children || text
6487
+ }
6488
+ );
6489
+ };
6490
+
6491
+ // src/ui/list-dropdown-menu/index.tsx
6492
+ var import_jsx_runtime24 = require("react/jsx-runtime");
6493
+ function canToggleAnyList(editor, listTypes) {
6494
+ if (!editor) return false;
6495
+ return listTypes.some((type) => canToggleList(editor, type));
6496
+ }
6497
+ function isAnyListActive(editor, listTypes) {
6498
+ if (!editor) return false;
6499
+ return listTypes.some((type) => isListActive(editor, type));
6500
+ }
6501
+ function getFilteredListOptions(availableTypes) {
6502
+ return listOptions.filter(
6503
+ (option) => !option.type || availableTypes.includes(option.type)
6504
+ );
6505
+ }
6506
+ function shouldShowListDropdown(params) {
6507
+ const { editor, hideWhenUnavailable, listInSchema, canToggleAny } = params;
6508
+ if (!listInSchema || !editor) {
6509
+ return false;
6510
+ }
6511
+ if (hideWhenUnavailable) {
6512
+ if ((0, import_react46.isNodeSelection)(editor.state.selection) || !canToggleAny) {
6513
+ return false;
6514
+ }
6515
+ }
6516
+ return true;
6517
+ }
6518
+ function useListDropdownState(editor, availableTypes) {
6519
+ const [isOpen, setIsOpen] = (0, import_react47.useState)(false);
6520
+ const listInSchema = availableTypes.some(
6521
+ (type) => (0, import_editor_utils16.isNodeInSchema)(type, editor)
6522
+ );
6523
+ const filteredLists = (0, import_react47.useMemo)(
6524
+ () => getFilteredListOptions(availableTypes),
6525
+ [availableTypes]
6526
+ );
6527
+ const canToggleAny = canToggleAnyList(editor, availableTypes);
6528
+ const isAnyActive = isAnyListActive(editor, availableTypes);
6529
+ const handleOpenChange = (0, import_react47.useCallback)(
6530
+ (open, callback) => {
6531
+ setIsOpen(open);
6532
+ callback == null ? void 0 : callback(open);
6533
+ },
6534
+ []
6535
+ );
6536
+ return {
6537
+ isOpen,
6538
+ setIsOpen,
6539
+ listInSchema,
6540
+ filteredLists,
6541
+ canToggleAny,
6542
+ isAnyActive,
6543
+ handleOpenChange
6544
+ };
6545
+ }
6546
+ function useActiveListIcon(editor, filteredLists) {
6547
+ return (0, import_react47.useCallback)(() => {
6548
+ const activeOption = filteredLists.find(
6549
+ (option) => isListActive(editor, option.type)
6550
+ );
6551
+ return activeOption ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(activeOption.icon, {}) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_icons17.ListIcon, {});
6552
+ }, [editor, filteredLists]);
6553
+ }
6554
+ function ListDropdownMenu({
6555
+ editor: providedEditor,
6556
+ types = ["bulletList", "orderedList", "taskList"],
6557
+ hideWhenUnavailable = false,
6558
+ onOpenChange,
6559
+ ...props
6560
+ }) {
6561
+ const { editor } = (0, import_editor_utils16.useTiptapEditor)(providedEditor);
6562
+ const {
6563
+ isOpen,
6564
+ listInSchema,
6565
+ filteredLists,
6566
+ canToggleAny,
6567
+ isAnyActive,
6568
+ handleOpenChange
6569
+ } = useListDropdownState(editor, types);
6570
+ const getActiveIcon = useActiveListIcon(editor, filteredLists);
6571
+ const show = (0, import_react47.useMemo)(() => {
6572
+ return shouldShowListDropdown({
6573
+ editor,
6574
+ listTypes: types,
6575
+ hideWhenUnavailable,
6576
+ listInSchema,
6577
+ canToggleAny
6578
+ });
6579
+ }, [editor, types, hideWhenUnavailable, listInSchema, canToggleAny]);
6580
+ const handleOnOpenChange = (0, import_react47.useCallback)(
6581
+ (open) => handleOpenChange(open, onOpenChange),
6582
+ [handleOpenChange, onOpenChange]
6583
+ );
6584
+ if (!show || !editor || !editor.isEditable) {
6585
+ return null;
6586
+ }
6587
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_dropdown_menu.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
6588
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_dropdown_menu.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6589
+ import_button13.Button,
6590
+ {
6591
+ type: "button",
6592
+ variant: "ghost",
6593
+ color: "default",
6594
+ "data-active-state": isAnyActive ? "on" : "off",
6595
+ tabIndex: -1,
6596
+ "aria-label": "List options",
6597
+ tooltip: "List",
6598
+ endContent: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_icons17.ChevronDownIcon, {}),
6599
+ ...props,
6600
+ children: getActiveIcon()
6601
+ }
6602
+ ) }),
6603
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_dropdown_menu.DropdownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_dropdown_menu.DropdownMenu.Group, { children: filteredLists.map((option) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_dropdown_menu.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6604
+ ListButton,
6605
+ {
6606
+ editor,
6607
+ type: option.type,
6608
+ text: option.label,
6609
+ hideWhenUnavailable,
6610
+ tooltip: "",
6611
+ fullWidth: true,
6612
+ spacing: "start"
6613
+ }
6614
+ ) }, option.type)) }) })
6615
+ ] });
6616
+ }
6617
+
6618
+ // src/ui/table-button/index.tsx
6619
+ var import_editor_utils17 = require("@kopexa/editor-utils");
6620
+ var import_toolbar6 = require("@kopexa/toolbar");
6621
+ var import_react48 = require("react");
6622
+ var import_jsx_runtime25 = require("react/jsx-runtime");
6623
+ var TableButton = ({
6624
+ editor: providedEditor,
6625
+ text,
6626
+ hideWhenUnavailable = false,
6627
+ onToggled,
6628
+ onClick,
6629
+ children,
6630
+ ...buttonProps
6631
+ }) => {
6632
+ const { editor } = (0, import_editor_utils17.useTiptapEditor)(providedEditor);
6633
+ const {
6634
+ isVisible,
6635
+ canToggle: canToggle3,
6636
+ isActive,
6637
+ handleToggle,
6638
+ label,
6639
+ // shortcutKeys,
6640
+ Icon
6641
+ } = useTableBlock({
6642
+ editor,
6643
+ hideWhenUnavailable,
5937
6644
  onToggled
5938
- } = config || {};
5939
- const { editor } = useTiptapEditor(providedEditor);
5940
- const [isVisible, setIsVisible] = React16.useState(true);
5941
- const canToggleState = canToggle2(editor);
5942
- const isActive = (editor == null ? void 0 : editor.isActive("codeBlock")) || false;
5943
- React16.useEffect(() => {
6645
+ });
6646
+ const handleClick = (0, import_react48.useCallback)(
6647
+ (event) => {
6648
+ onClick == null ? void 0 : onClick(event);
6649
+ if (event.defaultPrevented) return;
6650
+ handleToggle();
6651
+ },
6652
+ [handleToggle, onClick]
6653
+ );
6654
+ if (!isVisible) {
6655
+ return null;
6656
+ }
6657
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6658
+ import_toolbar6.ToolbarButton,
6659
+ {
6660
+ type: "button",
6661
+ variant: "ghost",
6662
+ color: "default",
6663
+ "data-active-state": isActive ? "on" : "off",
6664
+ disabled: !canToggle3,
6665
+ "data-disabled": !canToggle3,
6666
+ tabIndex: -1,
6667
+ "aria-label": label,
6668
+ "aria-pressed": isActive,
6669
+ title: label,
6670
+ onClick: handleClick,
6671
+ isIconOnly: !text && !children,
6672
+ ...buttonProps,
6673
+ children: children || /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
6674
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, {}),
6675
+ text && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: text })
6676
+ ] })
6677
+ }
6678
+ );
6679
+ };
6680
+
6681
+ // src/ui/text-align-button/text-align-button.tsx
6682
+ var import_button14 = require("@kopexa/button");
6683
+ var import_editor_utils19 = require("@kopexa/editor-utils");
6684
+ var import_react50 = require("react");
6685
+
6686
+ // src/ui/text-align-button/use-text-align.ts
6687
+ var import_editor_utils18 = require("@kopexa/editor-utils");
6688
+ var import_icons18 = require("@kopexa/icons");
6689
+ var import_react49 = require("react");
6690
+ var TEXT_ALIGN_SHORTCUT_KEYS = {
6691
+ left: "mod+shift+l",
6692
+ center: "mod+shift+e",
6693
+ right: "mod+shift+r",
6694
+ justify: "mod+shift+j"
6695
+ };
6696
+ var textAlignIcons = {
6697
+ left: import_icons18.AlignLeftIcon,
6698
+ center: import_icons18.AlignCenterIcon,
6699
+ right: import_icons18.AlignRightIcon,
6700
+ justify: import_icons18.AlignJustifyIcon
6701
+ };
6702
+ var textAlignLabels = {
6703
+ left: "Align left",
6704
+ center: "Align center",
6705
+ right: "Align right",
6706
+ justify: "Align justify"
6707
+ };
6708
+ function canSetTextAlign(editor, align) {
6709
+ if (!editor || !editor.isEditable) return false;
6710
+ if (!(0, import_editor_utils18.isExtensionAvailable)(editor, "textAlign") || (0, import_editor_utils18.isNodeTypeSelected)(editor, ["image"]))
6711
+ return false;
6712
+ return editor.can().setTextAlign(align);
6713
+ }
6714
+ function hasSetTextAlign(commands) {
6715
+ return "setTextAlign" in commands;
6716
+ }
6717
+ function isTextAlignActive(editor, align) {
6718
+ if (!editor || !editor.isEditable) return false;
6719
+ return editor.isActive({ textAlign: align });
6720
+ }
6721
+ function setTextAlign(editor, align) {
6722
+ if (!editor || !editor.isEditable) return false;
6723
+ if (!canSetTextAlign(editor, align)) return false;
6724
+ const chain = editor.chain().focus();
6725
+ if (hasSetTextAlign(chain)) {
6726
+ return chain.setTextAlign(align).run();
6727
+ }
6728
+ return false;
6729
+ }
6730
+ function shouldShowButton3(props) {
6731
+ const { editor, hideWhenUnavailable, align } = props;
6732
+ if (!editor || !editor.isEditable) return false;
6733
+ if (!(0, import_editor_utils18.isExtensionAvailable)(editor, "textAlign")) return false;
6734
+ if (hideWhenUnavailable && !editor.isActive("code")) {
6735
+ return canSetTextAlign(editor, align);
6736
+ }
6737
+ return true;
6738
+ }
6739
+ function useTextAlign(config) {
6740
+ const {
6741
+ editor: providedEditor,
6742
+ align,
6743
+ hideWhenUnavailable = false,
6744
+ onAligned
6745
+ } = config;
6746
+ const { editor } = (0, import_editor_utils18.useTiptapEditor)(providedEditor);
6747
+ const [isVisible, setIsVisible] = (0, import_react49.useState)(true);
6748
+ const canAlign = canSetTextAlign(editor, align);
6749
+ const isActive = isTextAlignActive(editor, align);
6750
+ (0, import_react49.useEffect)(() => {
5944
6751
  if (!editor) return;
5945
6752
  const handleSelectionUpdate = () => {
5946
- setIsVisible(shouldShowButton3({ editor, hideWhenUnavailable }));
6753
+ setIsVisible(shouldShowButton3({ editor, align, hideWhenUnavailable }));
5947
6754
  };
5948
6755
  handleSelectionUpdate();
5949
6756
  editor.on("selectionUpdate", handleSelectionUpdate);
5950
6757
  return () => {
5951
6758
  editor.off("selectionUpdate", handleSelectionUpdate);
5952
6759
  };
5953
- }, [editor, hideWhenUnavailable]);
5954
- const handleToggle = React16.useCallback(() => {
6760
+ }, [editor, hideWhenUnavailable, align]);
6761
+ const handleTextAlign = (0, import_react49.useCallback)(() => {
5955
6762
  if (!editor) return false;
5956
- const success = toggleCodeBlock(editor);
6763
+ const success = setTextAlign(editor, align);
5957
6764
  if (success) {
5958
- onToggled == null ? void 0 : onToggled();
6765
+ onAligned == null ? void 0 : onAligned();
5959
6766
  }
5960
6767
  return success;
5961
- }, [editor, onToggled]);
6768
+ }, [editor, align, onAligned]);
5962
6769
  return {
5963
6770
  isVisible,
5964
6771
  isActive,
5965
- handleToggle,
5966
- canToggle: canToggleState,
5967
- label: "Code Block",
5968
- shortcutKeys: CODE_BLOCK_SHORTCUT_KEY,
5969
- Icon: import_icons15.CodeblockIcon
6772
+ handleTextAlign,
6773
+ canAlign,
6774
+ label: textAlignLabels[align],
6775
+ shortcutKeys: TEXT_ALIGN_SHORTCUT_KEYS[align],
6776
+ Icon: textAlignIcons[align]
5970
6777
  };
5971
6778
  }
5972
6779
 
5973
- // src/ui/codeblock-button/code-block-button.tsx
5974
- var import_jsx_runtime22 = require("react/jsx-runtime");
5975
- var CodeBlockButton = ({
6780
+ // src/ui/text-align-button/text-align-button.tsx
6781
+ var import_jsx_runtime26 = require("react/jsx-runtime");
6782
+ var TextAlignButton = ({
5976
6783
  editor: providedEditor,
6784
+ align,
5977
6785
  text,
5978
6786
  hideWhenUnavailable = false,
5979
- onToggled,
6787
+ onAligned,
5980
6788
  showShortcut = false,
5981
6789
  onClick,
5982
6790
  children,
5983
6791
  ...buttonProps
5984
6792
  }) => {
5985
- const { editor } = useTiptapEditor(providedEditor);
5986
- const { isVisible, canToggle: canToggle3, isActive, handleToggle, label, shortcutKeys } = useCodeBlock({
6793
+ const { editor } = (0, import_editor_utils19.useTiptapEditor)(providedEditor);
6794
+ const {
6795
+ isVisible,
6796
+ handleTextAlign,
6797
+ label,
6798
+ canAlign,
6799
+ isActive,
6800
+ Icon,
6801
+ shortcutKeys
6802
+ } = useTextAlign({
5987
6803
  editor,
6804
+ align,
5988
6805
  hideWhenUnavailable,
5989
- onToggled
6806
+ onAligned
5990
6807
  });
5991
- const handleClick = (0, import_react44.useCallback)(
5992
- (event) => {
5993
- onClick == null ? void 0 : onClick(event);
5994
- if (event.defaultPrevented) return;
5995
- handleToggle();
6808
+ const handleClick = (0, import_react50.useCallback)(
6809
+ (e) => {
6810
+ onClick == null ? void 0 : onClick(e);
6811
+ if (e.defaultPrevented) return;
6812
+ handleTextAlign();
5996
6813
  },
5997
- [handleToggle, onClick]
6814
+ [handleTextAlign, onClick]
5998
6815
  );
5999
6816
  if (!isVisible) {
6000
6817
  return null;
6001
6818
  }
6002
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6003
- import_toolbar5.ToolbarButton,
6819
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6820
+ import_button14.IconButton,
6004
6821
  {
6005
6822
  type: "button",
6823
+ disabled: canAlign,
6006
6824
  variant: "ghost",
6007
6825
  color: "default",
6008
- disabled: !canToggle3,
6009
- "data-disabled": !canToggle3,
6010
6826
  "data-active-state": isActive ? "on" : "off",
6827
+ "data-disabled": canAlign,
6011
6828
  tabIndex: -1,
6012
- "aria-label": "codeBlock",
6829
+ "aria-label": label,
6013
6830
  "aria-pressed": isActive,
6014
- title: label,
6831
+ tooltip: label,
6015
6832
  shortcutKeys,
6016
6833
  onClick: handleClick,
6017
- isIconOnly: true,
6018
6834
  ...buttonProps,
6019
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons16.CodeblockIcon, {})
6835
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Icon, {})
6020
6836
  }
6021
6837
  );
6022
6838
  };
6023
6839
 
6024
- // src/ui/color-highlight-popover/color-highlight-popover.tsx
6025
- var import_button11 = require("@kopexa/button");
6026
- var import_icons18 = require("@kopexa/icons");
6027
- var import_popover2 = require("@kopexa/popover");
6028
- var import_toolbar7 = require("@kopexa/toolbar");
6029
- var import_react46 = require("react");
6840
+ // src/ui/turn-into-dropdown/turn-into-dropdown.tsx
6841
+ var import_button17 = require("@kopexa/button");
6842
+ var import_dropdown_menu2 = require("@kopexa/dropdown-menu");
6843
+ var import_editor_utils28 = require("@kopexa/editor-utils");
6844
+ var import_react56 = require("react");
6030
6845
 
6031
- // src/ui/color-highlight-button/color-highlight-button.tsx
6032
- var import_theme8 = require("@kopexa/theme");
6033
- var import_toolbar6 = require("@kopexa/toolbar");
6034
- var import_react45 = require("react");
6846
+ // src/ui/blockquote-button/blockquote-button.tsx
6847
+ var import_editor_utils21 = require("@kopexa/editor-utils");
6848
+ var import_toolbar7 = require("@kopexa/toolbar");
6849
+ var React16 = __toESM(require("react"));
6035
6850
 
6036
- // src/ui/color-highlight-button/use-color-highlight.ts
6037
- var import_editor_utils10 = require("@kopexa/editor-utils");
6038
- var import_icons17 = require("@kopexa/icons");
6039
- var import_use_is_mobile = require("@kopexa/use-is-mobile");
6040
- var React17 = __toESM(require("react"));
6041
- var import_react_hotkeys_hook = require("react-hotkeys-hook");
6042
- var COLOR_HIGHLIGHT_SHORTCUT_KEY = "mod+shift+h";
6043
- var HIGHLIGHT_COLORS = [
6044
- {
6045
- label: "Default background",
6046
- value: "var(--tt-bg-color)",
6047
- border: "var(--tt-bg-color-contrast)"
6048
- },
6049
- {
6050
- label: "Gray background",
6051
- value: "var(--tt-color-highlight-gray)",
6052
- border: "var(--tt-color-highlight-gray-contrast)"
6053
- },
6054
- {
6055
- label: "Brown background",
6056
- value: "var(--tt-color-highlight-brown)",
6057
- border: "var(--tt-color-highlight-brown-contrast)"
6058
- },
6059
- {
6060
- label: "Orange background",
6061
- value: "var(--tt-color-highlight-orange)",
6062
- border: "var(--tt-color-highlight-orange-contrast)"
6063
- },
6064
- {
6065
- label: "Yellow background",
6066
- value: "var(--tt-color-highlight-yellow)",
6067
- border: "var(--tt-color-highlight-yellow-contrast)"
6068
- },
6069
- {
6070
- label: "Green background",
6071
- value: "var(--tt-color-highlight-green)",
6072
- border: "var(--tt-color-highlight-green-contrast)"
6073
- },
6074
- {
6075
- label: "Blue background",
6076
- value: "var(--tt-color-highlight-blue)",
6077
- border: "var(--tt-color-highlight-blue-contrast)"
6078
- },
6079
- {
6080
- label: "Purple background",
6081
- value: "var(--tt-color-highlight-purple)",
6082
- border: "var(--tt-color-highlight-purple-contrast)"
6083
- },
6084
- {
6085
- label: "Pink background",
6086
- value: "var(--tt-color-highlight-pink)",
6087
- border: "var(--tt-color-highlight-pink-contrast)"
6088
- },
6089
- {
6090
- label: "Red background",
6091
- value: "var(--tt-color-highlight-red)",
6092
- border: "var(--tt-color-highlight-red-contrast)"
6093
- }
6094
- ];
6095
- function pickHighlightColorsByValue(values) {
6096
- const colorMap = new Map(
6097
- HIGHLIGHT_COLORS.map((color) => [color.value, color])
6098
- );
6099
- return values.map((value) => colorMap.get(value)).filter((color) => !!color);
6100
- }
6101
- function canColorHighlight(editor) {
6851
+ // src/ui/blockquote-button/use-blockquote.ts
6852
+ var import_editor_utils20 = require("@kopexa/editor-utils");
6853
+ var import_icons19 = require("@kopexa/icons");
6854
+ var import_state7 = require("@tiptap/pm/state");
6855
+ var React15 = __toESM(require("react"));
6856
+ var BLOCKQUOTE_SHORTCUT_KEY = "mod+shift+b";
6857
+ function canToggleBlockquote(editor, turnInto = true) {
6858
+ var _a;
6102
6859
  if (!editor || !editor.isEditable) return false;
6103
- if (!(0, import_editor_utils10.isMarkInSchema)("highlight", editor) || (0, import_editor_utils10.isNodeTypeSelected)(editor, ["image"]))
6860
+ if (!(0, import_editor_utils20.isNodeInSchema)("blockquote", editor) || (0, import_editor_utils20.isNodeTypeSelected)(editor, ["image"]))
6104
6861
  return false;
6105
- return editor.can().setMark("highlight");
6106
- }
6107
- function isColorHighlightActive(editor, highlightColor) {
6108
- if (!editor || !editor.isEditable) return false;
6109
- return highlightColor ? editor.isActive("highlight", { color: highlightColor }) : editor.isActive("highlight");
6862
+ if (!turnInto) {
6863
+ return editor.can().toggleWrap("blockquote");
6864
+ }
6865
+ try {
6866
+ const view = editor.view;
6867
+ const state = view.state;
6868
+ const selection = state.selection;
6869
+ if (selection.empty || selection instanceof import_state7.TextSelection) {
6870
+ const pos = (_a = (0, import_editor_utils20.findNodePosition)({
6871
+ editor,
6872
+ node: state.selection.$anchor.node(1)
6873
+ })) == null ? void 0 : _a.pos;
6874
+ if (!(0, import_editor_utils20.isValidPosition)(pos)) return false;
6875
+ }
6876
+ return true;
6877
+ } catch {
6878
+ return false;
6879
+ }
6110
6880
  }
6111
- function removeHighlight(editor) {
6881
+ function toggleBlockquote(editor) {
6882
+ var _a, _b, _c;
6112
6883
  if (!editor || !editor.isEditable) return false;
6113
- if (!canColorHighlight(editor)) return false;
6114
- return editor.chain().focus().unsetMark("highlight").run();
6884
+ if (!canToggleBlockquote(editor)) return false;
6885
+ try {
6886
+ const view = editor.view;
6887
+ let state = view.state;
6888
+ let tr = state.tr;
6889
+ if (state.selection.empty || state.selection instanceof import_state7.TextSelection) {
6890
+ const pos = (_a = (0, import_editor_utils20.findNodePosition)({
6891
+ editor,
6892
+ node: state.selection.$anchor.node(1)
6893
+ })) == null ? void 0 : _a.pos;
6894
+ if (!(0, import_editor_utils20.isValidPosition)(pos)) return false;
6895
+ tr = tr.setSelection(import_state7.NodeSelection.create(state.doc, pos));
6896
+ view.dispatch(tr);
6897
+ state = view.state;
6898
+ }
6899
+ const selection = state.selection;
6900
+ let chain = editor.chain().focus();
6901
+ if (selection instanceof import_state7.NodeSelection) {
6902
+ const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
6903
+ const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
6904
+ const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
6905
+ const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
6906
+ chain = chain.setTextSelection({ from, to }).clearNodes();
6907
+ }
6908
+ const toggle = editor.isActive("blockquote") ? chain.lift("blockquote") : chain.wrapIn("blockquote");
6909
+ toggle.run();
6910
+ editor.chain().focus().selectTextblockEnd().run();
6911
+ return true;
6912
+ } catch {
6913
+ return false;
6914
+ }
6115
6915
  }
6116
6916
  function shouldShowButton4(props) {
6117
6917
  const { editor, hideWhenUnavailable } = props;
6118
6918
  if (!editor || !editor.isEditable) return false;
6119
- if (!(0, import_editor_utils10.isMarkInSchema)("highlight", editor)) return false;
6919
+ if (!(0, import_editor_utils20.isNodeInSchema)("blockquote", editor)) return false;
6120
6920
  if (hideWhenUnavailable && !editor.isActive("code")) {
6121
- return canColorHighlight(editor);
6921
+ return canToggleBlockquote(editor);
6122
6922
  }
6123
6923
  return true;
6124
6924
  }
6125
- function useColorHighlight(config) {
6925
+ function useBlockquote(config) {
6126
6926
  const {
6127
6927
  editor: providedEditor,
6128
- label,
6129
- highlightColor,
6130
6928
  hideWhenUnavailable = false,
6131
- onApplied
6132
- } = config;
6133
- const { editor } = useTiptapEditor(providedEditor);
6134
- const isMobile = (0, import_use_is_mobile.useIsMobile)();
6135
- const [isVisible, setIsVisible] = React17.useState(true);
6136
- const canColorHighlightState = canColorHighlight(editor);
6137
- const isActive = isColorHighlightActive(editor, highlightColor);
6138
- React17.useEffect(() => {
6929
+ onToggled
6930
+ } = config || {};
6931
+ const { editor } = (0, import_editor_utils20.useTiptapEditor)(providedEditor);
6932
+ const [isVisible, setIsVisible] = React15.useState(true);
6933
+ const canToggle3 = canToggleBlockquote(editor);
6934
+ const isActive = (editor == null ? void 0 : editor.isActive("blockquote")) || false;
6935
+ React15.useEffect(() => {
6139
6936
  if (!editor) return;
6140
6937
  const handleSelectionUpdate = () => {
6141
6938
  setIsVisible(shouldShowButton4({ editor, hideWhenUnavailable }));
@@ -6146,674 +6943,403 @@ function useColorHighlight(config) {
6146
6943
  editor.off("selectionUpdate", handleSelectionUpdate);
6147
6944
  };
6148
6945
  }, [editor, hideWhenUnavailable]);
6149
- const handleColorHighlight = React17.useCallback(() => {
6150
- if (!editor || !canColorHighlightState || !highlightColor || !label)
6151
- return false;
6152
- if (editor.state.storedMarks) {
6153
- const highlightMarkType = editor.schema.marks.highlight;
6154
- if (highlightMarkType) {
6155
- editor.view.dispatch(
6156
- editor.state.tr.removeStoredMark(highlightMarkType)
6157
- );
6158
- }
6159
- }
6160
- setTimeout(() => {
6161
- const success = editor.chain().focus().toggleMark("highlight", { color: highlightColor }).run();
6162
- if (success) {
6163
- onApplied == null ? void 0 : onApplied({ color: highlightColor, label });
6164
- }
6165
- return success;
6166
- }, 0);
6167
- }, [canColorHighlightState, highlightColor, editor, label, onApplied]);
6168
- const handleRemoveHighlight = React17.useCallback(() => {
6169
- const success = removeHighlight(editor);
6946
+ const handleToggle = React15.useCallback(() => {
6947
+ if (!editor) return false;
6948
+ const success = toggleBlockquote(editor);
6170
6949
  if (success) {
6171
- onApplied == null ? void 0 : onApplied({ color: "", label: "Remove highlight" });
6950
+ onToggled == null ? void 0 : onToggled();
6172
6951
  }
6173
6952
  return success;
6174
- }, [editor, onApplied]);
6175
- (0, import_react_hotkeys_hook.useHotkeys)(
6176
- COLOR_HIGHLIGHT_SHORTCUT_KEY,
6177
- (event) => {
6178
- event.preventDefault();
6179
- handleColorHighlight();
6180
- },
6181
- {
6182
- enabled: isVisible && canColorHighlightState,
6183
- enableOnContentEditable: !isMobile,
6184
- enableOnFormTags: true
6185
- }
6186
- );
6953
+ }, [editor, onToggled]);
6187
6954
  return {
6188
6955
  isVisible,
6189
6956
  isActive,
6190
- handleColorHighlight,
6191
- handleRemoveHighlight,
6192
- canColorHighlight: canColorHighlightState,
6193
- label: label || `Highlight`,
6194
- shortcutKeys: COLOR_HIGHLIGHT_SHORTCUT_KEY,
6195
- Icon: import_icons17.HighlighterIcon
6957
+ handleToggle,
6958
+ canToggle: canToggle3,
6959
+ label: "Blockquote",
6960
+ shortcutKeys: BLOCKQUOTE_SHORTCUT_KEY,
6961
+ Icon: import_icons19.BlockquoteIcon
6196
6962
  };
6197
6963
  }
6198
6964
 
6199
- // src/ui/color-highlight-button/color-highlight-button.tsx
6200
- var import_jsx_runtime23 = require("react/jsx-runtime");
6201
- var ColorHighlightButton = ({
6965
+ // src/ui/blockquote-button/blockquote-button.tsx
6966
+ var import_jsx_runtime27 = require("react/jsx-runtime");
6967
+ var BlockquoteButton = ({
6202
6968
  editor: providedEditor,
6203
- highlightColor,
6204
6969
  text,
6205
6970
  hideWhenUnavailable = false,
6206
- onApplied,
6971
+ onToggled,
6207
6972
  showShortcut = false,
6208
6973
  onClick,
6209
6974
  children,
6210
- style,
6211
- className,
6212
6975
  ...buttonProps
6213
6976
  }) => {
6214
- const { editor } = useTiptapEditor(providedEditor);
6977
+ const { editor } = (0, import_editor_utils21.useTiptapEditor)(providedEditor);
6215
6978
  const {
6216
6979
  isVisible,
6217
- canColorHighlight: canColorHighlight2,
6980
+ canToggle: canToggle3,
6218
6981
  isActive,
6219
- handleColorHighlight,
6982
+ handleToggle,
6220
6983
  label,
6221
- shortcutKeys
6222
- } = useColorHighlight({
6984
+ shortcutKeys,
6985
+ Icon
6986
+ } = useBlockquote({
6223
6987
  editor,
6224
- highlightColor,
6225
- label: text || `Toggle highlight (${highlightColor})`,
6226
6988
  hideWhenUnavailable,
6227
- onApplied
6989
+ onToggled
6228
6990
  });
6229
- const handleClick = (0, import_react45.useCallback)(
6991
+ const handleClick = React16.useCallback(
6230
6992
  (event) => {
6231
6993
  onClick == null ? void 0 : onClick(event);
6232
6994
  if (event.defaultPrevented) return;
6233
- handleColorHighlight();
6995
+ handleToggle();
6234
6996
  },
6235
- [handleColorHighlight, onClick]
6236
- );
6237
- const buttonStyle = (0, import_react45.useMemo)(
6238
- () => ({
6239
- ...style,
6240
- "--highlight-color": highlightColor
6241
- }),
6242
- [highlightColor, style]
6997
+ [handleToggle, onClick]
6243
6998
  );
6244
6999
  if (!isVisible) {
6245
7000
  return null;
6246
7001
  }
6247
- const styles = (0, import_theme8.colorHighlightButton)();
6248
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6249
- import_toolbar6.ToolbarButton,
7002
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
7003
+ import_toolbar7.ToolbarButton,
6250
7004
  {
6251
7005
  type: "button",
6252
- disabled: !canColorHighlight2,
6253
- "data-disabled": !canColorHighlight2,
6254
7006
  variant: "ghost",
6255
7007
  color: "default",
7008
+ disabled: !canToggle3,
7009
+ "data-disabled": !canToggle3,
6256
7010
  "data-active-state": isActive ? "on" : "off",
6257
7011
  tabIndex: -1,
6258
- "aria-label": label,
6259
- shortcutKeys,
7012
+ "aria-label": "blockquote",
6260
7013
  "aria-pressed": isActive,
7014
+ title: label,
7015
+ shortcutKeys,
6261
7016
  onClick: handleClick,
6262
- style: buttonStyle,
6263
- className: styles.button({ className }),
6264
- isIconOnly: true,
7017
+ isIconOnly: !text && !children,
6265
7018
  ...buttonProps,
6266
- children: [
6267
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6268
- "span",
6269
- {
6270
- "data-active-state": isActive ? "on" : "off",
6271
- className: styles.mark()
6272
- }
6273
- ),
6274
- children || /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6275
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6276
- "span",
6277
- {
6278
- style: { "--highlight-color": highlightColor }
6279
- }
6280
- ),
6281
- text
6282
- ] })
6283
- ]
7019
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
7020
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Icon, {}),
7021
+ text && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: text })
7022
+ ] })
6284
7023
  }
6285
7024
  );
6286
7025
  };
6287
7026
 
6288
- // src/ui/color-highlight-popover/color-highlight-popover.tsx
6289
- var import_jsx_runtime24 = require("react/jsx-runtime");
6290
- var ColorHighlightPopoverButton = ({
6291
- className,
6292
- children,
6293
- ...props
6294
- }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6295
- import_button11.IconButton,
6296
- {
6297
- type: "button",
6298
- className,
6299
- variant: "ghost",
6300
- color: "default",
6301
- tabIndex: -1,
6302
- "aria-label": "Highlight text",
6303
- tooltip: "Highlight",
6304
- isIconOnly: !children,
6305
- ...props,
6306
- children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_icons18.HighlighterIcon, {})
6307
- }
6308
- );
6309
- function ColorHighlightPopoverContent({
6310
- editor,
6311
- colors = pickHighlightColorsByValue([
6312
- "var(--tt-color-highlight-green)",
6313
- "var(--tt-color-highlight-blue)",
6314
- "var(--tt-color-highlight-red)",
6315
- "var(--tt-color-highlight-purple)",
6316
- "var(--tt-color-highlight-yellow)"
6317
- ])
6318
- }) {
6319
- const { handleRemoveHighlight } = useColorHighlight({ editor });
6320
- const containerRef = (0, import_react46.useRef)(null);
6321
- const menuItems = (0, import_react46.useMemo)(
6322
- () => [...colors, { label: "Remove highlight", value: "none" }],
6323
- [colors]
6324
- );
6325
- const { selectedIndex } = useMenuNavigation({
6326
- containerRef,
6327
- items: menuItems,
6328
- orientation: "both",
6329
- onSelect: (item) => {
6330
- if (!containerRef.current) return false;
6331
- const highlightedElement = containerRef.current.querySelector(
6332
- '[data-highlighted="true"]'
6333
- );
6334
- if (highlightedElement) highlightedElement.click();
6335
- if (item.value === "none") handleRemoveHighlight();
6336
- },
6337
- autoSelectFirstItem: false
6338
- });
6339
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { ref: containerRef, className: "flex gap-1 items-center", children: [
6340
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6341
- "div",
6342
- {
6343
- className: "flex items-center gap-1 outline-none",
6344
- "data-orientation": "horizontal",
6345
- children: colors.map((color, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6346
- ColorHighlightButton,
6347
- {
6348
- editor,
6349
- highlightColor: color.value,
6350
- "aria-label": `${color.label} highlight color`,
6351
- tabIndex: index === selectedIndex ? 0 : -1,
6352
- "data-highlighted": selectedIndex === index
6353
- },
6354
- color.value
6355
- ))
6356
- }
6357
- ),
6358
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_toolbar7.ToolbarSeparator, { orientation: "vertical" }),
6359
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "tiptap-button-group", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6360
- import_button11.IconButton,
6361
- {
6362
- onClick: handleRemoveHighlight,
6363
- "aria-label": "Remove highlight",
6364
- tabIndex: selectedIndex === colors.length ? 0 : -1,
6365
- type: "button",
6366
- role: "menuitem",
6367
- variant: "ghost",
6368
- color: "default",
6369
- "data-highlighted": selectedIndex === colors.length,
6370
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_icons18.BanIcon, {})
6371
- }
6372
- ) })
6373
- ] });
6374
- }
6375
- function ColorHighlightPopover({
6376
- editor: providedEditor,
6377
- colors = pickHighlightColorsByValue([
6378
- "var(--tt-color-highlight-green)",
6379
- "var(--tt-color-highlight-blue)",
6380
- "var(--tt-color-highlight-red)",
6381
- "var(--tt-color-highlight-purple)",
6382
- "var(--tt-color-highlight-yellow)"
6383
- ]),
6384
- hideWhenUnavailable = false,
6385
- onApplied,
6386
- ...props
6387
- }) {
6388
- const { editor } = useTiptapEditor(providedEditor);
6389
- const [isOpen, setIsOpen] = (0, import_react46.useState)(false);
6390
- const { isVisible, canColorHighlight: canColorHighlight2, isActive, label } = useColorHighlight({
6391
- editor,
6392
- hideWhenUnavailable,
6393
- onApplied
6394
- });
6395
- if (!isVisible) return null;
6396
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_popover2.Popover.Root, { open: isOpen, onOpenChange: setIsOpen, spacing: "dense", children: [
6397
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6398
- import_popover2.Popover.Trigger,
6399
- {
6400
- render: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6401
- ColorHighlightPopoverButton,
6402
- {
6403
- disabled: !canColorHighlight2,
6404
- "data-disabled": !canColorHighlight2,
6405
- "data-active-state": isActive ? "on" : "off",
6406
- "aria-pressed": isActive,
6407
- "aria-label": label,
6408
- title: label,
6409
- ...props
6410
- }
6411
- )
6412
- }
6413
- ),
6414
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_popover2.Popover.Content, { "aria-label": "Highlight colors", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ColorHighlightPopoverContent, { editor, colors }) })
6415
- ] });
6416
- }
7027
+ // src/ui/codeblock-button/code-block-button.tsx
7028
+ var import_editor_utils23 = require("@kopexa/editor-utils");
7029
+ var import_icons21 = require("@kopexa/icons");
7030
+ var import_toolbar8 = require("@kopexa/toolbar");
7031
+ var import_react51 = require("react");
6417
7032
 
6418
- // src/ui/heading-dropdown-menu/index.tsx
6419
- var import_button13 = require("@kopexa/button");
6420
- var import_dropdown_menu = require("@kopexa/dropdown-menu");
6421
- var import_editor_utils12 = require("@kopexa/editor-utils");
7033
+ // src/ui/codeblock-button/use-code-block.ts
7034
+ var import_editor_utils22 = require("@kopexa/editor-utils");
6422
7035
  var import_icons20 = require("@kopexa/icons");
6423
- var import_react48 = require("@tiptap/react");
6424
- var React19 = __toESM(require("react"));
6425
-
6426
- // src/ui/heading-button/index.tsx
6427
- var import_button12 = require("@kopexa/button");
6428
- var import_editor_utils11 = require("@kopexa/editor-utils");
6429
- var import_icons19 = require("@kopexa/icons");
6430
- var React18 = __toESM(require("react"));
6431
-
6432
- // src/ui/heading-button/utils.ts
6433
- var import_react47 = require("@tiptap/react");
6434
- var headingShortcutKeys = {
6435
- 1: "Ctrl-Alt-1",
6436
- 2: "Ctrl-Alt-2",
6437
- 3: "Ctrl-Alt-3",
6438
- 4: "Ctrl-Alt-4",
6439
- 5: "Ctrl-Alt-5",
6440
- 6: "Ctrl-Alt-6"
6441
- };
6442
- function canToggleHeading(editor, level) {
6443
- if (!editor) return false;
7036
+ var import_state8 = require("@tiptap/pm/state");
7037
+ var React17 = __toESM(require("react"));
7038
+ var CODE_BLOCK_SHORTCUT_KEY = "mod+alt+c";
7039
+ function canToggle2(editor, turnInto = true) {
7040
+ var _a;
7041
+ if (!editor || !editor.isEditable) return false;
7042
+ if (!(0, import_editor_utils22.isNodeInSchema)("codeBlock", editor) || (0, import_editor_utils22.isNodeTypeSelected)(editor, ["image"]))
7043
+ return false;
7044
+ if (!turnInto) {
7045
+ return editor.can().toggleNode("codeBlock", "paragraph");
7046
+ }
6444
7047
  try {
6445
- return editor.can().toggleNode("heading", "paragraph", { level });
7048
+ const view = editor.view;
7049
+ const state = view.state;
7050
+ const selection = state.selection;
7051
+ if (selection.empty || selection instanceof import_state8.TextSelection) {
7052
+ const pos = (_a = (0, import_editor_utils22.findNodePosition)({
7053
+ editor,
7054
+ node: state.selection.$anchor.node(1)
7055
+ })) == null ? void 0 : _a.pos;
7056
+ if (!(0, import_editor_utils22.isValidPosition)(pos)) return false;
7057
+ }
7058
+ return true;
6446
7059
  } catch {
6447
7060
  return false;
6448
7061
  }
6449
7062
  }
6450
- function isHeadingActive(editor, level) {
6451
- if (!editor) return false;
6452
- return editor.isActive("heading", { level });
6453
- }
6454
- function toggleHeading(editor, level) {
6455
- if (!editor) return;
6456
- if (editor.isActive("heading", { level })) {
6457
- editor.chain().focus().setNode("paragraph").run();
6458
- } else {
6459
- editor.chain().focus().toggleNode("heading", "paragraph", { level }).run();
6460
- }
6461
- }
6462
- function isHeadingButtonDisabled(editor, level, userDisabled = false) {
6463
- if (!editor) return true;
6464
- if (userDisabled) return true;
6465
- if (!canToggleHeading(editor, level)) return true;
6466
- return false;
6467
- }
6468
- function shouldShowHeadingButton(params) {
6469
- const { editor, hideWhenUnavailable, headingInSchema } = params;
6470
- if (!headingInSchema || !editor) {
7063
+ function toggleCodeBlock(editor) {
7064
+ var _a, _b, _c;
7065
+ if (!editor || !editor.isEditable) return false;
7066
+ if (!canToggle2(editor)) return false;
7067
+ try {
7068
+ const view = editor.view;
7069
+ let state = view.state;
7070
+ let tr = state.tr;
7071
+ if (state.selection.empty || state.selection instanceof import_state8.TextSelection) {
7072
+ const pos = (_a = (0, import_editor_utils22.findNodePosition)({
7073
+ editor,
7074
+ node: state.selection.$anchor.node(1)
7075
+ })) == null ? void 0 : _a.pos;
7076
+ if (!(0, import_editor_utils22.isValidPosition)(pos)) return false;
7077
+ tr = tr.setSelection(import_state8.NodeSelection.create(state.doc, pos));
7078
+ view.dispatch(tr);
7079
+ state = view.state;
7080
+ }
7081
+ const selection = state.selection;
7082
+ let chain = editor.chain().focus();
7083
+ if (selection instanceof import_state8.NodeSelection) {
7084
+ const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
7085
+ const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
7086
+ const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
7087
+ const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
7088
+ chain = chain.setTextSelection({ from, to }).clearNodes();
7089
+ }
7090
+ const toggle = editor.isActive("codeBlock") ? chain.setNode("paragraph") : chain.toggleNode("codeBlock", "paragraph");
7091
+ toggle.run();
7092
+ editor.chain().focus().selectTextblockEnd().run();
7093
+ return true;
7094
+ } catch {
6471
7095
  return false;
6472
7096
  }
6473
- if (hideWhenUnavailable) {
6474
- if ((0, import_react47.isNodeSelection)(editor.state.selection)) {
6475
- return false;
6476
- }
7097
+ }
7098
+ function shouldShowButton5(props) {
7099
+ const { editor, hideWhenUnavailable } = props;
7100
+ if (!editor || !editor.isEditable) return false;
7101
+ if (!(0, import_editor_utils22.isNodeInSchema)("codeBlock", editor)) return false;
7102
+ if (hideWhenUnavailable && !editor.isActive("code")) {
7103
+ return canToggle2(editor);
6477
7104
  }
6478
7105
  return true;
6479
7106
  }
6480
- function getFormattedHeadingName(level) {
6481
- return `Heading ${level}`;
6482
- }
6483
-
6484
- // src/ui/heading-button/index.tsx
6485
- var import_jsx_runtime25 = require("react/jsx-runtime");
6486
- var headingIcons = {
6487
- 1: import_icons19.HeadingOneIcon,
6488
- 2: import_icons19.HeadingTwoIcon,
6489
- 3: import_icons19.HeadingThreeIcon,
6490
- 4: import_icons19.HeadingFourIcon,
6491
- 5: import_icons19.HeadingFiveIcon,
6492
- 6: import_icons19.HeadingSixIcon
6493
- };
6494
- function useHeadingState(editor, level, disabled = false) {
6495
- const headingInSchema = (0, import_editor_utils11.isNodeInSchema)("heading", editor);
6496
- const isDisabled = isHeadingButtonDisabled(editor, level, disabled);
6497
- const isActive = isHeadingActive(editor, level);
6498
- const Icon = headingIcons[level];
6499
- const shortcutKey = headingShortcutKeys[level];
6500
- const formattedName = getFormattedHeadingName(level);
7107
+ function useCodeBlock(config) {
7108
+ const {
7109
+ editor: providedEditor,
7110
+ hideWhenUnavailable = false,
7111
+ onToggled
7112
+ } = config || {};
7113
+ const { editor } = (0, import_editor_utils22.useTiptapEditor)(providedEditor);
7114
+ const [isVisible, setIsVisible] = React17.useState(true);
7115
+ const canToggleState = canToggle2(editor);
7116
+ const isActive = (editor == null ? void 0 : editor.isActive("codeBlock")) || false;
7117
+ React17.useEffect(() => {
7118
+ if (!editor) return;
7119
+ const handleSelectionUpdate = () => {
7120
+ setIsVisible(shouldShowButton5({ editor, hideWhenUnavailable }));
7121
+ };
7122
+ handleSelectionUpdate();
7123
+ editor.on("selectionUpdate", handleSelectionUpdate);
7124
+ return () => {
7125
+ editor.off("selectionUpdate", handleSelectionUpdate);
7126
+ };
7127
+ }, [editor, hideWhenUnavailable]);
7128
+ const handleToggle = React17.useCallback(() => {
7129
+ if (!editor) return false;
7130
+ const success = toggleCodeBlock(editor);
7131
+ if (success) {
7132
+ onToggled == null ? void 0 : onToggled();
7133
+ }
7134
+ return success;
7135
+ }, [editor, onToggled]);
6501
7136
  return {
6502
- headingInSchema,
6503
- isDisabled,
7137
+ isVisible,
6504
7138
  isActive,
6505
- Icon,
6506
- shortcutKey,
6507
- formattedName
7139
+ handleToggle,
7140
+ canToggle: canToggleState,
7141
+ label: "Code Block",
7142
+ shortcutKeys: CODE_BLOCK_SHORTCUT_KEY,
7143
+ Icon: import_icons20.CodeblockIcon
6508
7144
  };
6509
7145
  }
6510
- var HeadingButton = ({
7146
+
7147
+ // src/ui/codeblock-button/code-block-button.tsx
7148
+ var import_jsx_runtime28 = require("react/jsx-runtime");
7149
+ var CodeBlockButton = ({
6511
7150
  editor: providedEditor,
6512
- level,
6513
7151
  text,
6514
7152
  hideWhenUnavailable = false,
6515
- className = "",
6516
- disabled,
7153
+ onToggled,
7154
+ showShortcut = false,
6517
7155
  onClick,
6518
7156
  children,
6519
- ref,
6520
7157
  ...buttonProps
6521
7158
  }) => {
6522
- const { editor } = useTiptapEditor(providedEditor);
6523
- const {
6524
- headingInSchema,
6525
- isDisabled,
6526
- isActive,
6527
- Icon,
6528
- shortcutKey,
6529
- formattedName
6530
- } = useHeadingState(editor, level, disabled);
6531
- const handleClick = React18.useCallback(
6532
- (e) => {
6533
- onClick == null ? void 0 : onClick(e);
6534
- if (!e.defaultPrevented && !isDisabled && editor) {
6535
- toggleHeading(editor, level);
6536
- }
7159
+ const { editor } = (0, import_editor_utils23.useTiptapEditor)(providedEditor);
7160
+ const { isVisible, canToggle: canToggle3, isActive, handleToggle, label, shortcutKeys } = useCodeBlock({
7161
+ editor,
7162
+ hideWhenUnavailable,
7163
+ onToggled
7164
+ });
7165
+ const handleClick = (0, import_react51.useCallback)(
7166
+ (event) => {
7167
+ onClick == null ? void 0 : onClick(event);
7168
+ if (event.defaultPrevented) return;
7169
+ handleToggle();
6537
7170
  },
6538
- [onClick, isDisabled, editor, level]
7171
+ [handleToggle, onClick]
6539
7172
  );
6540
- const show = React18.useMemo(() => {
6541
- return shouldShowHeadingButton({
6542
- editor,
6543
- level,
6544
- hideWhenUnavailable,
6545
- headingInSchema
6546
- });
6547
- }, [editor, level, hideWhenUnavailable, headingInSchema]);
6548
- if (!show || !editor || !editor.isEditable) {
7173
+ if (!isVisible) {
6549
7174
  return null;
6550
7175
  }
6551
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6552
- import_button12.Button,
7176
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7177
+ import_toolbar8.ToolbarButton,
6553
7178
  {
6554
7179
  type: "button",
6555
- className: className.trim(),
6556
- disabled: isDisabled,
6557
7180
  variant: "ghost",
6558
7181
  color: "default",
7182
+ disabled: !canToggle3,
7183
+ "data-disabled": !canToggle3,
6559
7184
  "data-active-state": isActive ? "on" : "off",
6560
- "data-disabled": isDisabled,
6561
7185
  tabIndex: -1,
6562
- "aria-label": formattedName,
7186
+ "aria-label": "codeBlock",
6563
7187
  "aria-pressed": isActive,
6564
- tooltip: formattedName,
6565
- shortcutKeys: shortcutKey,
7188
+ title: label,
7189
+ shortcutKeys,
6566
7190
  onClick: handleClick,
6567
- startContent: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, {}),
7191
+ isIconOnly: !text && !children,
6568
7192
  ...buttonProps,
6569
- ref,
6570
- children: children || text
7193
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
7194
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons21.CodeblockIcon, {}),
7195
+ text && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: text })
7196
+ ] })
6571
7197
  }
6572
7198
  );
6573
7199
  };
6574
7200
 
6575
- // src/ui/heading-dropdown-menu/index.tsx
6576
- var import_jsx_runtime26 = require("react/jsx-runtime");
6577
- function HeadingDropdownMenu({
6578
- editor: providedEditor,
6579
- levels = [1, 2, 3, 4, 5, 6],
6580
- hideWhenUnavailable = false,
6581
- onOpenChange,
6582
- ...props
6583
- }) {
6584
- var _a;
6585
- const [isOpen, setIsOpen] = React19.useState(false);
6586
- const { editor } = useTiptapEditor(providedEditor);
6587
- const headingInSchema = (0, import_editor_utils12.isNodeInSchema)("heading", editor);
6588
- const handleOnOpenChange = React19.useCallback(
6589
- (open) => {
6590
- setIsOpen(open);
6591
- onOpenChange == null ? void 0 : onOpenChange(open);
6592
- },
6593
- [onOpenChange]
6594
- );
6595
- const getActiveIcon = React19.useCallback(() => {
6596
- if (!editor) return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons20.HeadingIcon, {});
6597
- const activeLevel = levels.find(
6598
- (level) => editor.isActive("heading", { level })
6599
- );
6600
- if (!activeLevel) return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons20.HeadingIcon, {});
6601
- const ActiveIcon = headingIcons[activeLevel];
6602
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ActiveIcon, {});
6603
- }, [editor, levels]);
6604
- const canToggleAnyHeading = React19.useCallback(() => {
6605
- if (!editor) return false;
6606
- return levels.some(
6607
- (level) => editor.can().toggleNode("heading", "paragraph", { level })
6608
- );
6609
- }, [editor, levels]);
6610
- const isDisabled = !canToggleAnyHeading();
6611
- const isAnyHeadingActive = (_a = editor == null ? void 0 : editor.isActive("heading")) != null ? _a : false;
6612
- const show = React19.useMemo(() => {
6613
- if (!headingInSchema || !editor) {
6614
- return false;
6615
- }
6616
- if (hideWhenUnavailable) {
6617
- if ((0, import_react48.isNodeSelection)(editor.state.selection) || !canToggleAnyHeading()) {
6618
- return false;
6619
- }
6620
- }
6621
- return true;
6622
- }, [headingInSchema, editor, hideWhenUnavailable, canToggleAnyHeading]);
6623
- if (!show || !editor || !editor.isEditable) {
6624
- return null;
6625
- }
6626
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_dropdown_menu.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
6627
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_dropdown_menu.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6628
- import_button13.Button,
6629
- {
6630
- type: "button",
6631
- disabled: isDisabled,
6632
- variant: "ghost",
6633
- color: "default",
6634
- "data-active-state": isAnyHeadingActive ? "on" : "off",
6635
- "data-disabled": isDisabled,
6636
- tabIndex: -1,
6637
- "aria-label": "Format text as heading",
6638
- "aria-pressed": isAnyHeadingActive,
6639
- tooltip: "Heading",
6640
- endContent: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons20.ChevronDownIcon, {}),
6641
- ...props,
6642
- children: getActiveIcon()
6643
- }
6644
- ) }),
6645
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_dropdown_menu.DropdownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_dropdown_menu.DropdownMenu.Group, { children: levels.map((level) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_dropdown_menu.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6646
- HeadingButton,
6647
- {
6648
- editor,
6649
- level,
6650
- text: getFormattedHeadingName(level),
6651
- tooltip: "",
6652
- fullWidth: true,
6653
- spacing: "start"
6654
- }
6655
- ) }, `heading-${level}`)) }) })
6656
- ] });
6657
- }
6658
-
6659
- // src/ui/list-dropdown-menu/index.tsx
7201
+ // src/ui/heading-button/index.tsx
6660
7202
  var import_button15 = require("@kopexa/button");
6661
- var import_dropdown_menu2 = require("@kopexa/dropdown-menu");
6662
- var import_editor_utils14 = require("@kopexa/editor-utils");
7203
+ var import_editor_utils24 = require("@kopexa/editor-utils");
6663
7204
  var import_icons22 = require("@kopexa/icons");
6664
- var import_react51 = require("@tiptap/react");
6665
- var import_react52 = require("react");
7205
+ var React18 = __toESM(require("react"));
6666
7206
 
6667
- // src/ui/list-button/index.tsx
6668
- var import_button14 = require("@kopexa/button");
6669
- var import_editor_utils13 = require("@kopexa/editor-utils");
6670
- var import_icons21 = require("@kopexa/icons");
6671
- var import_react49 = require("@tiptap/react");
6672
- var import_react50 = require("react");
6673
- var import_jsx_runtime27 = require("react/jsx-runtime");
6674
- var listOptions = [
6675
- {
6676
- label: "Bullet List",
6677
- type: "bulletList",
6678
- icon: import_icons21.ListIcon
6679
- },
6680
- {
6681
- label: "Ordered List",
6682
- type: "orderedList",
6683
- icon: import_icons21.ListOrderedIcon
6684
- },
6685
- {
6686
- label: "Task List",
6687
- type: "taskList",
6688
- icon: import_icons21.ListTodoIcon
6689
- }
6690
- ];
6691
- var listShortcutKeys = {
6692
- bulletList: "Ctrl-Shift-8",
6693
- orderedList: "Ctrl-Shift-7",
6694
- taskList: "Ctrl-Shift-9"
7207
+ // src/ui/heading-button/utils.ts
7208
+ var import_react52 = require("@tiptap/react");
7209
+ var headingShortcutKeys = {
7210
+ 1: "Ctrl-Alt-1",
7211
+ 2: "Ctrl-Alt-2",
7212
+ 3: "Ctrl-Alt-3",
7213
+ 4: "Ctrl-Alt-4",
7214
+ 5: "Ctrl-Alt-5",
7215
+ 6: "Ctrl-Alt-6"
6695
7216
  };
6696
- function canToggleList(editor, type) {
6697
- if (!editor) {
7217
+ function canToggleHeading(editor, level) {
7218
+ if (!editor) return false;
7219
+ try {
7220
+ return editor.can().toggleNode("heading", "paragraph", { level });
7221
+ } catch {
6698
7222
  return false;
6699
7223
  }
6700
- switch (type) {
6701
- case "bulletList":
6702
- return editor.can().toggleBulletList();
6703
- case "orderedList":
6704
- return editor.can().toggleOrderedList();
6705
- case "taskList":
6706
- return editor.can().toggleList("taskList", "taskItem");
6707
- default:
6708
- return false;
6709
- }
6710
7224
  }
6711
- function isListActive(editor, type) {
7225
+ function isHeadingActive(editor, level) {
6712
7226
  if (!editor) return false;
6713
- switch (type) {
6714
- case "bulletList":
6715
- return editor.isActive("bulletList");
6716
- case "orderedList":
6717
- return editor.isActive("orderedList");
6718
- case "taskList":
6719
- return editor.isActive("taskList");
6720
- default:
6721
- return false;
6722
- }
7227
+ return editor.isActive("heading", { level });
6723
7228
  }
6724
- function toggleList(editor, type) {
7229
+ function toggleHeading(editor, level) {
6725
7230
  if (!editor) return;
6726
- switch (type) {
6727
- case "bulletList":
6728
- editor.chain().focus().toggleBulletList().run();
6729
- break;
6730
- case "orderedList":
6731
- editor.chain().focus().toggleOrderedList().run();
6732
- break;
6733
- case "taskList":
6734
- editor.chain().focus().toggleList("taskList", "taskItem").run();
6735
- break;
7231
+ if (editor.isActive("heading", { level })) {
7232
+ editor.chain().focus().setNode("paragraph").run();
7233
+ } else {
7234
+ editor.chain().focus().toggleNode("heading", "paragraph", { level }).run();
6736
7235
  }
6737
7236
  }
6738
- function getListOption(type) {
6739
- return listOptions.find((option) => option.type === type);
7237
+ function isHeadingButtonDisabled(editor, level, userDisabled = false) {
7238
+ if (!editor) return true;
7239
+ if (userDisabled) return true;
7240
+ if (!canToggleHeading(editor, level)) return true;
7241
+ return false;
6740
7242
  }
6741
- function shouldShowListButton(params) {
6742
- const { editor, type, hideWhenUnavailable, listInSchema } = params;
6743
- if (!listInSchema || !editor) {
7243
+ function shouldShowHeadingButton(params) {
7244
+ const { editor, hideWhenUnavailable, headingInSchema } = params;
7245
+ if (!headingInSchema || !editor) {
6744
7246
  return false;
6745
7247
  }
6746
7248
  if (hideWhenUnavailable) {
6747
- if ((0, import_react49.isNodeSelection)(editor.state.selection) || !canToggleList(editor, type)) {
7249
+ if ((0, import_react52.isNodeSelection)(editor.state.selection)) {
6748
7250
  return false;
6749
7251
  }
6750
7252
  }
6751
7253
  return true;
6752
7254
  }
6753
- function useListState(editor, type) {
6754
- const listInSchema = (0, import_editor_utils13.isNodeInSchema)(type, editor);
6755
- const listOption = getListOption(type);
6756
- const isActive = isListActive(editor, type);
6757
- const shortcutKey = listShortcutKeys[type];
7255
+ function getFormattedHeadingName(level) {
7256
+ return `Heading ${level}`;
7257
+ }
7258
+
7259
+ // src/ui/heading-button/index.tsx
7260
+ var import_jsx_runtime29 = require("react/jsx-runtime");
7261
+ var headingIcons = {
7262
+ 1: import_icons22.HeadingOneIcon,
7263
+ 2: import_icons22.HeadingTwoIcon,
7264
+ 3: import_icons22.HeadingThreeIcon,
7265
+ 4: import_icons22.HeadingFourIcon,
7266
+ 5: import_icons22.HeadingFiveIcon,
7267
+ 6: import_icons22.HeadingSixIcon
7268
+ };
7269
+ function useHeadingState(editor, level, disabled = false) {
7270
+ const headingInSchema = (0, import_editor_utils24.isNodeInSchema)("heading", editor);
7271
+ const isDisabled = isHeadingButtonDisabled(editor, level, disabled);
7272
+ const isActive = isHeadingActive(editor, level);
7273
+ const Icon = headingIcons[level];
7274
+ const shortcutKey = headingShortcutKeys[level];
7275
+ const formattedName = getFormattedHeadingName(level);
6758
7276
  return {
6759
- listInSchema,
6760
- listOption,
7277
+ headingInSchema,
7278
+ isDisabled,
6761
7279
  isActive,
6762
- shortcutKey
7280
+ Icon,
7281
+ shortcutKey,
7282
+ formattedName
6763
7283
  };
6764
7284
  }
6765
- var ListButton = ({
7285
+ var HeadingButton = ({
6766
7286
  editor: providedEditor,
6767
- type,
7287
+ level,
7288
+ text,
6768
7289
  hideWhenUnavailable = false,
6769
7290
  className = "",
7291
+ disabled,
6770
7292
  onClick,
6771
- text,
6772
7293
  children,
6773
7294
  ref,
6774
7295
  ...buttonProps
6775
7296
  }) => {
6776
- const { editor } = useTiptapEditor(providedEditor);
6777
- const { listInSchema, listOption, isActive, shortcutKey } = useListState(
6778
- editor,
6779
- type
6780
- );
6781
- const Icon = (listOption == null ? void 0 : listOption.icon) || import_icons21.ListIcon;
6782
- const handleClick = (0, import_react50.useCallback)(
7297
+ const { editor } = (0, import_editor_utils24.useTiptapEditor)(providedEditor);
7298
+ const {
7299
+ headingInSchema,
7300
+ isDisabled,
7301
+ isActive,
7302
+ Icon,
7303
+ shortcutKey,
7304
+ formattedName
7305
+ } = useHeadingState(editor, level, disabled);
7306
+ const handleClick = React18.useCallback(
6783
7307
  (e) => {
6784
7308
  onClick == null ? void 0 : onClick(e);
6785
- if (!e.defaultPrevented && editor) {
6786
- toggleList(editor, type);
7309
+ if (!e.defaultPrevented && !isDisabled && editor) {
7310
+ toggleHeading(editor, level);
6787
7311
  }
6788
7312
  },
6789
- [onClick, editor, type]
7313
+ [onClick, isDisabled, editor, level]
6790
7314
  );
6791
- const show = (0, import_react50.useMemo)(() => {
6792
- return shouldShowListButton({
7315
+ const show = React18.useMemo(() => {
7316
+ return shouldShowHeadingButton({
6793
7317
  editor,
6794
- type,
7318
+ level,
6795
7319
  hideWhenUnavailable,
6796
- listInSchema
7320
+ headingInSchema
6797
7321
  });
6798
- }, [editor, type, hideWhenUnavailable, listInSchema]);
7322
+ }, [editor, level, hideWhenUnavailable, headingInSchema]);
6799
7323
  if (!show || !editor || !editor.isEditable) {
6800
7324
  return null;
6801
7325
  }
6802
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
6803
- import_button14.Button,
7326
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7327
+ import_button15.Button,
6804
7328
  {
6805
7329
  type: "button",
6806
7330
  className: className.trim(),
7331
+ disabled: isDisabled,
6807
7332
  variant: "ghost",
6808
7333
  color: "default",
6809
7334
  "data-active-state": isActive ? "on" : "off",
7335
+ "data-disabled": isDisabled,
6810
7336
  tabIndex: -1,
6811
- "aria-label": (listOption == null ? void 0 : listOption.label) || type,
7337
+ "aria-label": formattedName,
6812
7338
  "aria-pressed": isActive,
6813
- tooltip: (listOption == null ? void 0 : listOption.label) || type,
7339
+ tooltip: formattedName,
6814
7340
  shortcutKeys: shortcutKey,
6815
7341
  onClick: handleClick,
6816
- startContent: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Icon, {}),
7342
+ startContent: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon, {}),
6817
7343
  ...buttonProps,
6818
7344
  ref,
6819
7345
  children: children || text
@@ -6821,161 +7347,189 @@ var ListButton = ({
6821
7347
  );
6822
7348
  };
6823
7349
 
6824
- // src/ui/list-dropdown-menu/index.tsx
6825
- var import_jsx_runtime28 = require("react/jsx-runtime");
6826
- function canToggleAnyList(editor, listTypes) {
7350
+ // src/ui/text-button/text-button.tsx
7351
+ var import_button16 = require("@kopexa/button");
7352
+ var import_chip = require("@kopexa/chip");
7353
+ var import_editor_utils26 = require("@kopexa/editor-utils");
7354
+ var import_shared_utils = require("@kopexa/shared-utils");
7355
+ var import_react54 = require("react");
7356
+
7357
+ // src/ui/text-button/use-text.ts
7358
+ var import_editor_utils25 = require("@kopexa/editor-utils");
7359
+ var import_icons23 = require("@kopexa/icons");
7360
+ var import_use_is_mobile2 = require("@kopexa/use-is-mobile");
7361
+ var import_state9 = require("@tiptap/pm/state");
7362
+ var import_react53 = require("react");
7363
+ var import_react_hotkeys_hook2 = require("react-hotkeys-hook");
7364
+ var TEXT_SHORTCUT_KEY = "mod+alt+0";
7365
+ function canToggleText(editor, turnInto = true) {
6827
7366
  if (!editor) return false;
6828
- return listTypes.some((type) => canToggleList(editor, type));
7367
+ if (!editor.schema.nodes.paragraph) return false;
7368
+ if (!turnInto) {
7369
+ return editor.can().setNode("paragraph");
7370
+ }
7371
+ if (!(0, import_editor_utils25.selectionWithinConvertibleTypes)(editor, [
7372
+ "paragraph",
7373
+ "heading",
7374
+ "bulletList",
7375
+ "orderedList",
7376
+ "taskList",
7377
+ "blockquote",
7378
+ "codeBlock"
7379
+ ]))
7380
+ return false;
7381
+ return editor.can().setNode("paragraph") || editor.can().clearNodes();
6829
7382
  }
6830
- function isAnyListActive(editor, listTypes) {
7383
+ function isParagraphActive(editor) {
6831
7384
  if (!editor) return false;
6832
- return listTypes.some((type) => isListActive(editor, type));
6833
- }
6834
- function getFilteredListOptions(availableTypes) {
6835
- return listOptions.filter(
6836
- (option) => !option.type || availableTypes.includes(option.type)
6837
- );
7385
+ return editor.isActive("paragraph");
6838
7386
  }
6839
- function shouldShowListDropdown(params) {
6840
- const { editor, hideWhenUnavailable, listInSchema, canToggleAny } = params;
6841
- if (!listInSchema || !editor) {
7387
+ function toggleParagraph(editor) {
7388
+ var _a, _b, _c;
7389
+ if (!editor || !editor.isEditable) return false;
7390
+ if (!canToggleText(editor)) return false;
7391
+ try {
7392
+ const view = editor.view;
7393
+ let state = view.state;
7394
+ let tr = state.tr;
7395
+ const blocks = (0, import_editor_utils25.getSelectedBlockNodes)(editor);
7396
+ const isPossibleToTurnInto = (0, import_editor_utils25.selectionWithinConvertibleTypes)(editor, [
7397
+ "paragraph",
7398
+ "heading",
7399
+ "bulletList",
7400
+ "orderedList",
7401
+ "taskList",
7402
+ "blockquote",
7403
+ "codeBlock"
7404
+ ]) && blocks.length === 1;
7405
+ if ((state.selection.empty || state.selection instanceof import_state9.TextSelection) && isPossibleToTurnInto) {
7406
+ const pos = (_a = (0, import_editor_utils25.findNodePosition)({
7407
+ editor,
7408
+ node: state.selection.$anchor.node(1)
7409
+ })) == null ? void 0 : _a.pos;
7410
+ if (!(0, import_editor_utils25.isValidPosition)(pos)) return false;
7411
+ tr = tr.setSelection(import_state9.NodeSelection.create(state.doc, pos));
7412
+ view.dispatch(tr);
7413
+ state = view.state;
7414
+ }
7415
+ const selection = state.selection;
7416
+ let chain = editor.chain().focus();
7417
+ if (selection instanceof import_state9.NodeSelection) {
7418
+ const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
7419
+ const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
7420
+ const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
7421
+ const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
7422
+ const resolvedFrom = state.doc.resolve(from);
7423
+ const resolvedTo = state.doc.resolve(to);
7424
+ chain = chain.setTextSelection(import_state9.TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
7425
+ }
7426
+ if (!editor.isActive("paragraph")) {
7427
+ chain.setNode("paragraph").run();
7428
+ }
7429
+ editor.chain().focus().selectTextblockEnd().run();
7430
+ return true;
7431
+ } catch {
6842
7432
  return false;
6843
7433
  }
6844
- if (hideWhenUnavailable) {
6845
- if ((0, import_react51.isNodeSelection)(editor.state.selection) || !canToggleAny) {
6846
- return false;
6847
- }
7434
+ }
7435
+ function shouldShowButton6(props) {
7436
+ const { editor, hideWhenUnavailable } = props;
7437
+ if (!editor || !editor.isEditable) return false;
7438
+ if (!hideWhenUnavailable) {
7439
+ return true;
7440
+ }
7441
+ if (!(0, import_editor_utils25.isNodeInSchema)("paragraph", editor)) return false;
7442
+ if (!editor.isActive("code")) {
7443
+ return canToggleText(editor);
6848
7444
  }
6849
7445
  return true;
6850
7446
  }
6851
- function useListDropdownState(editor, availableTypes) {
6852
- const [isOpen, setIsOpen] = (0, import_react52.useState)(false);
6853
- const listInSchema = availableTypes.some(
6854
- (type) => (0, import_editor_utils14.isNodeInSchema)(type, editor)
6855
- );
6856
- const filteredLists = (0, import_react52.useMemo)(
6857
- () => getFilteredListOptions(availableTypes),
6858
- [availableTypes]
6859
- );
6860
- const canToggleAny = canToggleAnyList(editor, availableTypes);
6861
- const isAnyActive = isAnyListActive(editor, availableTypes);
6862
- const handleOpenChange = (0, import_react52.useCallback)(
6863
- (open, callback) => {
6864
- setIsOpen(open);
6865
- callback == null ? void 0 : callback(open);
6866
- },
6867
- []
6868
- );
6869
- return {
6870
- isOpen,
6871
- setIsOpen,
6872
- listInSchema,
6873
- filteredLists,
6874
- canToggleAny,
6875
- isAnyActive,
6876
- handleOpenChange
6877
- };
6878
- }
6879
- function useActiveListIcon(editor, filteredLists) {
6880
- return (0, import_react52.useCallback)(() => {
6881
- const activeOption = filteredLists.find(
6882
- (option) => isListActive(editor, option.type)
6883
- );
6884
- return activeOption ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(activeOption.icon, {}) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons22.ListIcon, {});
6885
- }, [editor, filteredLists]);
6886
- }
6887
- function ListDropdownMenu({
6888
- editor: providedEditor,
6889
- types = ["bulletList", "orderedList", "taskList"],
6890
- hideWhenUnavailable = false,
6891
- onOpenChange,
6892
- ...props
6893
- }) {
6894
- const { editor } = useTiptapEditor(providedEditor);
7447
+ function useText(config) {
6895
7448
  const {
6896
- isOpen,
6897
- listInSchema,
6898
- filteredLists,
6899
- canToggleAny,
6900
- isAnyActive,
6901
- handleOpenChange
6902
- } = useListDropdownState(editor, types);
6903
- const getActiveIcon = useActiveListIcon(editor, filteredLists);
6904
- const show = (0, import_react52.useMemo)(() => {
6905
- return shouldShowListDropdown({
6906
- editor,
6907
- listTypes: types,
6908
- hideWhenUnavailable,
6909
- listInSchema,
6910
- canToggleAny
6911
- });
6912
- }, [editor, types, hideWhenUnavailable, listInSchema, canToggleAny]);
6913
- const handleOnOpenChange = (0, import_react52.useCallback)(
6914
- (open) => handleOpenChange(open, onOpenChange),
6915
- [handleOpenChange, onOpenChange]
6916
- );
6917
- if (!show || !editor || !editor.isEditable) {
6918
- return null;
6919
- }
6920
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_dropdown_menu2.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
6921
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_dropdown_menu2.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
6922
- import_button15.Button,
6923
- {
6924
- type: "button",
6925
- variant: "ghost",
6926
- color: "default",
6927
- "data-active-state": isAnyActive ? "on" : "off",
6928
- tabIndex: -1,
6929
- "aria-label": "List options",
6930
- tooltip: "List",
6931
- endContent: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons22.ChevronDownIcon, {}),
6932
- ...props,
6933
- children: getActiveIcon()
6934
- }
6935
- ) }),
6936
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_dropdown_menu2.DropdownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_dropdown_menu2.DropdownMenu.Group, { children: filteredLists.map((option) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
6937
- ListButton,
6938
- {
6939
- editor,
6940
- type: option.type,
6941
- text: option.label,
6942
- hideWhenUnavailable,
6943
- tooltip: "",
6944
- fullWidth: true,
6945
- spacing: "start"
6946
- }
6947
- ) }, option.type)) }) })
6948
- ] });
7449
+ editor: providedEditor,
7450
+ hideWhenUnavailable = false,
7451
+ onToggled
7452
+ } = config || {};
7453
+ const { editor } = (0, import_editor_utils25.useTiptapEditor)(providedEditor);
7454
+ const isMobile = (0, import_use_is_mobile2.useIsMobile)();
7455
+ const [isVisible, setIsVisible] = (0, import_react53.useState)(true);
7456
+ const canToggle3 = canToggleText(editor);
7457
+ const isActive = isParagraphActive(editor);
7458
+ (0, import_react53.useEffect)(() => {
7459
+ if (!editor) return;
7460
+ const handleSelectionUpdate = () => {
7461
+ setIsVisible(shouldShowButton6({ editor, hideWhenUnavailable }));
7462
+ };
7463
+ handleSelectionUpdate();
7464
+ editor.on("selectionUpdate", handleSelectionUpdate);
7465
+ return () => {
7466
+ editor.off("selectionUpdate", handleSelectionUpdate);
7467
+ };
7468
+ }, [editor, hideWhenUnavailable]);
7469
+ const handleToggle = (0, import_react53.useCallback)(() => {
7470
+ if (!editor) return false;
7471
+ const success = toggleParagraph(editor);
7472
+ if (success) {
7473
+ onToggled == null ? void 0 : onToggled();
7474
+ }
7475
+ return success;
7476
+ }, [editor, onToggled]);
7477
+ (0, import_react_hotkeys_hook2.useHotkeys)(
7478
+ TEXT_SHORTCUT_KEY,
7479
+ (event) => {
7480
+ event.preventDefault();
7481
+ handleToggle();
7482
+ },
7483
+ {
7484
+ enabled: isVisible && canToggle3,
7485
+ enableOnContentEditable: !isMobile,
7486
+ enableOnFormTags: true
7487
+ }
7488
+ );
7489
+ return {
7490
+ isVisible,
7491
+ isActive,
7492
+ handleToggle,
7493
+ canToggle: canToggle3,
7494
+ label: "Text",
7495
+ shortcutKeys: TEXT_SHORTCUT_KEY,
7496
+ Icon: import_icons23.TypeIcon
7497
+ };
6949
7498
  }
6950
7499
 
6951
- // src/ui/table-button/index.tsx
6952
- var import_toolbar8 = require("@kopexa/toolbar");
6953
- var import_react53 = require("react");
6954
- var import_jsx_runtime29 = require("react/jsx-runtime");
6955
- var TableButton = ({
7500
+ // src/ui/text-button/text-button.tsx
7501
+ var import_jsx_runtime30 = require("react/jsx-runtime");
7502
+ function TextShortcutBadge({
7503
+ shortcutKeys = TEXT_SHORTCUT_KEY
7504
+ }) {
7505
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_chip.Chip, { children: (0, import_shared_utils.parseShortcutKeys)({ shortcutKeys }) });
7506
+ }
7507
+ var TextButton = ({
6956
7508
  editor: providedEditor,
6957
7509
  text,
6958
7510
  hideWhenUnavailable = false,
6959
7511
  onToggled,
7512
+ showShortcut = false,
6960
7513
  onClick,
6961
7514
  children,
7515
+ ref,
6962
7516
  ...buttonProps
6963
7517
  }) => {
6964
- const { editor } = useTiptapEditor(providedEditor);
7518
+ const { editor } = (0, import_editor_utils26.useTiptapEditor)(providedEditor);
6965
7519
  const {
6966
7520
  isVisible,
6967
7521
  canToggle: canToggle3,
6968
7522
  isActive,
6969
7523
  handleToggle,
6970
7524
  label,
6971
- // shortcutKeys,
7525
+ shortcutKeys,
6972
7526
  Icon
6973
- } = useTableBlock({
7527
+ } = useText({
6974
7528
  editor,
6975
7529
  hideWhenUnavailable,
6976
7530
  onToggled
6977
7531
  });
6978
- const handleClick = (0, import_react53.useCallback)(
7532
+ const handleClick = (0, import_react54.useCallback)(
6979
7533
  (event) => {
6980
7534
  onClick == null ? void 0 : onClick(event);
6981
7535
  if (event.defaultPrevented) return;
@@ -6986,196 +7540,343 @@ var TableButton = ({
6986
7540
  if (!isVisible) {
6987
7541
  return null;
6988
7542
  }
6989
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6990
- import_toolbar8.ToolbarButton,
7543
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7544
+ import_button16.Button,
6991
7545
  {
6992
7546
  type: "button",
6993
7547
  variant: "ghost",
6994
7548
  color: "default",
6995
7549
  "data-active-state": isActive ? "on" : "off",
7550
+ tabIndex: -1,
6996
7551
  disabled: !canToggle3,
6997
7552
  "data-disabled": !canToggle3,
6998
- tabIndex: -1,
6999
7553
  "aria-label": label,
7000
7554
  "aria-pressed": isActive,
7001
- title: label,
7555
+ tooltip: "Text",
7556
+ shortcutKeys,
7002
7557
  onClick: handleClick,
7003
- isIconOnly: !text && !children,
7558
+ startContent: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon, {}),
7004
7559
  ...buttonProps,
7005
- children: children || /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
7006
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon, {}),
7007
- text && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: text })
7560
+ ref,
7561
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
7562
+ text,
7563
+ showShortcut && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TextShortcutBadge, { shortcutKeys })
7008
7564
  ] })
7009
7565
  }
7010
7566
  );
7011
7567
  };
7012
7568
 
7013
- // src/ui/text-align-button/text-align-button.tsx
7014
- var import_button16 = require("@kopexa/button");
7569
+ // src/ui/turn-into-dropdown/use-turn-into-dropdown.ts
7570
+ var import_editor_utils27 = require("@kopexa/editor-utils");
7571
+ var import_icons24 = require("@kopexa/icons");
7572
+ var import_state10 = require("@tiptap/pm/state");
7015
7573
  var import_react55 = require("react");
7016
-
7017
- // src/ui/text-align-button/use-text-align.ts
7018
- var import_editor_utils15 = require("@kopexa/editor-utils");
7019
- var import_icons23 = require("@kopexa/icons");
7020
- var import_react54 = require("react");
7021
- var TEXT_ALIGN_SHORTCUT_KEYS = {
7022
- left: "mod+shift+l",
7023
- center: "mod+shift+e",
7024
- right: "mod+shift+r",
7025
- justify: "mod+shift+j"
7026
- };
7027
- var textAlignIcons = {
7028
- left: import_icons23.AlignLeftIcon,
7029
- center: import_icons23.AlignCenterIcon,
7030
- right: import_icons23.AlignRightIcon,
7031
- justify: import_icons23.AlignJustifyIcon
7032
- };
7033
- var textAlignLabels = {
7034
- left: "Align left",
7035
- center: "Align center",
7036
- right: "Align right",
7037
- justify: "Align justify"
7038
- };
7039
- function canSetTextAlign(editor, align) {
7574
+ var TURN_INTO_BLOCKS = [
7575
+ "paragraph",
7576
+ "heading",
7577
+ "bulletList",
7578
+ "orderedList",
7579
+ "taskList",
7580
+ "blockquote",
7581
+ "codeBlock"
7582
+ ];
7583
+ var blockTypeOptions = [
7584
+ {
7585
+ type: "paragraph",
7586
+ label: "Text",
7587
+ isActive: (editor) => editor.isActive("paragraph") && !editor.isActive("heading") && !editor.isActive("bulletList") && !editor.isActive("orderedList") && !editor.isActive("taskList") && !editor.isActive("blockquote") && !editor.isActive("codeBlock")
7588
+ },
7589
+ {
7590
+ type: "heading",
7591
+ label: "Heading 1",
7592
+ level: 1,
7593
+ isActive: (editor) => editor.isActive("heading", { level: 1 })
7594
+ },
7595
+ {
7596
+ type: "heading",
7597
+ label: "Heading 2",
7598
+ level: 2,
7599
+ isActive: (editor) => editor.isActive("heading", { level: 2 })
7600
+ },
7601
+ {
7602
+ type: "heading",
7603
+ label: "Heading 3",
7604
+ level: 3,
7605
+ isActive: (editor) => editor.isActive("heading", { level: 3 })
7606
+ },
7607
+ {
7608
+ type: "heading",
7609
+ label: "Heading 4",
7610
+ level: 4,
7611
+ isActive: (editor) => editor.isActive("heading", { level: 4 })
7612
+ },
7613
+ {
7614
+ type: "bulletList",
7615
+ label: "Bulleted list",
7616
+ isActive: (editor) => editor.isActive("bulletList")
7617
+ },
7618
+ {
7619
+ type: "orderedList",
7620
+ label: "Numbered list",
7621
+ isActive: (editor) => editor.isActive("orderedList")
7622
+ },
7623
+ {
7624
+ type: "taskList",
7625
+ label: "To-do list",
7626
+ isActive: (editor) => editor.isActive("taskList")
7627
+ },
7628
+ {
7629
+ type: "blockquote",
7630
+ label: "Blockquote",
7631
+ isActive: (editor) => editor.isActive("blockquote")
7632
+ },
7633
+ {
7634
+ type: "codeBlock",
7635
+ label: "Code block",
7636
+ isActive: (editor) => editor.isActive("codeBlock")
7637
+ }
7638
+ ];
7639
+ function canTurnInto(editor, allowedBlockTypes) {
7040
7640
  if (!editor || !editor.isEditable) return false;
7041
- if (!(0, import_editor_utils15.isExtensionAvailable)(editor, "textAlign") || (0, import_editor_utils15.isNodeTypeSelected)(editor, ["image"]))
7042
- return false;
7043
- return editor.can().setTextAlign(align);
7044
- }
7045
- function hasSetTextAlign(commands) {
7046
- return "setTextAlign" in commands;
7641
+ const blockTypes = allowedBlockTypes || TURN_INTO_BLOCKS;
7642
+ const { selection } = editor.state;
7643
+ if (selection instanceof import_state10.NodeSelection) {
7644
+ const nodeType2 = selection.node.type.name;
7645
+ return blockTypes.includes(nodeType2);
7646
+ }
7647
+ const { $anchor } = selection;
7648
+ const nodeType = $anchor.parent.type.name;
7649
+ return blockTypes.includes(nodeType);
7047
7650
  }
7048
- function isTextAlignActive(editor, align) {
7049
- if (!editor || !editor.isEditable) return false;
7050
- return editor.isActive({ textAlign: align });
7651
+ function getFilteredBlockTypeOptions(blockTypes) {
7652
+ if (!blockTypes) return blockTypeOptions;
7653
+ return blockTypeOptions.filter((option) => {
7654
+ return blockTypes.includes(option.type);
7655
+ });
7051
7656
  }
7052
- function setTextAlign(editor, align) {
7053
- if (!editor || !editor.isEditable) return false;
7054
- if (!canSetTextAlign(editor, align)) return false;
7055
- const chain = editor.chain().focus();
7056
- if (hasSetTextAlign(chain)) {
7057
- return chain.setTextAlign(align).run();
7058
- }
7059
- return false;
7657
+ function getActiveBlockType(editor, blockTypes) {
7658
+ if (!editor) return getFilteredBlockTypeOptions(blockTypes)[0];
7659
+ const filteredOptions = getFilteredBlockTypeOptions(blockTypes);
7660
+ const activeOption = filteredOptions.find(
7661
+ (option) => option.isActive(editor)
7662
+ );
7663
+ return activeOption || filteredOptions[0];
7060
7664
  }
7061
- function shouldShowButton5(props) {
7062
- const { editor, hideWhenUnavailable, align } = props;
7665
+ function shouldShowTurnInto(params) {
7666
+ const { editor, hideWhenUnavailable, blockTypes } = params;
7063
7667
  if (!editor || !editor.isEditable) return false;
7064
- if (!(0, import_editor_utils15.isExtensionAvailable)(editor, "textAlign")) return false;
7065
7668
  if (hideWhenUnavailable && !editor.isActive("code")) {
7066
- return canSetTextAlign(editor, align);
7669
+ return canTurnInto(editor, blockTypes);
7067
7670
  }
7068
7671
  return true;
7069
7672
  }
7070
- function useTextAlign(config) {
7673
+ function useTurnIntoDropdown(config) {
7071
7674
  const {
7072
7675
  editor: providedEditor,
7073
- align,
7074
7676
  hideWhenUnavailable = false,
7075
- onAligned
7076
- } = config;
7077
- const { editor } = useTiptapEditor(providedEditor);
7078
- const [isVisible, setIsVisible] = (0, import_react54.useState)(true);
7079
- const canAlign = canSetTextAlign(editor, align);
7080
- const isActive = isTextAlignActive(editor, align);
7081
- (0, import_react54.useEffect)(() => {
7677
+ blockTypes,
7678
+ onOpenChange
7679
+ } = config || {};
7680
+ const { editor } = (0, import_editor_utils27.useTiptapEditor)(providedEditor);
7681
+ const [isOpen, setIsOpen] = (0, import_react55.useState)(false);
7682
+ const [isVisible, setIsVisible] = (0, import_react55.useState)(true);
7683
+ const canToggle3 = canTurnInto(editor, blockTypes);
7684
+ const activeBlockType = getActiveBlockType(editor, blockTypes);
7685
+ const handleOpenChange = (0, import_react55.useCallback)(
7686
+ (open) => {
7687
+ if (!editor || !canToggle3) return;
7688
+ setIsOpen(open);
7689
+ onOpenChange == null ? void 0 : onOpenChange(open);
7690
+ },
7691
+ [canToggle3, editor, onOpenChange]
7692
+ );
7693
+ (0, import_react55.useEffect)(() => {
7082
7694
  if (!editor) return;
7083
7695
  const handleSelectionUpdate = () => {
7084
- setIsVisible(shouldShowButton5({ editor, align, hideWhenUnavailable }));
7696
+ setIsVisible(
7697
+ shouldShowTurnInto({
7698
+ editor,
7699
+ hideWhenUnavailable,
7700
+ blockTypes
7701
+ })
7702
+ );
7085
7703
  };
7086
7704
  handleSelectionUpdate();
7087
7705
  editor.on("selectionUpdate", handleSelectionUpdate);
7088
7706
  return () => {
7089
7707
  editor.off("selectionUpdate", handleSelectionUpdate);
7090
7708
  };
7091
- }, [editor, hideWhenUnavailable, align]);
7092
- const handleTextAlign = (0, import_react54.useCallback)(() => {
7093
- if (!editor) return false;
7094
- const success = setTextAlign(editor, align);
7095
- if (success) {
7096
- onAligned == null ? void 0 : onAligned();
7097
- }
7098
- return success;
7099
- }, [editor, align, onAligned]);
7709
+ }, [editor, hideWhenUnavailable, blockTypes]);
7100
7710
  return {
7101
7711
  isVisible,
7102
- isActive,
7103
- handleTextAlign,
7104
- canAlign,
7105
- label: textAlignLabels[align],
7106
- shortcutKeys: TEXT_ALIGN_SHORTCUT_KEYS[align],
7107
- Icon: textAlignIcons[align]
7712
+ canToggle: canToggle3,
7713
+ isOpen,
7714
+ setIsOpen,
7715
+ activeBlockType,
7716
+ handleOpenChange,
7717
+ filteredOptions: getFilteredBlockTypeOptions(blockTypes),
7718
+ label: `Turn into (current: ${(activeBlockType == null ? void 0 : activeBlockType.label) || "Text"})`,
7719
+ Icon: import_icons24.ChevronDownIcon
7108
7720
  };
7109
7721
  }
7110
7722
 
7111
- // src/ui/text-align-button/text-align-button.tsx
7112
- var import_jsx_runtime30 = require("react/jsx-runtime");
7113
- var TextAlignButton = ({
7114
- editor: providedEditor,
7115
- align,
7116
- text,
7117
- hideWhenUnavailable = false,
7118
- onAligned,
7119
- showShortcut = false,
7120
- onClick,
7121
- children,
7122
- ...buttonProps
7123
- }) => {
7124
- const { editor } = useTiptapEditor(providedEditor);
7125
- const {
7126
- isVisible,
7127
- handleTextAlign,
7128
- label,
7129
- canAlign,
7130
- isActive,
7131
- Icon,
7132
- shortcutKeys
7133
- } = useTextAlign({
7134
- editor,
7135
- align,
7136
- hideWhenUnavailable,
7137
- onAligned
7138
- });
7139
- const handleClick = (0, import_react55.useCallback)(
7140
- (e) => {
7141
- onClick == null ? void 0 : onClick(e);
7142
- if (e.defaultPrevented) return;
7143
- handleTextAlign();
7144
- },
7145
- [handleTextAlign, onClick]
7146
- );
7147
- if (!isVisible) {
7148
- return null;
7149
- }
7150
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7151
- import_button16.IconButton,
7152
- {
7153
- type: "button",
7154
- disabled: canAlign,
7155
- variant: "ghost",
7156
- color: "default",
7157
- "data-active-state": isActive ? "on" : "off",
7158
- "data-disabled": canAlign,
7159
- tabIndex: -1,
7160
- "aria-label": label,
7161
- "aria-pressed": isActive,
7162
- tooltip: label,
7163
- shortcutKeys,
7164
- onClick: handleClick,
7165
- ...buttonProps,
7166
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon, {})
7723
+ // src/ui/turn-into-dropdown/turn-into-dropdown.tsx
7724
+ var import_jsx_runtime31 = require("react/jsx-runtime");
7725
+ var TurnIntoDropdownContent = ({ blockTypes }) => {
7726
+ const filteredOptions = getFilteredBlockTypeOptions(blockTypes);
7727
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Group, { children: filteredOptions.map(
7728
+ (option, index) => {
7729
+ var _a;
7730
+ return renderBlockTypeButton(
7731
+ option,
7732
+ `${option.type}-${(_a = option.level) != null ? _a : index}`
7733
+ );
7167
7734
  }
7168
- );
7735
+ ) });
7169
7736
  };
7737
+ function renderBlockTypeButton(option, key) {
7738
+ switch (option.type) {
7739
+ case "paragraph":
7740
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7741
+ TextButton,
7742
+ {
7743
+ fullWidth: true,
7744
+ spacing: "start",
7745
+ tooltip: "",
7746
+ text: option.label
7747
+ }
7748
+ ) }, key);
7749
+ case "heading":
7750
+ if (!option.level) {
7751
+ return null;
7752
+ }
7753
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7754
+ HeadingButton,
7755
+ {
7756
+ level: option.level || 1,
7757
+ fullWidth: true,
7758
+ spacing: "start",
7759
+ tooltip: "",
7760
+ text: option.label
7761
+ }
7762
+ ) }, key);
7763
+ case "bulletList":
7764
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7765
+ ListButton,
7766
+ {
7767
+ type: "bulletList",
7768
+ fullWidth: true,
7769
+ spacing: "start",
7770
+ tooltip: "",
7771
+ text: option.label
7772
+ }
7773
+ ) }, key);
7774
+ case "orderedList":
7775
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7776
+ ListButton,
7777
+ {
7778
+ type: "orderedList",
7779
+ fullWidth: true,
7780
+ spacing: "start",
7781
+ tooltip: "",
7782
+ text: option.label
7783
+ }
7784
+ ) }, key);
7785
+ case "taskList":
7786
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7787
+ ListButton,
7788
+ {
7789
+ type: "taskList",
7790
+ fullWidth: true,
7791
+ spacing: "start",
7792
+ tooltip: "",
7793
+ text: option.label
7794
+ }
7795
+ ) }, key);
7796
+ case "blockquote":
7797
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7798
+ BlockquoteButton,
7799
+ {
7800
+ className: "w-full justify-start",
7801
+ title: "",
7802
+ tooltip: "",
7803
+ text: option.label
7804
+ }
7805
+ ) }, key);
7806
+ case "codeBlock":
7807
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7808
+ CodeBlockButton,
7809
+ {
7810
+ className: "w-full justify-start",
7811
+ title: "",
7812
+ tooltip: "",
7813
+ text: option.label
7814
+ }
7815
+ ) }, key);
7816
+ default:
7817
+ return null;
7818
+ }
7819
+ }
7820
+ var TurnIntoDropdown = (0, import_react56.forwardRef)(
7821
+ ({
7822
+ editor: providedEditor,
7823
+ hideWhenUnavailable = false,
7824
+ blockTypes,
7825
+ onOpenChange,
7826
+ children,
7827
+ ...buttonProps
7828
+ }, ref) => {
7829
+ const { editor } = (0, import_editor_utils28.useTiptapEditor)(providedEditor);
7830
+ const {
7831
+ isVisible,
7832
+ canToggle: canToggle3,
7833
+ isOpen,
7834
+ activeBlockType,
7835
+ handleOpenChange,
7836
+ label,
7837
+ Icon
7838
+ } = useTurnIntoDropdown({
7839
+ editor,
7840
+ hideWhenUnavailable,
7841
+ blockTypes,
7842
+ onOpenChange
7843
+ });
7844
+ if (!isVisible) {
7845
+ return null;
7846
+ }
7847
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_dropdown_menu2.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOpenChange, children: [
7848
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7849
+ import_button17.Button,
7850
+ {
7851
+ type: "button",
7852
+ variant: "ghost",
7853
+ color: "default",
7854
+ disabled: !canToggle3,
7855
+ "data-disabled": !canToggle3,
7856
+ tabIndex: -1,
7857
+ "aria-label": label,
7858
+ tooltip: "Turn into",
7859
+ endContent: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Icon, {}),
7860
+ ...buttonProps,
7861
+ ref,
7862
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { children: (activeBlockType == null ? void 0 : activeBlockType.label) || "Text" })
7863
+ }
7864
+ ) }),
7865
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Content, { align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TurnIntoDropdownContent, { blockTypes }) })
7866
+ ] });
7867
+ }
7868
+ );
7869
+ TurnIntoDropdown.displayName = "TurnIntoDropdown";
7170
7870
 
7171
7871
  // src/ui/undo-redo-button/undo-redo-button.tsx
7872
+ var import_editor_utils30 = require("@kopexa/editor-utils");
7172
7873
  var import_toolbar9 = require("@kopexa/toolbar");
7173
- var import_react57 = require("react");
7874
+ var import_react58 = require("react");
7174
7875
 
7175
7876
  // src/ui/undo-redo-button/use-undo-redo.ts
7176
- var import_editor_utils16 = require("@kopexa/editor-utils");
7177
- var import_icons24 = require("@kopexa/icons");
7178
- var import_react56 = require("react");
7877
+ var import_editor_utils29 = require("@kopexa/editor-utils");
7878
+ var import_icons25 = require("@kopexa/icons");
7879
+ var import_react57 = require("react");
7179
7880
  var UNDO_REDO_SHORTCUT_KEYS = {
7180
7881
  undo: "mod+z",
7181
7882
  redo: "mod+shift+z"
@@ -7185,12 +7886,12 @@ var historyActionLabels = {
7185
7886
  redo: "Redo"
7186
7887
  };
7187
7888
  var historyIcons = {
7188
- undo: import_icons24.UndoIcon,
7189
- redo: import_icons24.RedoIcon
7889
+ undo: import_icons25.UndoIcon,
7890
+ redo: import_icons25.RedoIcon
7190
7891
  };
7191
7892
  function canExecuteUndoRedoAction(editor, action) {
7192
7893
  if (!editor || !editor.isEditable) return false;
7193
- if ((0, import_editor_utils16.isNodeTypeSelected)(editor, ["image"])) return false;
7894
+ if ((0, import_editor_utils29.isNodeTypeSelected)(editor, ["image"])) return false;
7194
7895
  return action === "undo" ? editor.can().undo() : editor.can().redo();
7195
7896
  }
7196
7897
  function executeUndoRedoAction(editor, action) {
@@ -7199,7 +7900,7 @@ function executeUndoRedoAction(editor, action) {
7199
7900
  const chain = editor.chain().focus();
7200
7901
  return action === "undo" ? chain.undo().run() : chain.redo().run();
7201
7902
  }
7202
- function shouldShowButton6(props) {
7903
+ function shouldShowButton7(props) {
7203
7904
  const { editor, hideWhenUnavailable, action } = props;
7204
7905
  if (!editor || !editor.isEditable) return false;
7205
7906
  if (hideWhenUnavailable && !editor.isActive("code")) {
@@ -7214,13 +7915,13 @@ function useUndoRedo(config) {
7214
7915
  hideWhenUnavailable = false,
7215
7916
  onExecuted
7216
7917
  } = config;
7217
- const { editor } = useTiptapEditor(providedEditor);
7218
- const [isVisible, setIsVisible] = (0, import_react56.useState)(true);
7918
+ const { editor } = (0, import_editor_utils29.useTiptapEditor)(providedEditor);
7919
+ const [isVisible, setIsVisible] = (0, import_react57.useState)(true);
7219
7920
  const canExecute = canExecuteUndoRedoAction(editor, action);
7220
- (0, import_react56.useEffect)(() => {
7921
+ (0, import_react57.useEffect)(() => {
7221
7922
  if (!editor) return;
7222
7923
  const handleUpdate = () => {
7223
- setIsVisible(shouldShowButton6({ editor, hideWhenUnavailable, action }));
7924
+ setIsVisible(shouldShowButton7({ editor, hideWhenUnavailable, action }));
7224
7925
  };
7225
7926
  handleUpdate();
7226
7927
  editor.on("transaction", handleUpdate);
@@ -7228,7 +7929,7 @@ function useUndoRedo(config) {
7228
7929
  editor.off("transaction", handleUpdate);
7229
7930
  };
7230
7931
  }, [editor, hideWhenUnavailable, action]);
7231
- const handleAction = (0, import_react56.useCallback)(() => {
7932
+ const handleAction = (0, import_react57.useCallback)(() => {
7232
7933
  if (!editor) return false;
7233
7934
  const success = executeUndoRedoAction(editor, action);
7234
7935
  if (success) {
@@ -7247,7 +7948,7 @@ function useUndoRedo(config) {
7247
7948
  }
7248
7949
 
7249
7950
  // src/ui/undo-redo-button/undo-redo-button.tsx
7250
- var import_jsx_runtime31 = require("react/jsx-runtime");
7951
+ var import_jsx_runtime32 = require("react/jsx-runtime");
7251
7952
  var UndoRedoButton = ({
7252
7953
  editor: providedEditor,
7253
7954
  action,
@@ -7259,14 +7960,14 @@ var UndoRedoButton = ({
7259
7960
  children,
7260
7961
  ...buttonProps
7261
7962
  }) => {
7262
- const { editor } = useTiptapEditor(providedEditor);
7963
+ const { editor } = (0, import_editor_utils30.useTiptapEditor)(providedEditor);
7263
7964
  const { isVisible, handleAction, label, canExecute, Icon, shortcutKeys } = useUndoRedo({
7264
7965
  editor,
7265
7966
  action,
7266
7967
  hideWhenUnavailable,
7267
7968
  onExecuted
7268
7969
  });
7269
- const handleClick = (0, import_react57.useCallback)(
7970
+ const handleClick = (0, import_react58.useCallback)(
7270
7971
  (event) => {
7271
7972
  onClick == null ? void 0 : onClick(event);
7272
7973
  if (event.defaultPrevented) return;
@@ -7277,7 +7978,7 @@ var UndoRedoButton = ({
7277
7978
  if (!isVisible) {
7278
7979
  return null;
7279
7980
  }
7280
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7981
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7281
7982
  import_toolbar9.ToolbarButton,
7282
7983
  {
7283
7984
  type: "button",
@@ -7292,23 +7993,23 @@ var UndoRedoButton = ({
7292
7993
  onClick: handleClick,
7293
7994
  isIconOnly: true,
7294
7995
  ...buttonProps,
7295
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Icon, {})
7996
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, {})
7296
7997
  }
7297
7998
  );
7298
7999
  };
7299
8000
 
7300
8001
  // src/presets/basic/editor-header.tsx
7301
- var import_jsx_runtime32 = require("react/jsx-runtime");
8002
+ var import_jsx_runtime33 = require("react/jsx-runtime");
7302
8003
  var EditorHeader = ({
7303
8004
  editor: providedEditor,
7304
8005
  variant
7305
8006
  }) => {
7306
8007
  var _a, _b;
7307
- const { editor } = useTiptapEditor(providedEditor);
7308
- const isMobile = (0, import_use_is_mobile2.useIsMobile)();
8008
+ const { editor } = (0, import_editor_utils31.useTiptapEditor)(providedEditor);
8009
+ const isMobile = (0, import_use_is_mobile3.useIsMobile)();
7309
8010
  const windowSize = useWindowSize();
7310
8011
  const { styles } = useEditorUIContext();
7311
- const toolbarRef = (0, import_react58.useRef)(null);
8012
+ const toolbarRef = (0, import_react59.useRef)(null);
7312
8013
  const bodyRect = useCursorVisibility({
7313
8014
  editor,
7314
8015
  overlayHeight: (_b = (_a = toolbarRef.current) == null ? void 0 : _a.getBoundingClientRect().height) != null ? _b : 0
@@ -7317,7 +8018,7 @@ var EditorHeader = ({
7317
8018
  return null;
7318
8019
  }
7319
8020
  const ToolbarContent = variant === "comment" ? CommentToolbarContent : variant === "field" ? FieldToolbarContent : MainToolbarContent;
7320
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: styles.toolbarContainer(), "data-slot": "editor-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
8021
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: styles.toolbarContainer(), "data-slot": "editor-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7321
8022
  import_toolbar10.Toolbar,
7322
8023
  {
7323
8024
  sticky: true,
@@ -7327,63 +8028,58 @@ var EditorHeader = ({
7327
8028
  bottom: `calc(100% - ${windowSize.height - bodyRect.y}px)`
7328
8029
  } : {},
7329
8030
  className: styles.toolbar(),
7330
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ToolbarContent, {})
8031
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ToolbarContent, {})
7331
8032
  }
7332
8033
  ) });
7333
8034
  };
7334
- var MainToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
7335
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7336
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(UndoRedoButton, { action: "undo" }),
7337
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(UndoRedoButton, { action: "redo" })
7338
- ] }),
7339
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7340
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7341
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(HeadingDropdownMenu, { levels: [1, 2, 3, 4] }),
7342
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ListDropdownMenu, { types: ["bulletList", "orderedList", "taskList"] }),
7343
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(BlockquoteButton, {}),
7344
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CodeBlockButton, {})
8035
+ var MainToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
8036
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8037
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(UndoRedoButton, { action: "undo" }),
8038
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(UndoRedoButton, { action: "redo" })
7345
8039
  ] }),
7346
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7347
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7348
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "bold" }),
7349
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "italic" }),
7350
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "strike" }),
7351
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "code" }),
7352
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "underline" }),
7353
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ColorHighlightPopover, {}),
7354
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LinkPopover, {})
8040
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8041
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TurnIntoDropdown, {}) }),
8042
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8043
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8044
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "bold" }),
8045
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "italic" }),
8046
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "strike" }),
8047
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "code" }),
8048
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "underline" }),
8049
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ColorHighlightPopover, {}),
8050
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LinkPopover, {})
7355
8051
  ] }),
7356
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7357
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TableButton, {}) }),
7358
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MoreOptions, { hideWhenUnavailable: true })
8052
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8053
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TableButton, {}) }),
8054
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MoreOptions, { hideWhenUnavailable: true })
7359
8055
  ] });
7360
- var CommentToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
7361
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7362
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "bold" }),
7363
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "italic" }),
7364
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "strike" }),
7365
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "code" })
8056
+ var CommentToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
8057
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8058
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "bold" }),
8059
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "italic" }),
8060
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "strike" }),
8061
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "code" })
7366
8062
  ] }),
7367
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7368
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7369
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LinkPopover, {}),
7370
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ListDropdownMenu, { types: ["bulletList", "orderedList"] })
8063
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8064
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8065
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LinkPopover, {}),
8066
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ListDropdownMenu, { types: ["bulletList", "orderedList"] })
7371
8067
  ] })
7372
8068
  ] });
7373
- var FieldToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7374
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "bold" }),
7375
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "italic" }),
7376
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "strike" }),
7377
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LinkPopover, {})
8069
+ var FieldToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8070
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "bold" }),
8071
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "italic" }),
8072
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "strike" }),
8073
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LinkPopover, {})
7378
8074
  ] });
7379
8075
  function MoreOptions({
7380
8076
  editor: providedEditor,
7381
8077
  hideWhenUnavailable = false,
7382
8078
  ...props
7383
8079
  }) {
7384
- const { editor } = useTiptapEditor(providedEditor);
7385
- const [show, setShow] = (0, import_react58.useState)(false);
7386
- (0, import_react58.useEffect)(() => {
8080
+ const { editor } = (0, import_editor_utils31.useTiptapEditor)(providedEditor);
8081
+ const [show, setShow] = (0, import_react59.useState)(false);
8082
+ (0, import_react59.useEffect)(() => {
7387
8083
  if (!editor) return;
7388
8084
  const handleSelectionUpdate = () => {
7389
8085
  setShow(
@@ -7402,13 +8098,13 @@ function MoreOptions({
7402
8098
  if (!show || !editor || !editor.isEditable) {
7403
8099
  return null;
7404
8100
  }
7405
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
7406
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7407
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_popover3.Popover.Root, { spacing: "dense", width: "auto", children: [
7408
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
8101
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
8102
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8103
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_popover3.Popover.Root, { spacing: "dense", width: "auto", children: [
8104
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7409
8105
  import_popover3.Popover.Trigger,
7410
8106
  {
7411
- render: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
8107
+ render: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7412
8108
  import_toolbar10.ToolbarButton,
7413
8109
  {
7414
8110
  type: "button",
@@ -7420,29 +8116,29 @@ function MoreOptions({
7420
8116
  title: "More options",
7421
8117
  isIconOnly: true,
7422
8118
  ...props,
7423
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_icons25.MoreVerticalIcon, {})
8119
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_icons26.MoreVerticalIcon, {})
7424
8120
  }
7425
8121
  )
7426
8122
  }
7427
8123
  ),
7428
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
8124
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7429
8125
  import_popover3.Popover.Content,
7430
8126
  {
7431
8127
  side: "top",
7432
8128
  align: "end",
7433
8129
  alignOffset: 4,
7434
8130
  sideOffset: 4,
7435
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.Toolbar, { children: [
7436
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7437
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "superscript" }),
7438
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "subscript" })
8131
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.Toolbar, { children: [
8132
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8133
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "superscript" }),
8134
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "subscript" })
7439
8135
  ] }),
7440
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7441
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7442
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextAlignButton, { align: "left" }),
7443
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextAlignButton, { align: "center" }),
7444
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextAlignButton, { align: "right" }),
7445
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextAlignButton, { align: "justify" })
8136
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8137
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8138
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TextAlignButton, { align: "left" }),
8139
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TextAlignButton, { align: "center" }),
8140
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TextAlignButton, { align: "right" }),
8141
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TextAlignButton, { align: "justify" })
7446
8142
  ] })
7447
8143
  ] })
7448
8144
  }
@@ -7474,7 +8170,7 @@ function shouldShowMoreOptions(params) {
7474
8170
  }
7475
8171
 
7476
8172
  // src/presets/basic/index.tsx
7477
- var import_jsx_runtime33 = require("react/jsx-runtime");
8173
+ var import_jsx_runtime34 = require("react/jsx-runtime");
7478
8174
  var BasicEditor = ({
7479
8175
  variant,
7480
8176
  bordered,
@@ -7492,19 +8188,19 @@ var BasicEditor = ({
7492
8188
  ...options
7493
8189
  });
7494
8190
  const styles = (0, import_theme9.editorBasic)({ variant, bordered });
7495
- const resolveVariable = (0, import_react60.useCallback)(
8191
+ const resolveVariable = (0, import_react61.useCallback)(
7496
8192
  (name) => variableValues == null ? void 0 : variableValues[name],
7497
8193
  [variableValues]
7498
8194
  );
7499
8195
  if (!editor) {
7500
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LoadingSpinner, {});
8196
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(LoadingSpinner, {});
7501
8197
  }
7502
8198
  const isBottomToolbar = variant === "field";
7503
8199
  const hasVariables = variables && variables.length > 0;
7504
8200
  const hasPagination = !!pagesOptions;
7505
- const editorContent = /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(EditorUIProvider, { value: { styles }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: styles.root(), "data-slot": "editor", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react59.EditorContext.Provider, { value: { editor }, children: [
7506
- showToolbar && !isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(EditorHeader, { editor, variant }),
7507
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
8201
+ const editorContent = /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(EditorUIProvider, { value: { styles }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: styles.root(), "data-slot": "editor", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react60.EditorContext.Provider, { value: { editor }, children: [
8202
+ showToolbar && !isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(EditorHeader, { editor, variant }),
8203
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7508
8204
  EditorContentArea,
7509
8205
  {
7510
8206
  variant,
@@ -7512,10 +8208,10 @@ var BasicEditor = ({
7512
8208
  hasPagination
7513
8209
  }
7514
8210
  ),
7515
- showToolbar && isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(EditorHeader, { editor, variant })
8211
+ showToolbar && isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(EditorHeader, { editor, variant })
7516
8212
  ] }) }) });
7517
8213
  if (hasVariables) {
7518
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VariableProvider, { variables, resolveVariable, children: editorContent });
8214
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(VariableProvider, { variables, resolveVariable, children: editorContent });
7519
8215
  }
7520
8216
  return editorContent;
7521
8217
  };
@@ -7525,10 +8221,10 @@ var EditorContentArea = ({
7525
8221
  hasPagination
7526
8222
  }) => {
7527
8223
  const styles = (0, import_theme9.editorBasic)({ variant });
7528
- const { editor } = (0, import_react60.useContext)(import_react59.EditorContext);
8224
+ const { editor } = (0, import_react61.useContext)(import_react60.EditorContext);
7529
8225
  const { isDragging } = useUiEditorState(editor);
7530
8226
  useScrollToHash();
7531
- const handleKeyDown = (0, import_react60.useCallback)(
8227
+ const handleKeyDown = (0, import_react61.useCallback)(
7532
8228
  (e) => {
7533
8229
  if (!(editor == null ? void 0 : editor.isFocused)) return;
7534
8230
  const isMod = e.metaKey || e.ctrlKey;
@@ -7570,9 +8266,9 @@ var EditorContentArea = ({
7570
8266
  const contentClassName = hasPagination ? "w-full min-w-0 h-auto min-h-0" : styles.content();
7571
8267
  return (
7572
8268
  // biome-ignore lint/a11y/noStaticElementInteractions: Wrapper intercepts keyboard shortcuts to prevent propagation
7573
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: styles.wrapper(), onKeyDown: handleKeyDown, children: [
7574
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7575
- import_react59.EditorContent,
8269
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: styles.wrapper(), onKeyDown: handleKeyDown, children: [
8270
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
8271
+ import_react60.EditorContent,
7576
8272
  {
7577
8273
  editor,
7578
8274
  role: "presentation",
@@ -7581,20 +8277,36 @@ var EditorContentArea = ({
7581
8277
  cursor: isDragging ? "grabbing" : "auto"
7582
8278
  },
7583
8279
  children: [
7584
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SlashDropdownMenu, {}),
7585
- isEditable && variables && variables.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VariableSuggestion, { editor, variables })
8280
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SlashDropdownMenu, {}),
8281
+ isEditable && variables && variables.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(VariableSuggestion, { editor, variables })
7586
8282
  ]
7587
8283
  }
7588
8284
  ),
7589
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(BubbleMenu, { editor }),
7590
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LinkBubble, { editor })
8285
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(BubbleMenu, { editor }),
8286
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(LinkBubble, { editor }),
8287
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
8288
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_extension_table2.TableHandle, { editor }),
8289
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
8290
+ import_extension_table2.TableSelectionOverlay,
8291
+ {
8292
+ showResizeHandles: true,
8293
+ cellMenu: (props) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
8294
+ import_extension_table2.TableCellHandleMenu,
8295
+ {
8296
+ editor: props.editor,
8297
+ onOpenChange: props.onOpenChange
8298
+ }
8299
+ )
8300
+ }
8301
+ )
8302
+ ] })
7591
8303
  ] })
7592
8304
  );
7593
8305
  };
7594
8306
  function LoadingSpinner({ text = "Connecting..." }) {
7595
8307
  const styles = (0, import_theme9.editorSpinner)();
7596
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: styles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: styles.content(), children: [
7597
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
8308
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: styles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: styles.content(), children: [
8309
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
7598
8310
  "svg",
7599
8311
  {
7600
8312
  className: styles.svg(),
@@ -7602,9 +8314,9 @@ function LoadingSpinner({ text = "Connecting..." }) {
7602
8314
  fill: "none",
7603
8315
  viewBox: "0 0 24 24",
7604
8316
  children: [
7605
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("title", { children: "Loading Spinner" }),
7606
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("circle", { className: styles.circle(), cx: "12", cy: "12", r: "10" }),
7607
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
8317
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("title", { children: "Loading Spinner" }),
8318
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { className: styles.circle(), cx: "12", cy: "12", r: "10" }),
8319
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7608
8320
  "path",
7609
8321
  {
7610
8322
  className: styles.path(),
@@ -7614,7 +8326,7 @@ function LoadingSpinner({ text = "Connecting..." }) {
7614
8326
  ]
7615
8327
  }
7616
8328
  ),
7617
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: styles.text(), children: text })
8329
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: styles.text(), children: text })
7618
8330
  ] }) });
7619
8331
  }
7620
8332
  // Annotate the CommonJS export names for ESM import in node: