@kopexa/tiptap 17.7.2 → 17.8.1

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 +1661 -1221
  2. package/dist/index.mjs +1662 -1215
  3. package/package.json +24 -24
package/dist/index.js CHANGED
@@ -208,7 +208,7 @@ function CollaborationProvider({
208
208
  (0, import_react3.useEffect)(() => {
209
209
  const remote = remoteRef.current;
210
210
  if (!remote) return;
211
- if (enableLocalPersistence) {
211
+ if (enableLocalPersistence && !localRef.current) {
212
212
  const local = new import_y_indexeddb.IndexeddbPersistence(documentId, ydoc);
213
213
  local.on("synced", () => setLocalSynced(true));
214
214
  localRef.current = local;
@@ -262,12 +262,19 @@ function CollaborationProvider({
262
262
  remote.off("authenticationFailed", onAuthFailed);
263
263
  remote.off("synced", onSynced);
264
264
  remote.off("status", onStatus);
265
- remote.destroy();
265
+ remote.disconnect();
266
266
  (_a = localRef.current) == null ? void 0 : _a.destroy();
267
267
  localRef.current = null;
268
- remoteRef.current = null;
268
+ setReady(false);
269
269
  };
270
270
  }, [documentId, ydoc, enableLocalPersistence]);
271
+ (0, import_react3.useEffect)(() => {
272
+ return () => {
273
+ var _a;
274
+ (_a = remoteRef.current) == null ? void 0 : _a.destroy();
275
+ remoteRef.current = null;
276
+ };
277
+ }, []);
271
278
  (0, import_react3.useEffect)(() => {
272
279
  var _a;
273
280
  const awareness = (_a = remoteRef.current) == null ? void 0 : _a.awareness;
@@ -1023,7 +1030,7 @@ var ImageNode = import_extension_image.Image.extend({
1023
1030
  return (0, import_react11.ReactNodeViewRenderer)(ImageNodeView, {
1024
1031
  stopEvent: ({ event }) => {
1025
1032
  const target = event.target;
1026
- if (target.closest("button, [role='button'], input, a")) {
1033
+ if (target instanceof HTMLElement && target.closest("button, [role='button'], input, a")) {
1027
1034
  return true;
1028
1035
  }
1029
1036
  return false;
@@ -1374,7 +1381,7 @@ var ImageUploadNode = import_core2.Node.create({
1374
1381
  return (0, import_react14.ReactNodeViewRenderer)(ImageUploadNodeView, {
1375
1382
  stopEvent: ({ event }) => {
1376
1383
  const target = event.target;
1377
- if (target.closest("button, [role='button'], input, a")) {
1384
+ if (target instanceof HTMLElement && target.closest("button, [role='button'], input, a")) {
1378
1385
  return true;
1379
1386
  }
1380
1387
  return false;
@@ -4267,8 +4274,8 @@ async function handleFileUpload(editor, file, fileHandler, pos) {
4267
4274
  // src/presets/basic/index.tsx
4268
4275
  var import_extension_table2 = require("@kopexa/extension-table");
4269
4276
  var import_theme9 = require("@kopexa/theme");
4270
- var import_react57 = require("@tiptap/react");
4271
- var import_react58 = require("react");
4277
+ var import_react60 = require("@tiptap/react");
4278
+ var import_react61 = require("react");
4272
4279
 
4273
4280
  // src/context/editor-context.ts
4274
4281
  var import_react_utils = require("@kopexa/react-utils");
@@ -5818,12 +5825,12 @@ var List = ({
5818
5825
  };
5819
5826
 
5820
5827
  // src/presets/basic/editor-header.tsx
5821
- var import_editor_utils28 = require("@kopexa/editor-utils");
5822
- var import_icons25 = require("@kopexa/icons");
5828
+ var import_editor_utils31 = require("@kopexa/editor-utils");
5829
+ var import_icons26 = require("@kopexa/icons");
5823
5830
  var import_popover3 = require("@kopexa/popover");
5824
5831
  var import_toolbar10 = require("@kopexa/toolbar");
5825
- var import_use_is_mobile2 = require("@kopexa/use-is-mobile");
5826
- var import_react56 = require("react");
5832
+ var import_use_is_mobile3 = require("@kopexa/use-is-mobile");
5833
+ var import_react59 = require("react");
5827
5834
 
5828
5835
  // src/hooks/use-cursor-visibility.ts
5829
5836
  var React13 = __toESM(require("react"));
@@ -5927,95 +5934,122 @@ function useCursorVisibility({
5927
5934
  return rect;
5928
5935
  }
5929
5936
 
5930
- // src/ui/blockquote-button/blockquote-button.tsx
5937
+ // src/ui/color-highlight-popover/color-highlight-popover.tsx
5938
+ var import_button11 = require("@kopexa/button");
5939
+ var import_editor_utils14 = require("@kopexa/editor-utils");
5940
+ var import_icons15 = require("@kopexa/icons");
5941
+ var import_popover2 = require("@kopexa/popover");
5942
+ var import_toolbar5 = require("@kopexa/toolbar");
5943
+ var import_react43 = require("react");
5944
+
5945
+ // src/ui/color-highlight-button/color-highlight-button.tsx
5931
5946
  var import_editor_utils13 = require("@kopexa/editor-utils");
5947
+ var import_theme8 = require("@kopexa/theme");
5932
5948
  var import_toolbar4 = require("@kopexa/toolbar");
5933
- var React15 = __toESM(require("react"));
5949
+ var import_react42 = require("react");
5934
5950
 
5935
- // src/ui/blockquote-button/use-blockquote.ts
5951
+ // src/ui/color-highlight-button/use-color-highlight.ts
5936
5952
  var import_editor_utils12 = require("@kopexa/editor-utils");
5937
5953
  var import_icons14 = require("@kopexa/icons");
5938
- var import_state7 = require("@tiptap/pm/state");
5954
+ var import_use_is_mobile = require("@kopexa/use-is-mobile");
5939
5955
  var React14 = __toESM(require("react"));
5940
- var BLOCKQUOTE_SHORTCUT_KEY = "mod+shift+b";
5941
- function canToggleBlockquote(editor, turnInto = true) {
5942
- var _a;
5943
- if (!editor || !editor.isEditable) return false;
5944
- if (!(0, import_editor_utils12.isNodeInSchema)("blockquote", editor) || (0, import_editor_utils12.isNodeTypeSelected)(editor, ["image"]))
5945
- return false;
5946
- if (!turnInto) {
5947
- return editor.can().toggleWrap("blockquote");
5948
- }
5949
- try {
5950
- const view = editor.view;
5951
- const state = view.state;
5952
- const selection = state.selection;
5953
- if (selection.empty || selection instanceof import_state7.TextSelection) {
5954
- const pos = (_a = (0, import_editor_utils12.findNodePosition)({
5955
- editor,
5956
- node: state.selection.$anchor.node(1)
5957
- })) == null ? void 0 : _a.pos;
5958
- if (!(0, import_editor_utils12.isValidPosition)(pos)) return false;
5959
- }
5960
- return true;
5961
- } catch {
5962
- return false;
5956
+ var import_react_hotkeys_hook = require("react-hotkeys-hook");
5957
+ var COLOR_HIGHLIGHT_SHORTCUT_KEY = "mod+shift+h";
5958
+ var HIGHLIGHT_COLORS = [
5959
+ {
5960
+ label: "Default background",
5961
+ value: "var(--tt-bg-color)",
5962
+ border: "var(--tt-bg-color-contrast)"
5963
+ },
5964
+ {
5965
+ label: "Gray background",
5966
+ value: "var(--tt-color-highlight-gray)",
5967
+ border: "var(--tt-color-highlight-gray-contrast)"
5968
+ },
5969
+ {
5970
+ label: "Brown background",
5971
+ value: "var(--tt-color-highlight-brown)",
5972
+ border: "var(--tt-color-highlight-brown-contrast)"
5973
+ },
5974
+ {
5975
+ label: "Orange background",
5976
+ value: "var(--tt-color-highlight-orange)",
5977
+ border: "var(--tt-color-highlight-orange-contrast)"
5978
+ },
5979
+ {
5980
+ label: "Yellow background",
5981
+ value: "var(--tt-color-highlight-yellow)",
5982
+ border: "var(--tt-color-highlight-yellow-contrast)"
5983
+ },
5984
+ {
5985
+ label: "Green background",
5986
+ value: "var(--tt-color-highlight-green)",
5987
+ border: "var(--tt-color-highlight-green-contrast)"
5988
+ },
5989
+ {
5990
+ label: "Blue background",
5991
+ value: "var(--tt-color-highlight-blue)",
5992
+ border: "var(--tt-color-highlight-blue-contrast)"
5993
+ },
5994
+ {
5995
+ label: "Purple background",
5996
+ value: "var(--tt-color-highlight-purple)",
5997
+ border: "var(--tt-color-highlight-purple-contrast)"
5998
+ },
5999
+ {
6000
+ label: "Pink background",
6001
+ value: "var(--tt-color-highlight-pink)",
6002
+ border: "var(--tt-color-highlight-pink-contrast)"
6003
+ },
6004
+ {
6005
+ label: "Red background",
6006
+ value: "var(--tt-color-highlight-red)",
6007
+ border: "var(--tt-color-highlight-red-contrast)"
5963
6008
  }
6009
+ ];
6010
+ function pickHighlightColorsByValue(values) {
6011
+ const colorMap = new Map(
6012
+ HIGHLIGHT_COLORS.map((color) => [color.value, color])
6013
+ );
6014
+ return values.map((value) => colorMap.get(value)).filter((color) => !!color);
5964
6015
  }
5965
- function toggleBlockquote(editor) {
5966
- var _a, _b, _c;
6016
+ function canColorHighlight(editor) {
5967
6017
  if (!editor || !editor.isEditable) return false;
5968
- if (!canToggleBlockquote(editor)) return false;
5969
- try {
5970
- const view = editor.view;
5971
- let state = view.state;
5972
- let tr = state.tr;
5973
- if (state.selection.empty || state.selection instanceof import_state7.TextSelection) {
5974
- const pos = (_a = (0, import_editor_utils12.findNodePosition)({
5975
- editor,
5976
- node: state.selection.$anchor.node(1)
5977
- })) == null ? void 0 : _a.pos;
5978
- if (!(0, import_editor_utils12.isValidPosition)(pos)) return false;
5979
- tr = tr.setSelection(import_state7.NodeSelection.create(state.doc, pos));
5980
- view.dispatch(tr);
5981
- state = view.state;
5982
- }
5983
- const selection = state.selection;
5984
- let chain = editor.chain().focus();
5985
- if (selection instanceof import_state7.NodeSelection) {
5986
- const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
5987
- const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
5988
- const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
5989
- const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
5990
- chain = chain.setTextSelection({ from, to }).clearNodes();
5991
- }
5992
- const toggle = editor.isActive("blockquote") ? chain.lift("blockquote") : chain.wrapIn("blockquote");
5993
- toggle.run();
5994
- editor.chain().focus().selectTextblockEnd().run();
5995
- return true;
5996
- } catch {
6018
+ if (!(0, import_editor_utils12.isMarkInSchema)("highlight", editor) || (0, import_editor_utils12.isNodeTypeSelected)(editor, ["image"]))
5997
6019
  return false;
5998
- }
6020
+ return editor.can().setMark("highlight");
6021
+ }
6022
+ function isColorHighlightActive(editor, highlightColor) {
6023
+ if (!editor || !editor.isEditable) return false;
6024
+ return highlightColor ? editor.isActive("highlight", { color: highlightColor }) : editor.isActive("highlight");
6025
+ }
6026
+ function removeHighlight(editor) {
6027
+ if (!editor || !editor.isEditable) return false;
6028
+ if (!canColorHighlight(editor)) return false;
6029
+ return editor.chain().focus().unsetMark("highlight").run();
5999
6030
  }
6000
6031
  function shouldShowButton2(props) {
6001
6032
  const { editor, hideWhenUnavailable } = props;
6002
6033
  if (!editor || !editor.isEditable) return false;
6003
- if (!(0, import_editor_utils12.isNodeInSchema)("blockquote", editor)) return false;
6034
+ if (!(0, import_editor_utils12.isMarkInSchema)("highlight", editor)) return false;
6004
6035
  if (hideWhenUnavailable && !editor.isActive("code")) {
6005
- return canToggleBlockquote(editor);
6036
+ return canColorHighlight(editor);
6006
6037
  }
6007
6038
  return true;
6008
6039
  }
6009
- function useBlockquote(config) {
6040
+ function useColorHighlight(config) {
6010
6041
  const {
6011
6042
  editor: providedEditor,
6043
+ label,
6044
+ highlightColor,
6012
6045
  hideWhenUnavailable = false,
6013
- onToggled
6014
- } = config || {};
6046
+ onApplied
6047
+ } = config;
6015
6048
  const { editor } = (0, import_editor_utils12.useTiptapEditor)(providedEditor);
6049
+ const isMobile = (0, import_use_is_mobile.useIsMobile)();
6016
6050
  const [isVisible, setIsVisible] = React14.useState(true);
6017
- const canToggle3 = canToggleBlockquote(editor);
6018
- const isActive = (editor == null ? void 0 : editor.isActive("blockquote")) || false;
6051
+ const canColorHighlightState = canColorHighlight(editor);
6052
+ const isActive = isColorHighlightActive(editor, highlightColor);
6019
6053
  React14.useEffect(() => {
6020
6054
  if (!editor) return;
6021
6055
  const handleSelectionUpdate = () => {
@@ -6027,375 +6061,885 @@ function useBlockquote(config) {
6027
6061
  editor.off("selectionUpdate", handleSelectionUpdate);
6028
6062
  };
6029
6063
  }, [editor, hideWhenUnavailable]);
6030
- const handleToggle = React14.useCallback(() => {
6031
- if (!editor) return false;
6032
- const success = toggleBlockquote(editor);
6064
+ const handleColorHighlight = React14.useCallback(() => {
6065
+ if (!editor || !canColorHighlightState || !highlightColor || !label)
6066
+ return false;
6067
+ if (editor.state.storedMarks) {
6068
+ const highlightMarkType = editor.schema.marks.highlight;
6069
+ if (highlightMarkType) {
6070
+ editor.view.dispatch(
6071
+ editor.state.tr.removeStoredMark(highlightMarkType)
6072
+ );
6073
+ }
6074
+ }
6075
+ setTimeout(() => {
6076
+ const success = editor.chain().focus().toggleMark("highlight", { color: highlightColor }).run();
6077
+ if (success) {
6078
+ onApplied == null ? void 0 : onApplied({ color: highlightColor, label });
6079
+ }
6080
+ return success;
6081
+ }, 0);
6082
+ }, [canColorHighlightState, highlightColor, editor, label, onApplied]);
6083
+ const handleRemoveHighlight = React14.useCallback(() => {
6084
+ const success = removeHighlight(editor);
6033
6085
  if (success) {
6034
- onToggled == null ? void 0 : onToggled();
6086
+ onApplied == null ? void 0 : onApplied({ color: "", label: "Remove highlight" });
6035
6087
  }
6036
6088
  return success;
6037
- }, [editor, onToggled]);
6089
+ }, [editor, onApplied]);
6090
+ (0, import_react_hotkeys_hook.useHotkeys)(
6091
+ COLOR_HIGHLIGHT_SHORTCUT_KEY,
6092
+ (event) => {
6093
+ event.preventDefault();
6094
+ handleColorHighlight();
6095
+ },
6096
+ {
6097
+ enabled: isVisible && canColorHighlightState,
6098
+ enableOnContentEditable: !isMobile,
6099
+ enableOnFormTags: true
6100
+ }
6101
+ );
6038
6102
  return {
6039
6103
  isVisible,
6040
6104
  isActive,
6041
- handleToggle,
6042
- canToggle: canToggle3,
6043
- label: "Blockquote",
6044
- shortcutKeys: BLOCKQUOTE_SHORTCUT_KEY,
6045
- Icon: import_icons14.BlockquoteIcon
6105
+ handleColorHighlight,
6106
+ handleRemoveHighlight,
6107
+ canColorHighlight: canColorHighlightState,
6108
+ label: label || `Highlight`,
6109
+ shortcutKeys: COLOR_HIGHLIGHT_SHORTCUT_KEY,
6110
+ Icon: import_icons14.HighlighterIcon
6046
6111
  };
6047
6112
  }
6048
6113
 
6049
- // src/ui/blockquote-button/blockquote-button.tsx
6114
+ // src/ui/color-highlight-button/color-highlight-button.tsx
6050
6115
  var import_jsx_runtime21 = require("react/jsx-runtime");
6051
- var BlockquoteButton = ({
6116
+ var ColorHighlightButton = ({
6052
6117
  editor: providedEditor,
6118
+ highlightColor,
6053
6119
  text,
6054
6120
  hideWhenUnavailable = false,
6055
- onToggled,
6121
+ onApplied,
6056
6122
  showShortcut = false,
6057
6123
  onClick,
6058
6124
  children,
6125
+ style,
6126
+ className,
6059
6127
  ...buttonProps
6060
6128
  }) => {
6061
6129
  const { editor } = (0, import_editor_utils13.useTiptapEditor)(providedEditor);
6062
6130
  const {
6063
6131
  isVisible,
6064
- canToggle: canToggle3,
6132
+ canColorHighlight: canColorHighlight2,
6065
6133
  isActive,
6066
- handleToggle,
6134
+ handleColorHighlight,
6067
6135
  label,
6068
- shortcutKeys,
6069
- Icon
6070
- } = useBlockquote({
6136
+ shortcutKeys
6137
+ } = useColorHighlight({
6071
6138
  editor,
6139
+ highlightColor,
6140
+ label: text || `Toggle highlight (${highlightColor})`,
6072
6141
  hideWhenUnavailable,
6073
- onToggled
6142
+ onApplied
6074
6143
  });
6075
- const handleClick = React15.useCallback(
6144
+ const handleClick = (0, import_react42.useCallback)(
6076
6145
  (event) => {
6077
6146
  onClick == null ? void 0 : onClick(event);
6078
6147
  if (event.defaultPrevented) return;
6079
- handleToggle();
6148
+ handleColorHighlight();
6080
6149
  },
6081
- [handleToggle, onClick]
6150
+ [handleColorHighlight, onClick]
6151
+ );
6152
+ const buttonStyle = (0, import_react42.useMemo)(
6153
+ () => ({
6154
+ ...style,
6155
+ "--highlight-color": highlightColor
6156
+ }),
6157
+ [highlightColor, style]
6082
6158
  );
6083
6159
  if (!isVisible) {
6084
6160
  return null;
6085
6161
  }
6086
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6162
+ const styles = (0, import_theme8.colorHighlightButton)();
6163
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
6087
6164
  import_toolbar4.ToolbarButton,
6088
6165
  {
6089
6166
  type: "button",
6167
+ disabled: !canColorHighlight2,
6168
+ "data-disabled": !canColorHighlight2,
6090
6169
  variant: "ghost",
6091
6170
  color: "default",
6092
- disabled: !canToggle3,
6093
- "data-disabled": !canToggle3,
6094
6171
  "data-active-state": isActive ? "on" : "off",
6095
6172
  tabIndex: -1,
6096
- "aria-label": "blockquote",
6097
- "aria-pressed": isActive,
6098
- title: label,
6173
+ "aria-label": label,
6099
6174
  shortcutKeys,
6175
+ "aria-pressed": isActive,
6100
6176
  onClick: handleClick,
6101
- isIconOnly: !text && !children,
6102
- ...buttonProps,
6103
- children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
6104
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, {}),
6105
- text && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: text })
6106
- ] })
6177
+ style: buttonStyle,
6178
+ className: styles.button({ className }),
6179
+ isIconOnly: true,
6180
+ ...buttonProps,
6181
+ children: [
6182
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6183
+ "span",
6184
+ {
6185
+ "data-active-state": isActive ? "on" : "off",
6186
+ className: styles.mark()
6187
+ }
6188
+ ),
6189
+ children || /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
6190
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6191
+ "span",
6192
+ {
6193
+ style: { "--highlight-color": highlightColor }
6194
+ }
6195
+ ),
6196
+ text
6197
+ ] })
6198
+ ]
6199
+ }
6200
+ );
6201
+ };
6202
+
6203
+ // src/ui/color-highlight-popover/color-highlight-popover.tsx
6204
+ var import_jsx_runtime22 = require("react/jsx-runtime");
6205
+ var ColorHighlightPopoverButton = ({
6206
+ className,
6207
+ children,
6208
+ ...props
6209
+ }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6210
+ import_button11.IconButton,
6211
+ {
6212
+ type: "button",
6213
+ className,
6214
+ variant: "ghost",
6215
+ color: "default",
6216
+ tabIndex: -1,
6217
+ "aria-label": "Highlight text",
6218
+ tooltip: "Highlight",
6219
+ isIconOnly: !children,
6220
+ ...props,
6221
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons15.HighlighterIcon, {})
6222
+ }
6223
+ );
6224
+ function ColorHighlightPopoverContent({
6225
+ editor,
6226
+ colors = pickHighlightColorsByValue([
6227
+ "var(--tt-color-highlight-green)",
6228
+ "var(--tt-color-highlight-blue)",
6229
+ "var(--tt-color-highlight-red)",
6230
+ "var(--tt-color-highlight-purple)",
6231
+ "var(--tt-color-highlight-yellow)"
6232
+ ])
6233
+ }) {
6234
+ const { handleRemoveHighlight } = useColorHighlight({ editor });
6235
+ const containerRef = (0, import_react43.useRef)(null);
6236
+ const menuItems = (0, import_react43.useMemo)(
6237
+ () => [...colors, { label: "Remove highlight", value: "none" }],
6238
+ [colors]
6239
+ );
6240
+ const { selectedIndex } = useMenuNavigation({
6241
+ containerRef,
6242
+ items: menuItems,
6243
+ orientation: "both",
6244
+ onSelect: (item) => {
6245
+ if (!containerRef.current) return false;
6246
+ const highlightedElement = containerRef.current.querySelector(
6247
+ '[data-highlighted="true"]'
6248
+ );
6249
+ if (highlightedElement) highlightedElement.click();
6250
+ if (item.value === "none") handleRemoveHighlight();
6251
+ },
6252
+ autoSelectFirstItem: false
6253
+ });
6254
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { ref: containerRef, className: "flex gap-1 items-center", children: [
6255
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6256
+ "div",
6257
+ {
6258
+ className: "flex items-center gap-1 outline-none",
6259
+ "data-orientation": "horizontal",
6260
+ children: colors.map((color, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6261
+ ColorHighlightButton,
6262
+ {
6263
+ editor,
6264
+ highlightColor: color.value,
6265
+ "aria-label": `${color.label} highlight color`,
6266
+ tabIndex: index === selectedIndex ? 0 : -1,
6267
+ "data-highlighted": selectedIndex === index
6268
+ },
6269
+ color.value
6270
+ ))
6271
+ }
6272
+ ),
6273
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_toolbar5.ToolbarSeparator, { orientation: "vertical" }),
6274
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "tiptap-button-group", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6275
+ import_button11.IconButton,
6276
+ {
6277
+ onClick: handleRemoveHighlight,
6278
+ "aria-label": "Remove highlight",
6279
+ tabIndex: selectedIndex === colors.length ? 0 : -1,
6280
+ type: "button",
6281
+ role: "menuitem",
6282
+ variant: "ghost",
6283
+ color: "default",
6284
+ "data-highlighted": selectedIndex === colors.length,
6285
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons15.BanIcon, {})
6286
+ }
6287
+ ) })
6288
+ ] });
6289
+ }
6290
+ function ColorHighlightPopover({
6291
+ editor: providedEditor,
6292
+ colors = pickHighlightColorsByValue([
6293
+ "var(--tt-color-highlight-green)",
6294
+ "var(--tt-color-highlight-blue)",
6295
+ "var(--tt-color-highlight-red)",
6296
+ "var(--tt-color-highlight-purple)",
6297
+ "var(--tt-color-highlight-yellow)"
6298
+ ]),
6299
+ hideWhenUnavailable = false,
6300
+ onApplied,
6301
+ ...props
6302
+ }) {
6303
+ const { editor } = (0, import_editor_utils14.useTiptapEditor)(providedEditor);
6304
+ const [isOpen, setIsOpen] = (0, import_react43.useState)(false);
6305
+ const { isVisible, canColorHighlight: canColorHighlight2, isActive, label } = useColorHighlight({
6306
+ editor,
6307
+ hideWhenUnavailable,
6308
+ onApplied
6309
+ });
6310
+ if (!isVisible) return null;
6311
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_popover2.Popover.Root, { open: isOpen, onOpenChange: setIsOpen, spacing: "dense", children: [
6312
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6313
+ import_popover2.Popover.Trigger,
6314
+ {
6315
+ render: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6316
+ ColorHighlightPopoverButton,
6317
+ {
6318
+ disabled: !canColorHighlight2,
6319
+ "data-disabled": !canColorHighlight2,
6320
+ "data-active-state": isActive ? "on" : "off",
6321
+ "aria-pressed": isActive,
6322
+ "aria-label": label,
6323
+ title: label,
6324
+ ...props
6325
+ }
6326
+ )
6327
+ }
6328
+ ),
6329
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_popover2.Popover.Content, { "aria-label": "Highlight colors", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ColorHighlightPopoverContent, { editor, colors }) })
6330
+ ] });
6331
+ }
6332
+
6333
+ // src/ui/list-dropdown-menu/index.tsx
6334
+ var import_button13 = require("@kopexa/button");
6335
+ var import_dropdown_menu = require("@kopexa/dropdown-menu");
6336
+ var import_editor_utils16 = require("@kopexa/editor-utils");
6337
+ var import_icons17 = require("@kopexa/icons");
6338
+ var import_react46 = require("@tiptap/react");
6339
+ var import_react47 = require("react");
6340
+
6341
+ // src/ui/list-button/index.tsx
6342
+ var import_button12 = require("@kopexa/button");
6343
+ var import_editor_utils15 = require("@kopexa/editor-utils");
6344
+ var import_icons16 = require("@kopexa/icons");
6345
+ var import_react44 = require("@tiptap/react");
6346
+ var import_react45 = require("react");
6347
+ var import_jsx_runtime23 = require("react/jsx-runtime");
6348
+ var listOptions = [
6349
+ {
6350
+ label: "Bullet List",
6351
+ type: "bulletList",
6352
+ icon: import_icons16.ListIcon
6353
+ },
6354
+ {
6355
+ label: "Ordered List",
6356
+ type: "orderedList",
6357
+ icon: import_icons16.ListOrderedIcon
6358
+ },
6359
+ {
6360
+ label: "Task List",
6361
+ type: "taskList",
6362
+ icon: import_icons16.ListTodoIcon
6363
+ }
6364
+ ];
6365
+ var listShortcutKeys = {
6366
+ bulletList: "Ctrl-Shift-8",
6367
+ orderedList: "Ctrl-Shift-7",
6368
+ taskList: "Ctrl-Shift-9"
6369
+ };
6370
+ function canToggleList(editor, type) {
6371
+ if (!editor) {
6372
+ return false;
6373
+ }
6374
+ switch (type) {
6375
+ case "bulletList":
6376
+ return editor.can().toggleBulletList();
6377
+ case "orderedList":
6378
+ return editor.can().toggleOrderedList();
6379
+ case "taskList":
6380
+ return editor.can().toggleList("taskList", "taskItem");
6381
+ default:
6382
+ return false;
6383
+ }
6384
+ }
6385
+ function isListActive(editor, type) {
6386
+ if (!editor) return false;
6387
+ switch (type) {
6388
+ case "bulletList":
6389
+ return editor.isActive("bulletList");
6390
+ case "orderedList":
6391
+ return editor.isActive("orderedList");
6392
+ case "taskList":
6393
+ return editor.isActive("taskList");
6394
+ default:
6395
+ return false;
6396
+ }
6397
+ }
6398
+ function toggleList(editor, type) {
6399
+ if (!editor) return;
6400
+ switch (type) {
6401
+ case "bulletList":
6402
+ editor.chain().focus().toggleBulletList().run();
6403
+ break;
6404
+ case "orderedList":
6405
+ editor.chain().focus().toggleOrderedList().run();
6406
+ break;
6407
+ case "taskList":
6408
+ editor.chain().focus().toggleList("taskList", "taskItem").run();
6409
+ break;
6410
+ }
6411
+ }
6412
+ function getListOption(type) {
6413
+ return listOptions.find((option) => option.type === type);
6414
+ }
6415
+ function shouldShowListButton(params) {
6416
+ const { editor, type, hideWhenUnavailable, listInSchema } = params;
6417
+ if (!listInSchema || !editor) {
6418
+ return false;
6419
+ }
6420
+ if (hideWhenUnavailable) {
6421
+ if ((0, import_react44.isNodeSelection)(editor.state.selection) || !canToggleList(editor, type)) {
6422
+ return false;
6423
+ }
6424
+ }
6425
+ return true;
6426
+ }
6427
+ function useListState(editor, type) {
6428
+ const listInSchema = (0, import_editor_utils15.isNodeInSchema)(type, editor);
6429
+ const listOption = getListOption(type);
6430
+ const isActive = isListActive(editor, type);
6431
+ const shortcutKey = listShortcutKeys[type];
6432
+ return {
6433
+ listInSchema,
6434
+ listOption,
6435
+ isActive,
6436
+ shortcutKey
6437
+ };
6438
+ }
6439
+ var ListButton = ({
6440
+ editor: providedEditor,
6441
+ type,
6442
+ hideWhenUnavailable = false,
6443
+ className = "",
6444
+ onClick,
6445
+ text,
6446
+ children,
6447
+ ref,
6448
+ ...buttonProps
6449
+ }) => {
6450
+ const { editor } = (0, import_editor_utils15.useTiptapEditor)(providedEditor);
6451
+ const { listInSchema, listOption, isActive, shortcutKey } = useListState(
6452
+ editor,
6453
+ type
6454
+ );
6455
+ const Icon = (listOption == null ? void 0 : listOption.icon) || import_icons16.ListIcon;
6456
+ const handleClick = (0, import_react45.useCallback)(
6457
+ (e) => {
6458
+ onClick == null ? void 0 : onClick(e);
6459
+ if (!e.defaultPrevented && editor) {
6460
+ toggleList(editor, type);
6461
+ }
6462
+ },
6463
+ [onClick, editor, type]
6464
+ );
6465
+ const show = (0, import_react45.useMemo)(() => {
6466
+ return shouldShowListButton({
6467
+ editor,
6468
+ type,
6469
+ hideWhenUnavailable,
6470
+ listInSchema
6471
+ });
6472
+ }, [editor, type, hideWhenUnavailable, listInSchema]);
6473
+ if (!show || !editor || !editor.isEditable) {
6474
+ return null;
6475
+ }
6476
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6477
+ import_button12.Button,
6478
+ {
6479
+ type: "button",
6480
+ className: className.trim(),
6481
+ variant: "ghost",
6482
+ color: "default",
6483
+ "data-active-state": isActive ? "on" : "off",
6484
+ tabIndex: -1,
6485
+ "aria-label": (listOption == null ? void 0 : listOption.label) || type,
6486
+ "aria-pressed": isActive,
6487
+ tooltip: (listOption == null ? void 0 : listOption.label) || type,
6488
+ shortcutKeys: shortcutKey,
6489
+ onClick: handleClick,
6490
+ startContent: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, {}),
6491
+ ...buttonProps,
6492
+ ref,
6493
+ children: children || text
6494
+ }
6495
+ );
6496
+ };
6497
+
6498
+ // src/ui/list-dropdown-menu/index.tsx
6499
+ var import_jsx_runtime24 = require("react/jsx-runtime");
6500
+ function canToggleAnyList(editor, listTypes) {
6501
+ if (!editor) return false;
6502
+ return listTypes.some((type) => canToggleList(editor, type));
6503
+ }
6504
+ function isAnyListActive(editor, listTypes) {
6505
+ if (!editor) return false;
6506
+ return listTypes.some((type) => isListActive(editor, type));
6507
+ }
6508
+ function getFilteredListOptions(availableTypes) {
6509
+ return listOptions.filter(
6510
+ (option) => !option.type || availableTypes.includes(option.type)
6511
+ );
6512
+ }
6513
+ function shouldShowListDropdown(params) {
6514
+ const { editor, hideWhenUnavailable, listInSchema, canToggleAny } = params;
6515
+ if (!listInSchema || !editor) {
6516
+ return false;
6517
+ }
6518
+ if (hideWhenUnavailable) {
6519
+ if ((0, import_react46.isNodeSelection)(editor.state.selection) || !canToggleAny) {
6520
+ return false;
6521
+ }
6522
+ }
6523
+ return true;
6524
+ }
6525
+ function useListDropdownState(editor, availableTypes) {
6526
+ const [isOpen, setIsOpen] = (0, import_react47.useState)(false);
6527
+ const listInSchema = availableTypes.some(
6528
+ (type) => (0, import_editor_utils16.isNodeInSchema)(type, editor)
6529
+ );
6530
+ const filteredLists = (0, import_react47.useMemo)(
6531
+ () => getFilteredListOptions(availableTypes),
6532
+ [availableTypes]
6533
+ );
6534
+ const canToggleAny = canToggleAnyList(editor, availableTypes);
6535
+ const isAnyActive = isAnyListActive(editor, availableTypes);
6536
+ const handleOpenChange = (0, import_react47.useCallback)(
6537
+ (open, callback) => {
6538
+ setIsOpen(open);
6539
+ callback == null ? void 0 : callback(open);
6540
+ },
6541
+ []
6542
+ );
6543
+ return {
6544
+ isOpen,
6545
+ setIsOpen,
6546
+ listInSchema,
6547
+ filteredLists,
6548
+ canToggleAny,
6549
+ isAnyActive,
6550
+ handleOpenChange
6551
+ };
6552
+ }
6553
+ function useActiveListIcon(editor, filteredLists) {
6554
+ return (0, import_react47.useCallback)(() => {
6555
+ const activeOption = filteredLists.find(
6556
+ (option) => isListActive(editor, option.type)
6557
+ );
6558
+ return activeOption ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(activeOption.icon, {}) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_icons17.ListIcon, {});
6559
+ }, [editor, filteredLists]);
6560
+ }
6561
+ function ListDropdownMenu({
6562
+ editor: providedEditor,
6563
+ types = ["bulletList", "orderedList", "taskList"],
6564
+ hideWhenUnavailable = false,
6565
+ onOpenChange,
6566
+ ...props
6567
+ }) {
6568
+ const { editor } = (0, import_editor_utils16.useTiptapEditor)(providedEditor);
6569
+ const {
6570
+ isOpen,
6571
+ listInSchema,
6572
+ filteredLists,
6573
+ canToggleAny,
6574
+ isAnyActive,
6575
+ handleOpenChange
6576
+ } = useListDropdownState(editor, types);
6577
+ const getActiveIcon = useActiveListIcon(editor, filteredLists);
6578
+ const show = (0, import_react47.useMemo)(() => {
6579
+ return shouldShowListDropdown({
6580
+ editor,
6581
+ listTypes: types,
6582
+ hideWhenUnavailable,
6583
+ listInSchema,
6584
+ canToggleAny
6585
+ });
6586
+ }, [editor, types, hideWhenUnavailable, listInSchema, canToggleAny]);
6587
+ const handleOnOpenChange = (0, import_react47.useCallback)(
6588
+ (open) => handleOpenChange(open, onOpenChange),
6589
+ [handleOpenChange, onOpenChange]
6590
+ );
6591
+ if (!show || !editor || !editor.isEditable) {
6592
+ return null;
6593
+ }
6594
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_dropdown_menu.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
6595
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_dropdown_menu.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6596
+ import_button13.Button,
6597
+ {
6598
+ type: "button",
6599
+ variant: "ghost",
6600
+ color: "default",
6601
+ "data-active-state": isAnyActive ? "on" : "off",
6602
+ tabIndex: -1,
6603
+ "aria-label": "List options",
6604
+ tooltip: "List",
6605
+ endContent: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_icons17.ChevronDownIcon, {}),
6606
+ ...props,
6607
+ children: getActiveIcon()
6608
+ }
6609
+ ) }),
6610
+ /* @__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)(
6611
+ ListButton,
6612
+ {
6613
+ editor,
6614
+ type: option.type,
6615
+ text: option.label,
6616
+ hideWhenUnavailable,
6617
+ tooltip: "",
6618
+ fullWidth: true,
6619
+ spacing: "start"
6620
+ }
6621
+ ) }, option.type)) }) })
6622
+ ] });
6623
+ }
6624
+
6625
+ // src/ui/table-button/index.tsx
6626
+ var import_editor_utils17 = require("@kopexa/editor-utils");
6627
+ var import_toolbar6 = require("@kopexa/toolbar");
6628
+ var import_react48 = require("react");
6629
+ var import_jsx_runtime25 = require("react/jsx-runtime");
6630
+ var TableButton = ({
6631
+ editor: providedEditor,
6632
+ text,
6633
+ hideWhenUnavailable = false,
6634
+ onToggled,
6635
+ onClick,
6636
+ children,
6637
+ ...buttonProps
6638
+ }) => {
6639
+ const { editor } = (0, import_editor_utils17.useTiptapEditor)(providedEditor);
6640
+ const {
6641
+ isVisible,
6642
+ canToggle: canToggle3,
6643
+ isActive,
6644
+ handleToggle,
6645
+ label,
6646
+ // shortcutKeys,
6647
+ Icon
6648
+ } = useTableBlock({
6649
+ editor,
6650
+ hideWhenUnavailable,
6651
+ onToggled
6652
+ });
6653
+ const handleClick = (0, import_react48.useCallback)(
6654
+ (event) => {
6655
+ onClick == null ? void 0 : onClick(event);
6656
+ if (event.defaultPrevented) return;
6657
+ handleToggle();
6658
+ },
6659
+ [handleToggle, onClick]
6660
+ );
6661
+ if (!isVisible) {
6662
+ return null;
6663
+ }
6664
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6665
+ import_toolbar6.ToolbarButton,
6666
+ {
6667
+ type: "button",
6668
+ variant: "ghost",
6669
+ color: "default",
6670
+ "data-active-state": isActive ? "on" : "off",
6671
+ disabled: !canToggle3,
6672
+ "data-disabled": !canToggle3,
6673
+ tabIndex: -1,
6674
+ "aria-label": label,
6675
+ "aria-pressed": isActive,
6676
+ title: label,
6677
+ onClick: handleClick,
6678
+ isIconOnly: !text && !children,
6679
+ ...buttonProps,
6680
+ children: children || /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
6681
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, {}),
6682
+ text && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: text })
6683
+ ] })
6107
6684
  }
6108
6685
  );
6109
6686
  };
6110
6687
 
6111
- // src/ui/codeblock-button/code-block-button.tsx
6112
- var import_editor_utils15 = require("@kopexa/editor-utils");
6113
- var import_icons16 = require("@kopexa/icons");
6114
- var import_toolbar5 = require("@kopexa/toolbar");
6115
- var import_react42 = require("react");
6688
+ // src/ui/text-align-button/text-align-button.tsx
6689
+ var import_button14 = require("@kopexa/button");
6690
+ var import_editor_utils19 = require("@kopexa/editor-utils");
6691
+ var import_react50 = require("react");
6116
6692
 
6117
- // src/ui/codeblock-button/use-code-block.ts
6118
- var import_editor_utils14 = require("@kopexa/editor-utils");
6119
- var import_icons15 = require("@kopexa/icons");
6120
- var import_state8 = require("@tiptap/pm/state");
6121
- var React16 = __toESM(require("react"));
6122
- var CODE_BLOCK_SHORTCUT_KEY = "mod+alt+c";
6123
- function canToggle2(editor, turnInto = true) {
6124
- var _a;
6693
+ // src/ui/text-align-button/use-text-align.ts
6694
+ var import_editor_utils18 = require("@kopexa/editor-utils");
6695
+ var import_icons18 = require("@kopexa/icons");
6696
+ var import_react49 = require("react");
6697
+ var TEXT_ALIGN_SHORTCUT_KEYS = {
6698
+ left: "mod+shift+l",
6699
+ center: "mod+shift+e",
6700
+ right: "mod+shift+r",
6701
+ justify: "mod+shift+j"
6702
+ };
6703
+ var textAlignIcons = {
6704
+ left: import_icons18.AlignLeftIcon,
6705
+ center: import_icons18.AlignCenterIcon,
6706
+ right: import_icons18.AlignRightIcon,
6707
+ justify: import_icons18.AlignJustifyIcon
6708
+ };
6709
+ var textAlignLabels = {
6710
+ left: "Align left",
6711
+ center: "Align center",
6712
+ right: "Align right",
6713
+ justify: "Align justify"
6714
+ };
6715
+ function canSetTextAlign(editor, align) {
6125
6716
  if (!editor || !editor.isEditable) return false;
6126
- if (!(0, import_editor_utils14.isNodeInSchema)("codeBlock", editor) || (0, import_editor_utils14.isNodeTypeSelected)(editor, ["image"]))
6127
- return false;
6128
- if (!turnInto) {
6129
- return editor.can().toggleNode("codeBlock", "paragraph");
6130
- }
6131
- try {
6132
- const view = editor.view;
6133
- const state = view.state;
6134
- const selection = state.selection;
6135
- if (selection.empty || selection instanceof import_state8.TextSelection) {
6136
- const pos = (_a = (0, import_editor_utils14.findNodePosition)({
6137
- editor,
6138
- node: state.selection.$anchor.node(1)
6139
- })) == null ? void 0 : _a.pos;
6140
- if (!(0, import_editor_utils14.isValidPosition)(pos)) return false;
6141
- }
6142
- return true;
6143
- } catch {
6717
+ if (!(0, import_editor_utils18.isExtensionAvailable)(editor, "textAlign") || (0, import_editor_utils18.isNodeTypeSelected)(editor, ["image"]))
6144
6718
  return false;
6145
- }
6719
+ return editor.can().setTextAlign(align);
6146
6720
  }
6147
- function toggleCodeBlock(editor) {
6148
- var _a, _b, _c;
6721
+ function hasSetTextAlign(commands) {
6722
+ return "setTextAlign" in commands;
6723
+ }
6724
+ function isTextAlignActive(editor, align) {
6149
6725
  if (!editor || !editor.isEditable) return false;
6150
- if (!canToggle2(editor)) return false;
6151
- try {
6152
- const view = editor.view;
6153
- let state = view.state;
6154
- let tr = state.tr;
6155
- if (state.selection.empty || state.selection instanceof import_state8.TextSelection) {
6156
- const pos = (_a = (0, import_editor_utils14.findNodePosition)({
6157
- editor,
6158
- node: state.selection.$anchor.node(1)
6159
- })) == null ? void 0 : _a.pos;
6160
- if (!(0, import_editor_utils14.isValidPosition)(pos)) return false;
6161
- tr = tr.setSelection(import_state8.NodeSelection.create(state.doc, pos));
6162
- view.dispatch(tr);
6163
- state = view.state;
6164
- }
6165
- const selection = state.selection;
6166
- let chain = editor.chain().focus();
6167
- if (selection instanceof import_state8.NodeSelection) {
6168
- const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
6169
- const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
6170
- const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
6171
- const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
6172
- chain = chain.setTextSelection({ from, to }).clearNodes();
6173
- }
6174
- const toggle = editor.isActive("codeBlock") ? chain.setNode("paragraph") : chain.toggleNode("codeBlock", "paragraph");
6175
- toggle.run();
6176
- editor.chain().focus().selectTextblockEnd().run();
6177
- return true;
6178
- } catch {
6179
- return false;
6726
+ return editor.isActive({ textAlign: align });
6727
+ }
6728
+ function setTextAlign(editor, align) {
6729
+ if (!editor || !editor.isEditable) return false;
6730
+ if (!canSetTextAlign(editor, align)) return false;
6731
+ const chain = editor.chain().focus();
6732
+ if (hasSetTextAlign(chain)) {
6733
+ return chain.setTextAlign(align).run();
6180
6734
  }
6735
+ return false;
6181
6736
  }
6182
6737
  function shouldShowButton3(props) {
6183
- const { editor, hideWhenUnavailable } = props;
6738
+ const { editor, hideWhenUnavailable, align } = props;
6184
6739
  if (!editor || !editor.isEditable) return false;
6185
- if (!(0, import_editor_utils14.isNodeInSchema)("codeBlock", editor)) return false;
6740
+ if (!(0, import_editor_utils18.isExtensionAvailable)(editor, "textAlign")) return false;
6186
6741
  if (hideWhenUnavailable && !editor.isActive("code")) {
6187
- return canToggle2(editor);
6742
+ return canSetTextAlign(editor, align);
6188
6743
  }
6189
6744
  return true;
6190
6745
  }
6191
- function useCodeBlock(config) {
6746
+ function useTextAlign(config) {
6192
6747
  const {
6193
6748
  editor: providedEditor,
6749
+ align,
6194
6750
  hideWhenUnavailable = false,
6195
- onToggled
6196
- } = config || {};
6197
- const { editor } = (0, import_editor_utils14.useTiptapEditor)(providedEditor);
6198
- const [isVisible, setIsVisible] = React16.useState(true);
6199
- const canToggleState = canToggle2(editor);
6200
- const isActive = (editor == null ? void 0 : editor.isActive("codeBlock")) || false;
6201
- React16.useEffect(() => {
6751
+ onAligned
6752
+ } = config;
6753
+ const { editor } = (0, import_editor_utils18.useTiptapEditor)(providedEditor);
6754
+ const [isVisible, setIsVisible] = (0, import_react49.useState)(true);
6755
+ const canAlign = canSetTextAlign(editor, align);
6756
+ const isActive = isTextAlignActive(editor, align);
6757
+ (0, import_react49.useEffect)(() => {
6202
6758
  if (!editor) return;
6203
6759
  const handleSelectionUpdate = () => {
6204
- setIsVisible(shouldShowButton3({ editor, hideWhenUnavailable }));
6760
+ setIsVisible(shouldShowButton3({ editor, align, hideWhenUnavailable }));
6205
6761
  };
6206
6762
  handleSelectionUpdate();
6207
6763
  editor.on("selectionUpdate", handleSelectionUpdate);
6208
6764
  return () => {
6209
6765
  editor.off("selectionUpdate", handleSelectionUpdate);
6210
6766
  };
6211
- }, [editor, hideWhenUnavailable]);
6212
- const handleToggle = React16.useCallback(() => {
6767
+ }, [editor, hideWhenUnavailable, align]);
6768
+ const handleTextAlign = (0, import_react49.useCallback)(() => {
6213
6769
  if (!editor) return false;
6214
- const success = toggleCodeBlock(editor);
6770
+ const success = setTextAlign(editor, align);
6215
6771
  if (success) {
6216
- onToggled == null ? void 0 : onToggled();
6772
+ onAligned == null ? void 0 : onAligned();
6217
6773
  }
6218
6774
  return success;
6219
- }, [editor, onToggled]);
6775
+ }, [editor, align, onAligned]);
6220
6776
  return {
6221
6777
  isVisible,
6222
6778
  isActive,
6223
- handleToggle,
6224
- canToggle: canToggleState,
6225
- label: "Code Block",
6226
- shortcutKeys: CODE_BLOCK_SHORTCUT_KEY,
6227
- Icon: import_icons15.CodeblockIcon
6779
+ handleTextAlign,
6780
+ canAlign,
6781
+ label: textAlignLabels[align],
6782
+ shortcutKeys: TEXT_ALIGN_SHORTCUT_KEYS[align],
6783
+ Icon: textAlignIcons[align]
6228
6784
  };
6229
6785
  }
6230
6786
 
6231
- // src/ui/codeblock-button/code-block-button.tsx
6232
- var import_jsx_runtime22 = require("react/jsx-runtime");
6233
- var CodeBlockButton = ({
6787
+ // src/ui/text-align-button/text-align-button.tsx
6788
+ var import_jsx_runtime26 = require("react/jsx-runtime");
6789
+ var TextAlignButton = ({
6234
6790
  editor: providedEditor,
6791
+ align,
6235
6792
  text,
6236
6793
  hideWhenUnavailable = false,
6237
- onToggled,
6794
+ onAligned,
6238
6795
  showShortcut = false,
6239
6796
  onClick,
6240
6797
  children,
6241
6798
  ...buttonProps
6242
6799
  }) => {
6243
- const { editor } = (0, import_editor_utils15.useTiptapEditor)(providedEditor);
6244
- const { isVisible, canToggle: canToggle3, isActive, handleToggle, label, shortcutKeys } = useCodeBlock({
6800
+ const { editor } = (0, import_editor_utils19.useTiptapEditor)(providedEditor);
6801
+ const {
6802
+ isVisible,
6803
+ handleTextAlign,
6804
+ label,
6805
+ canAlign,
6806
+ isActive,
6807
+ Icon,
6808
+ shortcutKeys
6809
+ } = useTextAlign({
6245
6810
  editor,
6811
+ align,
6246
6812
  hideWhenUnavailable,
6247
- onToggled
6813
+ onAligned
6248
6814
  });
6249
- const handleClick = (0, import_react42.useCallback)(
6250
- (event) => {
6251
- onClick == null ? void 0 : onClick(event);
6252
- if (event.defaultPrevented) return;
6253
- handleToggle();
6815
+ const handleClick = (0, import_react50.useCallback)(
6816
+ (e) => {
6817
+ onClick == null ? void 0 : onClick(e);
6818
+ if (e.defaultPrevented) return;
6819
+ handleTextAlign();
6254
6820
  },
6255
- [handleToggle, onClick]
6821
+ [handleTextAlign, onClick]
6256
6822
  );
6257
6823
  if (!isVisible) {
6258
6824
  return null;
6259
6825
  }
6260
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6261
- import_toolbar5.ToolbarButton,
6826
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6827
+ import_button14.IconButton,
6262
6828
  {
6263
6829
  type: "button",
6830
+ disabled: canAlign,
6264
6831
  variant: "ghost",
6265
6832
  color: "default",
6266
- disabled: !canToggle3,
6267
- "data-disabled": !canToggle3,
6268
6833
  "data-active-state": isActive ? "on" : "off",
6834
+ "data-disabled": canAlign,
6269
6835
  tabIndex: -1,
6270
- "aria-label": "codeBlock",
6836
+ "aria-label": label,
6271
6837
  "aria-pressed": isActive,
6272
- title: label,
6838
+ tooltip: label,
6273
6839
  shortcutKeys,
6274
6840
  onClick: handleClick,
6275
- isIconOnly: true,
6276
6841
  ...buttonProps,
6277
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons16.CodeblockIcon, {})
6842
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Icon, {})
6278
6843
  }
6279
6844
  );
6280
6845
  };
6281
6846
 
6282
- // src/ui/color-highlight-popover/color-highlight-popover.tsx
6283
- var import_button11 = require("@kopexa/button");
6284
- var import_editor_utils18 = require("@kopexa/editor-utils");
6285
- var import_icons18 = require("@kopexa/icons");
6286
- var import_popover2 = require("@kopexa/popover");
6287
- var import_toolbar7 = require("@kopexa/toolbar");
6288
- var import_react44 = require("react");
6847
+ // src/ui/turn-into-dropdown/turn-into-dropdown.tsx
6848
+ var import_button17 = require("@kopexa/button");
6849
+ var import_dropdown_menu2 = require("@kopexa/dropdown-menu");
6850
+ var import_editor_utils28 = require("@kopexa/editor-utils");
6851
+ var import_react56 = require("react");
6289
6852
 
6290
- // src/ui/color-highlight-button/color-highlight-button.tsx
6291
- var import_editor_utils17 = require("@kopexa/editor-utils");
6292
- var import_theme8 = require("@kopexa/theme");
6293
- var import_toolbar6 = require("@kopexa/toolbar");
6294
- var import_react43 = require("react");
6853
+ // src/ui/blockquote-button/blockquote-button.tsx
6854
+ var import_editor_utils21 = require("@kopexa/editor-utils");
6855
+ var import_toolbar7 = require("@kopexa/toolbar");
6856
+ var React16 = __toESM(require("react"));
6295
6857
 
6296
- // src/ui/color-highlight-button/use-color-highlight.ts
6297
- var import_editor_utils16 = require("@kopexa/editor-utils");
6298
- var import_icons17 = require("@kopexa/icons");
6299
- var import_use_is_mobile = require("@kopexa/use-is-mobile");
6300
- var React17 = __toESM(require("react"));
6301
- var import_react_hotkeys_hook = require("react-hotkeys-hook");
6302
- var COLOR_HIGHLIGHT_SHORTCUT_KEY = "mod+shift+h";
6303
- var HIGHLIGHT_COLORS = [
6304
- {
6305
- label: "Default background",
6306
- value: "var(--tt-bg-color)",
6307
- border: "var(--tt-bg-color-contrast)"
6308
- },
6309
- {
6310
- label: "Gray background",
6311
- value: "var(--tt-color-highlight-gray)",
6312
- border: "var(--tt-color-highlight-gray-contrast)"
6313
- },
6314
- {
6315
- label: "Brown background",
6316
- value: "var(--tt-color-highlight-brown)",
6317
- border: "var(--tt-color-highlight-brown-contrast)"
6318
- },
6319
- {
6320
- label: "Orange background",
6321
- value: "var(--tt-color-highlight-orange)",
6322
- border: "var(--tt-color-highlight-orange-contrast)"
6323
- },
6324
- {
6325
- label: "Yellow background",
6326
- value: "var(--tt-color-highlight-yellow)",
6327
- border: "var(--tt-color-highlight-yellow-contrast)"
6328
- },
6329
- {
6330
- label: "Green background",
6331
- value: "var(--tt-color-highlight-green)",
6332
- border: "var(--tt-color-highlight-green-contrast)"
6333
- },
6334
- {
6335
- label: "Blue background",
6336
- value: "var(--tt-color-highlight-blue)",
6337
- border: "var(--tt-color-highlight-blue-contrast)"
6338
- },
6339
- {
6340
- label: "Purple background",
6341
- value: "var(--tt-color-highlight-purple)",
6342
- border: "var(--tt-color-highlight-purple-contrast)"
6343
- },
6344
- {
6345
- label: "Pink background",
6346
- value: "var(--tt-color-highlight-pink)",
6347
- border: "var(--tt-color-highlight-pink-contrast)"
6348
- },
6349
- {
6350
- label: "Red background",
6351
- value: "var(--tt-color-highlight-red)",
6352
- border: "var(--tt-color-highlight-red-contrast)"
6353
- }
6354
- ];
6355
- function pickHighlightColorsByValue(values) {
6356
- const colorMap = new Map(
6357
- HIGHLIGHT_COLORS.map((color) => [color.value, color])
6358
- );
6359
- return values.map((value) => colorMap.get(value)).filter((color) => !!color);
6360
- }
6361
- function canColorHighlight(editor) {
6858
+ // src/ui/blockquote-button/use-blockquote.ts
6859
+ var import_editor_utils20 = require("@kopexa/editor-utils");
6860
+ var import_icons19 = require("@kopexa/icons");
6861
+ var import_state7 = require("@tiptap/pm/state");
6862
+ var React15 = __toESM(require("react"));
6863
+ var BLOCKQUOTE_SHORTCUT_KEY = "mod+shift+b";
6864
+ function canToggleBlockquote(editor, turnInto = true) {
6865
+ var _a;
6362
6866
  if (!editor || !editor.isEditable) return false;
6363
- if (!(0, import_editor_utils16.isMarkInSchema)("highlight", editor) || (0, import_editor_utils16.isNodeTypeSelected)(editor, ["image"]))
6867
+ if (!(0, import_editor_utils20.isNodeInSchema)("blockquote", editor) || (0, import_editor_utils20.isNodeTypeSelected)(editor, ["image"]))
6364
6868
  return false;
6365
- return editor.can().setMark("highlight");
6366
- }
6367
- function isColorHighlightActive(editor, highlightColor) {
6368
- if (!editor || !editor.isEditable) return false;
6369
- return highlightColor ? editor.isActive("highlight", { color: highlightColor }) : editor.isActive("highlight");
6869
+ if (!turnInto) {
6870
+ return editor.can().toggleWrap("blockquote");
6871
+ }
6872
+ try {
6873
+ const view = editor.view;
6874
+ const state = view.state;
6875
+ const selection = state.selection;
6876
+ if (selection.empty || selection instanceof import_state7.TextSelection) {
6877
+ const pos = (_a = (0, import_editor_utils20.findNodePosition)({
6878
+ editor,
6879
+ node: state.selection.$anchor.node(1)
6880
+ })) == null ? void 0 : _a.pos;
6881
+ if (!(0, import_editor_utils20.isValidPosition)(pos)) return false;
6882
+ }
6883
+ return true;
6884
+ } catch {
6885
+ return false;
6886
+ }
6370
6887
  }
6371
- function removeHighlight(editor) {
6888
+ function toggleBlockquote(editor) {
6889
+ var _a, _b, _c;
6372
6890
  if (!editor || !editor.isEditable) return false;
6373
- if (!canColorHighlight(editor)) return false;
6374
- return editor.chain().focus().unsetMark("highlight").run();
6891
+ if (!canToggleBlockquote(editor)) return false;
6892
+ try {
6893
+ const view = editor.view;
6894
+ let state = view.state;
6895
+ let tr = state.tr;
6896
+ if (state.selection.empty || state.selection instanceof import_state7.TextSelection) {
6897
+ const pos = (_a = (0, import_editor_utils20.findNodePosition)({
6898
+ editor,
6899
+ node: state.selection.$anchor.node(1)
6900
+ })) == null ? void 0 : _a.pos;
6901
+ if (!(0, import_editor_utils20.isValidPosition)(pos)) return false;
6902
+ tr = tr.setSelection(import_state7.NodeSelection.create(state.doc, pos));
6903
+ view.dispatch(tr);
6904
+ state = view.state;
6905
+ }
6906
+ const selection = state.selection;
6907
+ let chain = editor.chain().focus();
6908
+ if (selection instanceof import_state7.NodeSelection) {
6909
+ const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
6910
+ const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
6911
+ const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
6912
+ const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
6913
+ chain = chain.setTextSelection({ from, to }).clearNodes();
6914
+ }
6915
+ const toggle = editor.isActive("blockquote") ? chain.lift("blockquote") : chain.wrapIn("blockquote");
6916
+ toggle.run();
6917
+ editor.chain().focus().selectTextblockEnd().run();
6918
+ return true;
6919
+ } catch {
6920
+ return false;
6921
+ }
6375
6922
  }
6376
6923
  function shouldShowButton4(props) {
6377
6924
  const { editor, hideWhenUnavailable } = props;
6378
6925
  if (!editor || !editor.isEditable) return false;
6379
- if (!(0, import_editor_utils16.isMarkInSchema)("highlight", editor)) return false;
6926
+ if (!(0, import_editor_utils20.isNodeInSchema)("blockquote", editor)) return false;
6380
6927
  if (hideWhenUnavailable && !editor.isActive("code")) {
6381
- return canColorHighlight(editor);
6928
+ return canToggleBlockquote(editor);
6382
6929
  }
6383
6930
  return true;
6384
6931
  }
6385
- function useColorHighlight(config) {
6932
+ function useBlockquote(config) {
6386
6933
  const {
6387
6934
  editor: providedEditor,
6388
- label,
6389
- highlightColor,
6390
6935
  hideWhenUnavailable = false,
6391
- onApplied
6392
- } = config;
6393
- const { editor } = (0, import_editor_utils16.useTiptapEditor)(providedEditor);
6394
- const isMobile = (0, import_use_is_mobile.useIsMobile)();
6395
- const [isVisible, setIsVisible] = React17.useState(true);
6396
- const canColorHighlightState = canColorHighlight(editor);
6397
- const isActive = isColorHighlightActive(editor, highlightColor);
6398
- React17.useEffect(() => {
6936
+ onToggled
6937
+ } = config || {};
6938
+ const { editor } = (0, import_editor_utils20.useTiptapEditor)(providedEditor);
6939
+ const [isVisible, setIsVisible] = React15.useState(true);
6940
+ const canToggle3 = canToggleBlockquote(editor);
6941
+ const isActive = (editor == null ? void 0 : editor.isActive("blockquote")) || false;
6942
+ React15.useEffect(() => {
6399
6943
  if (!editor) return;
6400
6944
  const handleSelectionUpdate = () => {
6401
6945
  setIsVisible(shouldShowButton4({ editor, hideWhenUnavailable }));
@@ -6406,674 +6950,403 @@ function useColorHighlight(config) {
6406
6950
  editor.off("selectionUpdate", handleSelectionUpdate);
6407
6951
  };
6408
6952
  }, [editor, hideWhenUnavailable]);
6409
- const handleColorHighlight = React17.useCallback(() => {
6410
- if (!editor || !canColorHighlightState || !highlightColor || !label)
6411
- return false;
6412
- if (editor.state.storedMarks) {
6413
- const highlightMarkType = editor.schema.marks.highlight;
6414
- if (highlightMarkType) {
6415
- editor.view.dispatch(
6416
- editor.state.tr.removeStoredMark(highlightMarkType)
6417
- );
6418
- }
6419
- }
6420
- setTimeout(() => {
6421
- const success = editor.chain().focus().toggleMark("highlight", { color: highlightColor }).run();
6422
- if (success) {
6423
- onApplied == null ? void 0 : onApplied({ color: highlightColor, label });
6424
- }
6425
- return success;
6426
- }, 0);
6427
- }, [canColorHighlightState, highlightColor, editor, label, onApplied]);
6428
- const handleRemoveHighlight = React17.useCallback(() => {
6429
- const success = removeHighlight(editor);
6953
+ const handleToggle = React15.useCallback(() => {
6954
+ if (!editor) return false;
6955
+ const success = toggleBlockquote(editor);
6430
6956
  if (success) {
6431
- onApplied == null ? void 0 : onApplied({ color: "", label: "Remove highlight" });
6957
+ onToggled == null ? void 0 : onToggled();
6432
6958
  }
6433
6959
  return success;
6434
- }, [editor, onApplied]);
6435
- (0, import_react_hotkeys_hook.useHotkeys)(
6436
- COLOR_HIGHLIGHT_SHORTCUT_KEY,
6437
- (event) => {
6438
- event.preventDefault();
6439
- handleColorHighlight();
6440
- },
6441
- {
6442
- enabled: isVisible && canColorHighlightState,
6443
- enableOnContentEditable: !isMobile,
6444
- enableOnFormTags: true
6445
- }
6446
- );
6960
+ }, [editor, onToggled]);
6447
6961
  return {
6448
6962
  isVisible,
6449
6963
  isActive,
6450
- handleColorHighlight,
6451
- handleRemoveHighlight,
6452
- canColorHighlight: canColorHighlightState,
6453
- label: label || `Highlight`,
6454
- shortcutKeys: COLOR_HIGHLIGHT_SHORTCUT_KEY,
6455
- Icon: import_icons17.HighlighterIcon
6964
+ handleToggle,
6965
+ canToggle: canToggle3,
6966
+ label: "Blockquote",
6967
+ shortcutKeys: BLOCKQUOTE_SHORTCUT_KEY,
6968
+ Icon: import_icons19.BlockquoteIcon
6456
6969
  };
6457
6970
  }
6458
6971
 
6459
- // src/ui/color-highlight-button/color-highlight-button.tsx
6460
- var import_jsx_runtime23 = require("react/jsx-runtime");
6461
- var ColorHighlightButton = ({
6972
+ // src/ui/blockquote-button/blockquote-button.tsx
6973
+ var import_jsx_runtime27 = require("react/jsx-runtime");
6974
+ var BlockquoteButton = ({
6462
6975
  editor: providedEditor,
6463
- highlightColor,
6464
6976
  text,
6465
6977
  hideWhenUnavailable = false,
6466
- onApplied,
6978
+ onToggled,
6467
6979
  showShortcut = false,
6468
6980
  onClick,
6469
6981
  children,
6470
- style,
6471
- className,
6472
6982
  ...buttonProps
6473
6983
  }) => {
6474
- const { editor } = (0, import_editor_utils17.useTiptapEditor)(providedEditor);
6984
+ const { editor } = (0, import_editor_utils21.useTiptapEditor)(providedEditor);
6475
6985
  const {
6476
6986
  isVisible,
6477
- canColorHighlight: canColorHighlight2,
6987
+ canToggle: canToggle3,
6478
6988
  isActive,
6479
- handleColorHighlight,
6989
+ handleToggle,
6480
6990
  label,
6481
- shortcutKeys
6482
- } = useColorHighlight({
6991
+ shortcutKeys,
6992
+ Icon
6993
+ } = useBlockquote({
6483
6994
  editor,
6484
- highlightColor,
6485
- label: text || `Toggle highlight (${highlightColor})`,
6486
6995
  hideWhenUnavailable,
6487
- onApplied
6996
+ onToggled
6488
6997
  });
6489
- const handleClick = (0, import_react43.useCallback)(
6998
+ const handleClick = React16.useCallback(
6490
6999
  (event) => {
6491
7000
  onClick == null ? void 0 : onClick(event);
6492
7001
  if (event.defaultPrevented) return;
6493
- handleColorHighlight();
7002
+ handleToggle();
6494
7003
  },
6495
- [handleColorHighlight, onClick]
6496
- );
6497
- const buttonStyle = (0, import_react43.useMemo)(
6498
- () => ({
6499
- ...style,
6500
- "--highlight-color": highlightColor
6501
- }),
6502
- [highlightColor, style]
7004
+ [handleToggle, onClick]
6503
7005
  );
6504
7006
  if (!isVisible) {
6505
7007
  return null;
6506
7008
  }
6507
- const styles = (0, import_theme8.colorHighlightButton)();
6508
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6509
- import_toolbar6.ToolbarButton,
7009
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
7010
+ import_toolbar7.ToolbarButton,
6510
7011
  {
6511
7012
  type: "button",
6512
- disabled: !canColorHighlight2,
6513
- "data-disabled": !canColorHighlight2,
6514
7013
  variant: "ghost",
6515
7014
  color: "default",
7015
+ disabled: !canToggle3,
7016
+ "data-disabled": !canToggle3,
6516
7017
  "data-active-state": isActive ? "on" : "off",
6517
7018
  tabIndex: -1,
6518
- "aria-label": label,
6519
- shortcutKeys,
7019
+ "aria-label": "blockquote",
6520
7020
  "aria-pressed": isActive,
7021
+ title: label,
7022
+ shortcutKeys,
6521
7023
  onClick: handleClick,
6522
- style: buttonStyle,
6523
- className: styles.button({ className }),
6524
- isIconOnly: true,
7024
+ isIconOnly: !text && !children,
6525
7025
  ...buttonProps,
6526
- children: [
6527
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6528
- "span",
6529
- {
6530
- "data-active-state": isActive ? "on" : "off",
6531
- className: styles.mark()
6532
- }
6533
- ),
6534
- children || /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6535
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6536
- "span",
6537
- {
6538
- style: { "--highlight-color": highlightColor }
6539
- }
6540
- ),
6541
- text
6542
- ] })
6543
- ]
7026
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
7027
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Icon, {}),
7028
+ text && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: text })
7029
+ ] })
6544
7030
  }
6545
7031
  );
6546
7032
  };
6547
7033
 
6548
- // src/ui/color-highlight-popover/color-highlight-popover.tsx
6549
- var import_jsx_runtime24 = require("react/jsx-runtime");
6550
- var ColorHighlightPopoverButton = ({
6551
- className,
6552
- children,
6553
- ...props
6554
- }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6555
- import_button11.IconButton,
6556
- {
6557
- type: "button",
6558
- className,
6559
- variant: "ghost",
6560
- color: "default",
6561
- tabIndex: -1,
6562
- "aria-label": "Highlight text",
6563
- tooltip: "Highlight",
6564
- isIconOnly: !children,
6565
- ...props,
6566
- children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_icons18.HighlighterIcon, {})
6567
- }
6568
- );
6569
- function ColorHighlightPopoverContent({
6570
- editor,
6571
- colors = pickHighlightColorsByValue([
6572
- "var(--tt-color-highlight-green)",
6573
- "var(--tt-color-highlight-blue)",
6574
- "var(--tt-color-highlight-red)",
6575
- "var(--tt-color-highlight-purple)",
6576
- "var(--tt-color-highlight-yellow)"
6577
- ])
6578
- }) {
6579
- const { handleRemoveHighlight } = useColorHighlight({ editor });
6580
- const containerRef = (0, import_react44.useRef)(null);
6581
- const menuItems = (0, import_react44.useMemo)(
6582
- () => [...colors, { label: "Remove highlight", value: "none" }],
6583
- [colors]
6584
- );
6585
- const { selectedIndex } = useMenuNavigation({
6586
- containerRef,
6587
- items: menuItems,
6588
- orientation: "both",
6589
- onSelect: (item) => {
6590
- if (!containerRef.current) return false;
6591
- const highlightedElement = containerRef.current.querySelector(
6592
- '[data-highlighted="true"]'
6593
- );
6594
- if (highlightedElement) highlightedElement.click();
6595
- if (item.value === "none") handleRemoveHighlight();
6596
- },
6597
- autoSelectFirstItem: false
6598
- });
6599
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { ref: containerRef, className: "flex gap-1 items-center", children: [
6600
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6601
- "div",
6602
- {
6603
- className: "flex items-center gap-1 outline-none",
6604
- "data-orientation": "horizontal",
6605
- children: colors.map((color, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6606
- ColorHighlightButton,
6607
- {
6608
- editor,
6609
- highlightColor: color.value,
6610
- "aria-label": `${color.label} highlight color`,
6611
- tabIndex: index === selectedIndex ? 0 : -1,
6612
- "data-highlighted": selectedIndex === index
6613
- },
6614
- color.value
6615
- ))
6616
- }
6617
- ),
6618
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_toolbar7.ToolbarSeparator, { orientation: "vertical" }),
6619
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "tiptap-button-group", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6620
- import_button11.IconButton,
6621
- {
6622
- onClick: handleRemoveHighlight,
6623
- "aria-label": "Remove highlight",
6624
- tabIndex: selectedIndex === colors.length ? 0 : -1,
6625
- type: "button",
6626
- role: "menuitem",
6627
- variant: "ghost",
6628
- color: "default",
6629
- "data-highlighted": selectedIndex === colors.length,
6630
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_icons18.BanIcon, {})
6631
- }
6632
- ) })
6633
- ] });
6634
- }
6635
- function ColorHighlightPopover({
6636
- editor: providedEditor,
6637
- colors = pickHighlightColorsByValue([
6638
- "var(--tt-color-highlight-green)",
6639
- "var(--tt-color-highlight-blue)",
6640
- "var(--tt-color-highlight-red)",
6641
- "var(--tt-color-highlight-purple)",
6642
- "var(--tt-color-highlight-yellow)"
6643
- ]),
6644
- hideWhenUnavailable = false,
6645
- onApplied,
6646
- ...props
6647
- }) {
6648
- const { editor } = (0, import_editor_utils18.useTiptapEditor)(providedEditor);
6649
- const [isOpen, setIsOpen] = (0, import_react44.useState)(false);
6650
- const { isVisible, canColorHighlight: canColorHighlight2, isActive, label } = useColorHighlight({
6651
- editor,
6652
- hideWhenUnavailable,
6653
- onApplied
6654
- });
6655
- if (!isVisible) return null;
6656
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_popover2.Popover.Root, { open: isOpen, onOpenChange: setIsOpen, spacing: "dense", children: [
6657
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6658
- import_popover2.Popover.Trigger,
6659
- {
6660
- render: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
6661
- ColorHighlightPopoverButton,
6662
- {
6663
- disabled: !canColorHighlight2,
6664
- "data-disabled": !canColorHighlight2,
6665
- "data-active-state": isActive ? "on" : "off",
6666
- "aria-pressed": isActive,
6667
- "aria-label": label,
6668
- title: label,
6669
- ...props
6670
- }
6671
- )
6672
- }
6673
- ),
6674
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_popover2.Popover.Content, { "aria-label": "Highlight colors", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ColorHighlightPopoverContent, { editor, colors }) })
6675
- ] });
6676
- }
7034
+ // src/ui/codeblock-button/code-block-button.tsx
7035
+ var import_editor_utils23 = require("@kopexa/editor-utils");
7036
+ var import_icons21 = require("@kopexa/icons");
7037
+ var import_toolbar8 = require("@kopexa/toolbar");
7038
+ var import_react51 = require("react");
6677
7039
 
6678
- // src/ui/heading-dropdown-menu/index.tsx
6679
- var import_button13 = require("@kopexa/button");
6680
- var import_dropdown_menu = require("@kopexa/dropdown-menu");
6681
- var import_editor_utils20 = require("@kopexa/editor-utils");
7040
+ // src/ui/codeblock-button/use-code-block.ts
7041
+ var import_editor_utils22 = require("@kopexa/editor-utils");
6682
7042
  var import_icons20 = require("@kopexa/icons");
6683
- var import_react46 = require("@tiptap/react");
6684
- var React19 = __toESM(require("react"));
6685
-
6686
- // src/ui/heading-button/index.tsx
6687
- var import_button12 = require("@kopexa/button");
6688
- var import_editor_utils19 = require("@kopexa/editor-utils");
6689
- var import_icons19 = require("@kopexa/icons");
6690
- var React18 = __toESM(require("react"));
6691
-
6692
- // src/ui/heading-button/utils.ts
6693
- var import_react45 = require("@tiptap/react");
6694
- var headingShortcutKeys = {
6695
- 1: "Ctrl-Alt-1",
6696
- 2: "Ctrl-Alt-2",
6697
- 3: "Ctrl-Alt-3",
6698
- 4: "Ctrl-Alt-4",
6699
- 5: "Ctrl-Alt-5",
6700
- 6: "Ctrl-Alt-6"
6701
- };
6702
- function canToggleHeading(editor, level) {
6703
- if (!editor) return false;
7043
+ var import_state8 = require("@tiptap/pm/state");
7044
+ var React17 = __toESM(require("react"));
7045
+ var CODE_BLOCK_SHORTCUT_KEY = "mod+alt+c";
7046
+ function canToggle2(editor, turnInto = true) {
7047
+ var _a;
7048
+ if (!editor || !editor.isEditable) return false;
7049
+ if (!(0, import_editor_utils22.isNodeInSchema)("codeBlock", editor) || (0, import_editor_utils22.isNodeTypeSelected)(editor, ["image"]))
7050
+ return false;
7051
+ if (!turnInto) {
7052
+ return editor.can().toggleNode("codeBlock", "paragraph");
7053
+ }
6704
7054
  try {
6705
- return editor.can().toggleNode("heading", "paragraph", { level });
7055
+ const view = editor.view;
7056
+ const state = view.state;
7057
+ const selection = state.selection;
7058
+ if (selection.empty || selection instanceof import_state8.TextSelection) {
7059
+ const pos = (_a = (0, import_editor_utils22.findNodePosition)({
7060
+ editor,
7061
+ node: state.selection.$anchor.node(1)
7062
+ })) == null ? void 0 : _a.pos;
7063
+ if (!(0, import_editor_utils22.isValidPosition)(pos)) return false;
7064
+ }
7065
+ return true;
6706
7066
  } catch {
6707
7067
  return false;
6708
7068
  }
6709
7069
  }
6710
- function isHeadingActive(editor, level) {
6711
- if (!editor) return false;
6712
- return editor.isActive("heading", { level });
6713
- }
6714
- function toggleHeading(editor, level) {
6715
- if (!editor) return;
6716
- if (editor.isActive("heading", { level })) {
6717
- editor.chain().focus().setNode("paragraph").run();
6718
- } else {
6719
- editor.chain().focus().toggleNode("heading", "paragraph", { level }).run();
6720
- }
6721
- }
6722
- function isHeadingButtonDisabled(editor, level, userDisabled = false) {
6723
- if (!editor) return true;
6724
- if (userDisabled) return true;
6725
- if (!canToggleHeading(editor, level)) return true;
6726
- return false;
6727
- }
6728
- function shouldShowHeadingButton(params) {
6729
- const { editor, hideWhenUnavailable, headingInSchema } = params;
6730
- if (!headingInSchema || !editor) {
7070
+ function toggleCodeBlock(editor) {
7071
+ var _a, _b, _c;
7072
+ if (!editor || !editor.isEditable) return false;
7073
+ if (!canToggle2(editor)) return false;
7074
+ try {
7075
+ const view = editor.view;
7076
+ let state = view.state;
7077
+ let tr = state.tr;
7078
+ if (state.selection.empty || state.selection instanceof import_state8.TextSelection) {
7079
+ const pos = (_a = (0, import_editor_utils22.findNodePosition)({
7080
+ editor,
7081
+ node: state.selection.$anchor.node(1)
7082
+ })) == null ? void 0 : _a.pos;
7083
+ if (!(0, import_editor_utils22.isValidPosition)(pos)) return false;
7084
+ tr = tr.setSelection(import_state8.NodeSelection.create(state.doc, pos));
7085
+ view.dispatch(tr);
7086
+ state = view.state;
7087
+ }
7088
+ const selection = state.selection;
7089
+ let chain = editor.chain().focus();
7090
+ if (selection instanceof import_state8.NodeSelection) {
7091
+ const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
7092
+ const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
7093
+ const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
7094
+ const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
7095
+ chain = chain.setTextSelection({ from, to }).clearNodes();
7096
+ }
7097
+ const toggle = editor.isActive("codeBlock") ? chain.setNode("paragraph") : chain.toggleNode("codeBlock", "paragraph");
7098
+ toggle.run();
7099
+ editor.chain().focus().selectTextblockEnd().run();
7100
+ return true;
7101
+ } catch {
6731
7102
  return false;
6732
7103
  }
6733
- if (hideWhenUnavailable) {
6734
- if ((0, import_react45.isNodeSelection)(editor.state.selection)) {
6735
- return false;
6736
- }
7104
+ }
7105
+ function shouldShowButton5(props) {
7106
+ const { editor, hideWhenUnavailable } = props;
7107
+ if (!editor || !editor.isEditable) return false;
7108
+ if (!(0, import_editor_utils22.isNodeInSchema)("codeBlock", editor)) return false;
7109
+ if (hideWhenUnavailable && !editor.isActive("code")) {
7110
+ return canToggle2(editor);
6737
7111
  }
6738
7112
  return true;
6739
7113
  }
6740
- function getFormattedHeadingName(level) {
6741
- return `Heading ${level}`;
6742
- }
6743
-
6744
- // src/ui/heading-button/index.tsx
6745
- var import_jsx_runtime25 = require("react/jsx-runtime");
6746
- var headingIcons = {
6747
- 1: import_icons19.HeadingOneIcon,
6748
- 2: import_icons19.HeadingTwoIcon,
6749
- 3: import_icons19.HeadingThreeIcon,
6750
- 4: import_icons19.HeadingFourIcon,
6751
- 5: import_icons19.HeadingFiveIcon,
6752
- 6: import_icons19.HeadingSixIcon
6753
- };
6754
- function useHeadingState(editor, level, disabled = false) {
6755
- const headingInSchema = (0, import_editor_utils19.isNodeInSchema)("heading", editor);
6756
- const isDisabled = isHeadingButtonDisabled(editor, level, disabled);
6757
- const isActive = isHeadingActive(editor, level);
6758
- const Icon = headingIcons[level];
6759
- const shortcutKey = headingShortcutKeys[level];
6760
- const formattedName = getFormattedHeadingName(level);
7114
+ function useCodeBlock(config) {
7115
+ const {
7116
+ editor: providedEditor,
7117
+ hideWhenUnavailable = false,
7118
+ onToggled
7119
+ } = config || {};
7120
+ const { editor } = (0, import_editor_utils22.useTiptapEditor)(providedEditor);
7121
+ const [isVisible, setIsVisible] = React17.useState(true);
7122
+ const canToggleState = canToggle2(editor);
7123
+ const isActive = (editor == null ? void 0 : editor.isActive("codeBlock")) || false;
7124
+ React17.useEffect(() => {
7125
+ if (!editor) return;
7126
+ const handleSelectionUpdate = () => {
7127
+ setIsVisible(shouldShowButton5({ editor, hideWhenUnavailable }));
7128
+ };
7129
+ handleSelectionUpdate();
7130
+ editor.on("selectionUpdate", handleSelectionUpdate);
7131
+ return () => {
7132
+ editor.off("selectionUpdate", handleSelectionUpdate);
7133
+ };
7134
+ }, [editor, hideWhenUnavailable]);
7135
+ const handleToggle = React17.useCallback(() => {
7136
+ if (!editor) return false;
7137
+ const success = toggleCodeBlock(editor);
7138
+ if (success) {
7139
+ onToggled == null ? void 0 : onToggled();
7140
+ }
7141
+ return success;
7142
+ }, [editor, onToggled]);
6761
7143
  return {
6762
- headingInSchema,
6763
- isDisabled,
7144
+ isVisible,
6764
7145
  isActive,
6765
- Icon,
6766
- shortcutKey,
6767
- formattedName
7146
+ handleToggle,
7147
+ canToggle: canToggleState,
7148
+ label: "Code Block",
7149
+ shortcutKeys: CODE_BLOCK_SHORTCUT_KEY,
7150
+ Icon: import_icons20.CodeblockIcon
6768
7151
  };
6769
7152
  }
6770
- var HeadingButton = ({
7153
+
7154
+ // src/ui/codeblock-button/code-block-button.tsx
7155
+ var import_jsx_runtime28 = require("react/jsx-runtime");
7156
+ var CodeBlockButton = ({
6771
7157
  editor: providedEditor,
6772
- level,
6773
7158
  text,
6774
7159
  hideWhenUnavailable = false,
6775
- className = "",
6776
- disabled,
7160
+ onToggled,
7161
+ showShortcut = false,
6777
7162
  onClick,
6778
7163
  children,
6779
- ref,
6780
7164
  ...buttonProps
6781
7165
  }) => {
6782
- const { editor } = (0, import_editor_utils19.useTiptapEditor)(providedEditor);
6783
- const {
6784
- headingInSchema,
6785
- isDisabled,
6786
- isActive,
6787
- Icon,
6788
- shortcutKey,
6789
- formattedName
6790
- } = useHeadingState(editor, level, disabled);
6791
- const handleClick = React18.useCallback(
6792
- (e) => {
6793
- onClick == null ? void 0 : onClick(e);
6794
- if (!e.defaultPrevented && !isDisabled && editor) {
6795
- toggleHeading(editor, level);
6796
- }
7166
+ const { editor } = (0, import_editor_utils23.useTiptapEditor)(providedEditor);
7167
+ const { isVisible, canToggle: canToggle3, isActive, handleToggle, label, shortcutKeys } = useCodeBlock({
7168
+ editor,
7169
+ hideWhenUnavailable,
7170
+ onToggled
7171
+ });
7172
+ const handleClick = (0, import_react51.useCallback)(
7173
+ (event) => {
7174
+ onClick == null ? void 0 : onClick(event);
7175
+ if (event.defaultPrevented) return;
7176
+ handleToggle();
6797
7177
  },
6798
- [onClick, isDisabled, editor, level]
7178
+ [handleToggle, onClick]
6799
7179
  );
6800
- const show = React18.useMemo(() => {
6801
- return shouldShowHeadingButton({
6802
- editor,
6803
- level,
6804
- hideWhenUnavailable,
6805
- headingInSchema
6806
- });
6807
- }, [editor, level, hideWhenUnavailable, headingInSchema]);
6808
- if (!show || !editor || !editor.isEditable) {
7180
+ if (!isVisible) {
6809
7181
  return null;
6810
7182
  }
6811
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6812
- import_button12.Button,
7183
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7184
+ import_toolbar8.ToolbarButton,
6813
7185
  {
6814
7186
  type: "button",
6815
- className: className.trim(),
6816
- disabled: isDisabled,
6817
7187
  variant: "ghost",
6818
7188
  color: "default",
7189
+ disabled: !canToggle3,
7190
+ "data-disabled": !canToggle3,
6819
7191
  "data-active-state": isActive ? "on" : "off",
6820
- "data-disabled": isDisabled,
6821
7192
  tabIndex: -1,
6822
- "aria-label": formattedName,
7193
+ "aria-label": "codeBlock",
6823
7194
  "aria-pressed": isActive,
6824
- tooltip: formattedName,
6825
- shortcutKeys: shortcutKey,
7195
+ title: label,
7196
+ shortcutKeys,
6826
7197
  onClick: handleClick,
6827
- startContent: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, {}),
7198
+ isIconOnly: !text && !children,
6828
7199
  ...buttonProps,
6829
- ref,
6830
- children: children || text
7200
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
7201
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons21.CodeblockIcon, {}),
7202
+ text && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: text })
7203
+ ] })
6831
7204
  }
6832
7205
  );
6833
7206
  };
6834
7207
 
6835
- // src/ui/heading-dropdown-menu/index.tsx
6836
- var import_jsx_runtime26 = require("react/jsx-runtime");
6837
- function HeadingDropdownMenu({
6838
- editor: providedEditor,
6839
- levels = [1, 2, 3, 4, 5, 6],
6840
- hideWhenUnavailable = false,
6841
- onOpenChange,
6842
- ...props
6843
- }) {
6844
- var _a;
6845
- const [isOpen, setIsOpen] = React19.useState(false);
6846
- const { editor } = (0, import_editor_utils20.useTiptapEditor)(providedEditor);
6847
- const headingInSchema = (0, import_editor_utils20.isNodeInSchema)("heading", editor);
6848
- const handleOnOpenChange = React19.useCallback(
6849
- (open) => {
6850
- setIsOpen(open);
6851
- onOpenChange == null ? void 0 : onOpenChange(open);
6852
- },
6853
- [onOpenChange]
6854
- );
6855
- const getActiveIcon = React19.useCallback(() => {
6856
- if (!editor) return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons20.HeadingIcon, {});
6857
- const activeLevel = levels.find(
6858
- (level) => editor.isActive("heading", { level })
6859
- );
6860
- if (!activeLevel) return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons20.HeadingIcon, {});
6861
- const ActiveIcon = headingIcons[activeLevel];
6862
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ActiveIcon, {});
6863
- }, [editor, levels]);
6864
- const canToggleAnyHeading = React19.useCallback(() => {
6865
- if (!editor) return false;
6866
- return levels.some(
6867
- (level) => editor.can().toggleNode("heading", "paragraph", { level })
6868
- );
6869
- }, [editor, levels]);
6870
- const isDisabled = !canToggleAnyHeading();
6871
- const isAnyHeadingActive = (_a = editor == null ? void 0 : editor.isActive("heading")) != null ? _a : false;
6872
- const show = React19.useMemo(() => {
6873
- if (!headingInSchema || !editor) {
6874
- return false;
6875
- }
6876
- if (hideWhenUnavailable) {
6877
- if ((0, import_react46.isNodeSelection)(editor.state.selection) || !canToggleAnyHeading()) {
6878
- return false;
6879
- }
6880
- }
6881
- return true;
6882
- }, [headingInSchema, editor, hideWhenUnavailable, canToggleAnyHeading]);
6883
- if (!show || !editor || !editor.isEditable) {
6884
- return null;
6885
- }
6886
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_dropdown_menu.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
6887
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_dropdown_menu.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6888
- import_button13.Button,
6889
- {
6890
- type: "button",
6891
- disabled: isDisabled,
6892
- variant: "ghost",
6893
- color: "default",
6894
- "data-active-state": isAnyHeadingActive ? "on" : "off",
6895
- "data-disabled": isDisabled,
6896
- tabIndex: -1,
6897
- "aria-label": "Format text as heading",
6898
- "aria-pressed": isAnyHeadingActive,
6899
- tooltip: "Heading",
6900
- endContent: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons20.ChevronDownIcon, {}),
6901
- ...props,
6902
- children: getActiveIcon()
6903
- }
6904
- ) }),
6905
- /* @__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)(
6906
- HeadingButton,
6907
- {
6908
- editor,
6909
- level,
6910
- text: getFormattedHeadingName(level),
6911
- tooltip: "",
6912
- fullWidth: true,
6913
- spacing: "start"
6914
- }
6915
- ) }, `heading-${level}`)) }) })
6916
- ] });
6917
- }
6918
-
6919
- // src/ui/list-dropdown-menu/index.tsx
7208
+ // src/ui/heading-button/index.tsx
6920
7209
  var import_button15 = require("@kopexa/button");
6921
- var import_dropdown_menu2 = require("@kopexa/dropdown-menu");
6922
- var import_editor_utils22 = require("@kopexa/editor-utils");
7210
+ var import_editor_utils24 = require("@kopexa/editor-utils");
6923
7211
  var import_icons22 = require("@kopexa/icons");
6924
- var import_react49 = require("@tiptap/react");
6925
- var import_react50 = require("react");
7212
+ var React18 = __toESM(require("react"));
6926
7213
 
6927
- // src/ui/list-button/index.tsx
6928
- var import_button14 = require("@kopexa/button");
6929
- var import_editor_utils21 = require("@kopexa/editor-utils");
6930
- var import_icons21 = require("@kopexa/icons");
6931
- var import_react47 = require("@tiptap/react");
6932
- var import_react48 = require("react");
6933
- var import_jsx_runtime27 = require("react/jsx-runtime");
6934
- var listOptions = [
6935
- {
6936
- label: "Bullet List",
6937
- type: "bulletList",
6938
- icon: import_icons21.ListIcon
6939
- },
6940
- {
6941
- label: "Ordered List",
6942
- type: "orderedList",
6943
- icon: import_icons21.ListOrderedIcon
6944
- },
6945
- {
6946
- label: "Task List",
6947
- type: "taskList",
6948
- icon: import_icons21.ListTodoIcon
6949
- }
6950
- ];
6951
- var listShortcutKeys = {
6952
- bulletList: "Ctrl-Shift-8",
6953
- orderedList: "Ctrl-Shift-7",
6954
- taskList: "Ctrl-Shift-9"
7214
+ // src/ui/heading-button/utils.ts
7215
+ var import_react52 = require("@tiptap/react");
7216
+ var headingShortcutKeys = {
7217
+ 1: "Ctrl-Alt-1",
7218
+ 2: "Ctrl-Alt-2",
7219
+ 3: "Ctrl-Alt-3",
7220
+ 4: "Ctrl-Alt-4",
7221
+ 5: "Ctrl-Alt-5",
7222
+ 6: "Ctrl-Alt-6"
6955
7223
  };
6956
- function canToggleList(editor, type) {
6957
- if (!editor) {
7224
+ function canToggleHeading(editor, level) {
7225
+ if (!editor) return false;
7226
+ try {
7227
+ return editor.can().toggleNode("heading", "paragraph", { level });
7228
+ } catch {
6958
7229
  return false;
6959
7230
  }
6960
- switch (type) {
6961
- case "bulletList":
6962
- return editor.can().toggleBulletList();
6963
- case "orderedList":
6964
- return editor.can().toggleOrderedList();
6965
- case "taskList":
6966
- return editor.can().toggleList("taskList", "taskItem");
6967
- default:
6968
- return false;
6969
- }
6970
7231
  }
6971
- function isListActive(editor, type) {
7232
+ function isHeadingActive(editor, level) {
6972
7233
  if (!editor) return false;
6973
- switch (type) {
6974
- case "bulletList":
6975
- return editor.isActive("bulletList");
6976
- case "orderedList":
6977
- return editor.isActive("orderedList");
6978
- case "taskList":
6979
- return editor.isActive("taskList");
6980
- default:
6981
- return false;
6982
- }
7234
+ return editor.isActive("heading", { level });
6983
7235
  }
6984
- function toggleList(editor, type) {
7236
+ function toggleHeading(editor, level) {
6985
7237
  if (!editor) return;
6986
- switch (type) {
6987
- case "bulletList":
6988
- editor.chain().focus().toggleBulletList().run();
6989
- break;
6990
- case "orderedList":
6991
- editor.chain().focus().toggleOrderedList().run();
6992
- break;
6993
- case "taskList":
6994
- editor.chain().focus().toggleList("taskList", "taskItem").run();
6995
- break;
7238
+ if (editor.isActive("heading", { level })) {
7239
+ editor.chain().focus().setNode("paragraph").run();
7240
+ } else {
7241
+ editor.chain().focus().toggleNode("heading", "paragraph", { level }).run();
6996
7242
  }
6997
7243
  }
6998
- function getListOption(type) {
6999
- return listOptions.find((option) => option.type === type);
7244
+ function isHeadingButtonDisabled(editor, level, userDisabled = false) {
7245
+ if (!editor) return true;
7246
+ if (userDisabled) return true;
7247
+ if (!canToggleHeading(editor, level)) return true;
7248
+ return false;
7000
7249
  }
7001
- function shouldShowListButton(params) {
7002
- const { editor, type, hideWhenUnavailable, listInSchema } = params;
7003
- if (!listInSchema || !editor) {
7250
+ function shouldShowHeadingButton(params) {
7251
+ const { editor, hideWhenUnavailable, headingInSchema } = params;
7252
+ if (!headingInSchema || !editor) {
7004
7253
  return false;
7005
7254
  }
7006
7255
  if (hideWhenUnavailable) {
7007
- if ((0, import_react47.isNodeSelection)(editor.state.selection) || !canToggleList(editor, type)) {
7256
+ if ((0, import_react52.isNodeSelection)(editor.state.selection)) {
7008
7257
  return false;
7009
7258
  }
7010
7259
  }
7011
7260
  return true;
7012
7261
  }
7013
- function useListState(editor, type) {
7014
- const listInSchema = (0, import_editor_utils21.isNodeInSchema)(type, editor);
7015
- const listOption = getListOption(type);
7016
- const isActive = isListActive(editor, type);
7017
- const shortcutKey = listShortcutKeys[type];
7262
+ function getFormattedHeadingName(level) {
7263
+ return `Heading ${level}`;
7264
+ }
7265
+
7266
+ // src/ui/heading-button/index.tsx
7267
+ var import_jsx_runtime29 = require("react/jsx-runtime");
7268
+ var headingIcons = {
7269
+ 1: import_icons22.HeadingOneIcon,
7270
+ 2: import_icons22.HeadingTwoIcon,
7271
+ 3: import_icons22.HeadingThreeIcon,
7272
+ 4: import_icons22.HeadingFourIcon,
7273
+ 5: import_icons22.HeadingFiveIcon,
7274
+ 6: import_icons22.HeadingSixIcon
7275
+ };
7276
+ function useHeadingState(editor, level, disabled = false) {
7277
+ const headingInSchema = (0, import_editor_utils24.isNodeInSchema)("heading", editor);
7278
+ const isDisabled = isHeadingButtonDisabled(editor, level, disabled);
7279
+ const isActive = isHeadingActive(editor, level);
7280
+ const Icon = headingIcons[level];
7281
+ const shortcutKey = headingShortcutKeys[level];
7282
+ const formattedName = getFormattedHeadingName(level);
7018
7283
  return {
7019
- listInSchema,
7020
- listOption,
7284
+ headingInSchema,
7285
+ isDisabled,
7021
7286
  isActive,
7022
- shortcutKey
7287
+ Icon,
7288
+ shortcutKey,
7289
+ formattedName
7023
7290
  };
7024
7291
  }
7025
- var ListButton = ({
7292
+ var HeadingButton = ({
7026
7293
  editor: providedEditor,
7027
- type,
7294
+ level,
7295
+ text,
7028
7296
  hideWhenUnavailable = false,
7029
7297
  className = "",
7298
+ disabled,
7030
7299
  onClick,
7031
- text,
7032
7300
  children,
7033
7301
  ref,
7034
7302
  ...buttonProps
7035
7303
  }) => {
7036
- const { editor } = (0, import_editor_utils21.useTiptapEditor)(providedEditor);
7037
- const { listInSchema, listOption, isActive, shortcutKey } = useListState(
7038
- editor,
7039
- type
7040
- );
7041
- const Icon = (listOption == null ? void 0 : listOption.icon) || import_icons21.ListIcon;
7042
- const handleClick = (0, import_react48.useCallback)(
7304
+ const { editor } = (0, import_editor_utils24.useTiptapEditor)(providedEditor);
7305
+ const {
7306
+ headingInSchema,
7307
+ isDisabled,
7308
+ isActive,
7309
+ Icon,
7310
+ shortcutKey,
7311
+ formattedName
7312
+ } = useHeadingState(editor, level, disabled);
7313
+ const handleClick = React18.useCallback(
7043
7314
  (e) => {
7044
7315
  onClick == null ? void 0 : onClick(e);
7045
- if (!e.defaultPrevented && editor) {
7046
- toggleList(editor, type);
7316
+ if (!e.defaultPrevented && !isDisabled && editor) {
7317
+ toggleHeading(editor, level);
7047
7318
  }
7048
7319
  },
7049
- [onClick, editor, type]
7320
+ [onClick, isDisabled, editor, level]
7050
7321
  );
7051
- const show = (0, import_react48.useMemo)(() => {
7052
- return shouldShowListButton({
7322
+ const show = React18.useMemo(() => {
7323
+ return shouldShowHeadingButton({
7053
7324
  editor,
7054
- type,
7325
+ level,
7055
7326
  hideWhenUnavailable,
7056
- listInSchema
7327
+ headingInSchema
7057
7328
  });
7058
- }, [editor, type, hideWhenUnavailable, listInSchema]);
7329
+ }, [editor, level, hideWhenUnavailable, headingInSchema]);
7059
7330
  if (!show || !editor || !editor.isEditable) {
7060
7331
  return null;
7061
7332
  }
7062
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
7063
- import_button14.Button,
7333
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7334
+ import_button15.Button,
7064
7335
  {
7065
7336
  type: "button",
7066
7337
  className: className.trim(),
7338
+ disabled: isDisabled,
7067
7339
  variant: "ghost",
7068
7340
  color: "default",
7069
7341
  "data-active-state": isActive ? "on" : "off",
7342
+ "data-disabled": isDisabled,
7070
7343
  tabIndex: -1,
7071
- "aria-label": (listOption == null ? void 0 : listOption.label) || type,
7344
+ "aria-label": formattedName,
7072
7345
  "aria-pressed": isActive,
7073
- tooltip: (listOption == null ? void 0 : listOption.label) || type,
7346
+ tooltip: formattedName,
7074
7347
  shortcutKeys: shortcutKey,
7075
7348
  onClick: handleClick,
7076
- startContent: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Icon, {}),
7349
+ startContent: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon, {}),
7077
7350
  ...buttonProps,
7078
7351
  ref,
7079
7352
  children: children || text
@@ -7081,162 +7354,189 @@ var ListButton = ({
7081
7354
  );
7082
7355
  };
7083
7356
 
7084
- // src/ui/list-dropdown-menu/index.tsx
7085
- var import_jsx_runtime28 = require("react/jsx-runtime");
7086
- function canToggleAnyList(editor, listTypes) {
7357
+ // src/ui/text-button/text-button.tsx
7358
+ var import_button16 = require("@kopexa/button");
7359
+ var import_chip = require("@kopexa/chip");
7360
+ var import_editor_utils26 = require("@kopexa/editor-utils");
7361
+ var import_shared_utils = require("@kopexa/shared-utils");
7362
+ var import_react54 = require("react");
7363
+
7364
+ // src/ui/text-button/use-text.ts
7365
+ var import_editor_utils25 = require("@kopexa/editor-utils");
7366
+ var import_icons23 = require("@kopexa/icons");
7367
+ var import_use_is_mobile2 = require("@kopexa/use-is-mobile");
7368
+ var import_state9 = require("@tiptap/pm/state");
7369
+ var import_react53 = require("react");
7370
+ var import_react_hotkeys_hook2 = require("react-hotkeys-hook");
7371
+ var TEXT_SHORTCUT_KEY = "mod+alt+0";
7372
+ function canToggleText(editor, turnInto = true) {
7087
7373
  if (!editor) return false;
7088
- return listTypes.some((type) => canToggleList(editor, type));
7374
+ if (!editor.schema.nodes.paragraph) return false;
7375
+ if (!turnInto) {
7376
+ return editor.can().setNode("paragraph");
7377
+ }
7378
+ if (!(0, import_editor_utils25.selectionWithinConvertibleTypes)(editor, [
7379
+ "paragraph",
7380
+ "heading",
7381
+ "bulletList",
7382
+ "orderedList",
7383
+ "taskList",
7384
+ "blockquote",
7385
+ "codeBlock"
7386
+ ]))
7387
+ return false;
7388
+ return editor.can().setNode("paragraph") || editor.can().clearNodes();
7089
7389
  }
7090
- function isAnyListActive(editor, listTypes) {
7390
+ function isParagraphActive(editor) {
7091
7391
  if (!editor) return false;
7092
- return listTypes.some((type) => isListActive(editor, type));
7093
- }
7094
- function getFilteredListOptions(availableTypes) {
7095
- return listOptions.filter(
7096
- (option) => !option.type || availableTypes.includes(option.type)
7097
- );
7392
+ return editor.isActive("paragraph");
7098
7393
  }
7099
- function shouldShowListDropdown(params) {
7100
- const { editor, hideWhenUnavailable, listInSchema, canToggleAny } = params;
7101
- if (!listInSchema || !editor) {
7394
+ function toggleParagraph(editor) {
7395
+ var _a, _b, _c;
7396
+ if (!editor || !editor.isEditable) return false;
7397
+ if (!canToggleText(editor)) return false;
7398
+ try {
7399
+ const view = editor.view;
7400
+ let state = view.state;
7401
+ let tr = state.tr;
7402
+ const blocks = (0, import_editor_utils25.getSelectedBlockNodes)(editor);
7403
+ const isPossibleToTurnInto = (0, import_editor_utils25.selectionWithinConvertibleTypes)(editor, [
7404
+ "paragraph",
7405
+ "heading",
7406
+ "bulletList",
7407
+ "orderedList",
7408
+ "taskList",
7409
+ "blockquote",
7410
+ "codeBlock"
7411
+ ]) && blocks.length === 1;
7412
+ if ((state.selection.empty || state.selection instanceof import_state9.TextSelection) && isPossibleToTurnInto) {
7413
+ const pos = (_a = (0, import_editor_utils25.findNodePosition)({
7414
+ editor,
7415
+ node: state.selection.$anchor.node(1)
7416
+ })) == null ? void 0 : _a.pos;
7417
+ if (!(0, import_editor_utils25.isValidPosition)(pos)) return false;
7418
+ tr = tr.setSelection(import_state9.NodeSelection.create(state.doc, pos));
7419
+ view.dispatch(tr);
7420
+ state = view.state;
7421
+ }
7422
+ const selection = state.selection;
7423
+ let chain = editor.chain().focus();
7424
+ if (selection instanceof import_state9.NodeSelection) {
7425
+ const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
7426
+ const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
7427
+ const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
7428
+ const to = lastChild ? selection.to - lastChild.nodeSize : selection.to - 1;
7429
+ const resolvedFrom = state.doc.resolve(from);
7430
+ const resolvedTo = state.doc.resolve(to);
7431
+ chain = chain.setTextSelection(import_state9.TextSelection.between(resolvedFrom, resolvedTo)).clearNodes();
7432
+ }
7433
+ if (!editor.isActive("paragraph")) {
7434
+ chain.setNode("paragraph").run();
7435
+ }
7436
+ editor.chain().focus().selectTextblockEnd().run();
7437
+ return true;
7438
+ } catch {
7102
7439
  return false;
7103
7440
  }
7104
- if (hideWhenUnavailable) {
7105
- if ((0, import_react49.isNodeSelection)(editor.state.selection) || !canToggleAny) {
7106
- return false;
7107
- }
7441
+ }
7442
+ function shouldShowButton6(props) {
7443
+ const { editor, hideWhenUnavailable } = props;
7444
+ if (!editor || !editor.isEditable) return false;
7445
+ if (!hideWhenUnavailable) {
7446
+ return true;
7447
+ }
7448
+ if (!(0, import_editor_utils25.isNodeInSchema)("paragraph", editor)) return false;
7449
+ if (!editor.isActive("code")) {
7450
+ return canToggleText(editor);
7108
7451
  }
7109
7452
  return true;
7110
7453
  }
7111
- function useListDropdownState(editor, availableTypes) {
7112
- const [isOpen, setIsOpen] = (0, import_react50.useState)(false);
7113
- const listInSchema = availableTypes.some(
7114
- (type) => (0, import_editor_utils22.isNodeInSchema)(type, editor)
7115
- );
7116
- const filteredLists = (0, import_react50.useMemo)(
7117
- () => getFilteredListOptions(availableTypes),
7118
- [availableTypes]
7119
- );
7120
- const canToggleAny = canToggleAnyList(editor, availableTypes);
7121
- const isAnyActive = isAnyListActive(editor, availableTypes);
7122
- const handleOpenChange = (0, import_react50.useCallback)(
7123
- (open, callback) => {
7124
- setIsOpen(open);
7125
- callback == null ? void 0 : callback(open);
7126
- },
7127
- []
7128
- );
7129
- return {
7130
- isOpen,
7131
- setIsOpen,
7132
- listInSchema,
7133
- filteredLists,
7134
- canToggleAny,
7135
- isAnyActive,
7136
- handleOpenChange
7137
- };
7138
- }
7139
- function useActiveListIcon(editor, filteredLists) {
7140
- return (0, import_react50.useCallback)(() => {
7141
- const activeOption = filteredLists.find(
7142
- (option) => isListActive(editor, option.type)
7143
- );
7144
- return activeOption ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(activeOption.icon, {}) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons22.ListIcon, {});
7145
- }, [editor, filteredLists]);
7146
- }
7147
- function ListDropdownMenu({
7148
- editor: providedEditor,
7149
- types = ["bulletList", "orderedList", "taskList"],
7150
- hideWhenUnavailable = false,
7151
- onOpenChange,
7152
- ...props
7153
- }) {
7154
- const { editor } = (0, import_editor_utils22.useTiptapEditor)(providedEditor);
7454
+ function useText(config) {
7155
7455
  const {
7156
- isOpen,
7157
- listInSchema,
7158
- filteredLists,
7159
- canToggleAny,
7160
- isAnyActive,
7161
- handleOpenChange
7162
- } = useListDropdownState(editor, types);
7163
- const getActiveIcon = useActiveListIcon(editor, filteredLists);
7164
- const show = (0, import_react50.useMemo)(() => {
7165
- return shouldShowListDropdown({
7166
- editor,
7167
- listTypes: types,
7168
- hideWhenUnavailable,
7169
- listInSchema,
7170
- canToggleAny
7171
- });
7172
- }, [editor, types, hideWhenUnavailable, listInSchema, canToggleAny]);
7173
- const handleOnOpenChange = (0, import_react50.useCallback)(
7174
- (open) => handleOpenChange(open, onOpenChange),
7175
- [handleOpenChange, onOpenChange]
7176
- );
7177
- if (!show || !editor || !editor.isEditable) {
7178
- return null;
7179
- }
7180
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_dropdown_menu2.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
7181
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_dropdown_menu2.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7182
- import_button15.Button,
7183
- {
7184
- type: "button",
7185
- variant: "ghost",
7186
- color: "default",
7187
- "data-active-state": isAnyActive ? "on" : "off",
7188
- tabIndex: -1,
7189
- "aria-label": "List options",
7190
- tooltip: "List",
7191
- endContent: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_icons22.ChevronDownIcon, {}),
7192
- ...props,
7193
- children: getActiveIcon()
7194
- }
7195
- ) }),
7196
- /* @__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)(
7197
- ListButton,
7198
- {
7199
- editor,
7200
- type: option.type,
7201
- text: option.label,
7202
- hideWhenUnavailable,
7203
- tooltip: "",
7204
- fullWidth: true,
7205
- spacing: "start"
7206
- }
7207
- ) }, option.type)) }) })
7208
- ] });
7456
+ editor: providedEditor,
7457
+ hideWhenUnavailable = false,
7458
+ onToggled
7459
+ } = config || {};
7460
+ const { editor } = (0, import_editor_utils25.useTiptapEditor)(providedEditor);
7461
+ const isMobile = (0, import_use_is_mobile2.useIsMobile)();
7462
+ const [isVisible, setIsVisible] = (0, import_react53.useState)(true);
7463
+ const canToggle3 = canToggleText(editor);
7464
+ const isActive = isParagraphActive(editor);
7465
+ (0, import_react53.useEffect)(() => {
7466
+ if (!editor) return;
7467
+ const handleSelectionUpdate = () => {
7468
+ setIsVisible(shouldShowButton6({ editor, hideWhenUnavailable }));
7469
+ };
7470
+ handleSelectionUpdate();
7471
+ editor.on("selectionUpdate", handleSelectionUpdate);
7472
+ return () => {
7473
+ editor.off("selectionUpdate", handleSelectionUpdate);
7474
+ };
7475
+ }, [editor, hideWhenUnavailable]);
7476
+ const handleToggle = (0, import_react53.useCallback)(() => {
7477
+ if (!editor) return false;
7478
+ const success = toggleParagraph(editor);
7479
+ if (success) {
7480
+ onToggled == null ? void 0 : onToggled();
7481
+ }
7482
+ return success;
7483
+ }, [editor, onToggled]);
7484
+ (0, import_react_hotkeys_hook2.useHotkeys)(
7485
+ TEXT_SHORTCUT_KEY,
7486
+ (event) => {
7487
+ event.preventDefault();
7488
+ handleToggle();
7489
+ },
7490
+ {
7491
+ enabled: isVisible && canToggle3,
7492
+ enableOnContentEditable: !isMobile,
7493
+ enableOnFormTags: true
7494
+ }
7495
+ );
7496
+ return {
7497
+ isVisible,
7498
+ isActive,
7499
+ handleToggle,
7500
+ canToggle: canToggle3,
7501
+ label: "Text",
7502
+ shortcutKeys: TEXT_SHORTCUT_KEY,
7503
+ Icon: import_icons23.TypeIcon
7504
+ };
7209
7505
  }
7210
7506
 
7211
- // src/ui/table-button/index.tsx
7212
- var import_editor_utils23 = require("@kopexa/editor-utils");
7213
- var import_toolbar8 = require("@kopexa/toolbar");
7214
- var import_react51 = require("react");
7215
- var import_jsx_runtime29 = require("react/jsx-runtime");
7216
- var TableButton = ({
7507
+ // src/ui/text-button/text-button.tsx
7508
+ var import_jsx_runtime30 = require("react/jsx-runtime");
7509
+ function TextShortcutBadge({
7510
+ shortcutKeys = TEXT_SHORTCUT_KEY
7511
+ }) {
7512
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_chip.Chip, { children: (0, import_shared_utils.parseShortcutKeys)({ shortcutKeys }) });
7513
+ }
7514
+ var TextButton = ({
7217
7515
  editor: providedEditor,
7218
7516
  text,
7219
7517
  hideWhenUnavailable = false,
7220
7518
  onToggled,
7519
+ showShortcut = false,
7221
7520
  onClick,
7222
7521
  children,
7522
+ ref,
7223
7523
  ...buttonProps
7224
7524
  }) => {
7225
- const { editor } = (0, import_editor_utils23.useTiptapEditor)(providedEditor);
7525
+ const { editor } = (0, import_editor_utils26.useTiptapEditor)(providedEditor);
7226
7526
  const {
7227
7527
  isVisible,
7228
7528
  canToggle: canToggle3,
7229
7529
  isActive,
7230
7530
  handleToggle,
7231
7531
  label,
7232
- // shortcutKeys,
7532
+ shortcutKeys,
7233
7533
  Icon
7234
- } = useTableBlock({
7534
+ } = useText({
7235
7535
  editor,
7236
7536
  hideWhenUnavailable,
7237
7537
  onToggled
7238
7538
  });
7239
- const handleClick = (0, import_react51.useCallback)(
7539
+ const handleClick = (0, import_react54.useCallback)(
7240
7540
  (event) => {
7241
7541
  onClick == null ? void 0 : onClick(event);
7242
7542
  if (event.defaultPrevented) return;
@@ -7247,198 +7547,343 @@ var TableButton = ({
7247
7547
  if (!isVisible) {
7248
7548
  return null;
7249
7549
  }
7250
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7251
- import_toolbar8.ToolbarButton,
7550
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7551
+ import_button16.Button,
7252
7552
  {
7253
7553
  type: "button",
7254
7554
  variant: "ghost",
7255
7555
  color: "default",
7256
7556
  "data-active-state": isActive ? "on" : "off",
7557
+ tabIndex: -1,
7257
7558
  disabled: !canToggle3,
7258
7559
  "data-disabled": !canToggle3,
7259
- tabIndex: -1,
7260
7560
  "aria-label": label,
7261
7561
  "aria-pressed": isActive,
7262
- title: label,
7562
+ tooltip: "Text",
7563
+ shortcutKeys,
7263
7564
  onClick: handleClick,
7264
- isIconOnly: !text && !children,
7565
+ startContent: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon, {}),
7265
7566
  ...buttonProps,
7266
- children: children || /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
7267
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon, {}),
7268
- text && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: text })
7567
+ ref,
7568
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
7569
+ text,
7570
+ showShortcut && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TextShortcutBadge, { shortcutKeys })
7269
7571
  ] })
7270
7572
  }
7271
7573
  );
7272
7574
  };
7273
7575
 
7274
- // src/ui/text-align-button/text-align-button.tsx
7275
- var import_button16 = require("@kopexa/button");
7276
- var import_editor_utils25 = require("@kopexa/editor-utils");
7277
- var import_react53 = require("react");
7278
-
7279
- // src/ui/text-align-button/use-text-align.ts
7280
- var import_editor_utils24 = require("@kopexa/editor-utils");
7281
- var import_icons23 = require("@kopexa/icons");
7282
- var import_react52 = require("react");
7283
- var TEXT_ALIGN_SHORTCUT_KEYS = {
7284
- left: "mod+shift+l",
7285
- center: "mod+shift+e",
7286
- right: "mod+shift+r",
7287
- justify: "mod+shift+j"
7288
- };
7289
- var textAlignIcons = {
7290
- left: import_icons23.AlignLeftIcon,
7291
- center: import_icons23.AlignCenterIcon,
7292
- right: import_icons23.AlignRightIcon,
7293
- justify: import_icons23.AlignJustifyIcon
7294
- };
7295
- var textAlignLabels = {
7296
- left: "Align left",
7297
- center: "Align center",
7298
- right: "Align right",
7299
- justify: "Align justify"
7300
- };
7301
- function canSetTextAlign(editor, align) {
7576
+ // src/ui/turn-into-dropdown/use-turn-into-dropdown.ts
7577
+ var import_editor_utils27 = require("@kopexa/editor-utils");
7578
+ var import_icons24 = require("@kopexa/icons");
7579
+ var import_state10 = require("@tiptap/pm/state");
7580
+ var import_react55 = require("react");
7581
+ var TURN_INTO_BLOCKS = [
7582
+ "paragraph",
7583
+ "heading",
7584
+ "bulletList",
7585
+ "orderedList",
7586
+ "taskList",
7587
+ "blockquote",
7588
+ "codeBlock"
7589
+ ];
7590
+ var blockTypeOptions = [
7591
+ {
7592
+ type: "paragraph",
7593
+ label: "Text",
7594
+ isActive: (editor) => editor.isActive("paragraph") && !editor.isActive("heading") && !editor.isActive("bulletList") && !editor.isActive("orderedList") && !editor.isActive("taskList") && !editor.isActive("blockquote") && !editor.isActive("codeBlock")
7595
+ },
7596
+ {
7597
+ type: "heading",
7598
+ label: "Heading 1",
7599
+ level: 1,
7600
+ isActive: (editor) => editor.isActive("heading", { level: 1 })
7601
+ },
7602
+ {
7603
+ type: "heading",
7604
+ label: "Heading 2",
7605
+ level: 2,
7606
+ isActive: (editor) => editor.isActive("heading", { level: 2 })
7607
+ },
7608
+ {
7609
+ type: "heading",
7610
+ label: "Heading 3",
7611
+ level: 3,
7612
+ isActive: (editor) => editor.isActive("heading", { level: 3 })
7613
+ },
7614
+ {
7615
+ type: "heading",
7616
+ label: "Heading 4",
7617
+ level: 4,
7618
+ isActive: (editor) => editor.isActive("heading", { level: 4 })
7619
+ },
7620
+ {
7621
+ type: "bulletList",
7622
+ label: "Bulleted list",
7623
+ isActive: (editor) => editor.isActive("bulletList")
7624
+ },
7625
+ {
7626
+ type: "orderedList",
7627
+ label: "Numbered list",
7628
+ isActive: (editor) => editor.isActive("orderedList")
7629
+ },
7630
+ {
7631
+ type: "taskList",
7632
+ label: "To-do list",
7633
+ isActive: (editor) => editor.isActive("taskList")
7634
+ },
7635
+ {
7636
+ type: "blockquote",
7637
+ label: "Blockquote",
7638
+ isActive: (editor) => editor.isActive("blockquote")
7639
+ },
7640
+ {
7641
+ type: "codeBlock",
7642
+ label: "Code block",
7643
+ isActive: (editor) => editor.isActive("codeBlock")
7644
+ }
7645
+ ];
7646
+ function canTurnInto(editor, allowedBlockTypes) {
7302
7647
  if (!editor || !editor.isEditable) return false;
7303
- if (!(0, import_editor_utils24.isExtensionAvailable)(editor, "textAlign") || (0, import_editor_utils24.isNodeTypeSelected)(editor, ["image"]))
7304
- return false;
7305
- return editor.can().setTextAlign(align);
7306
- }
7307
- function hasSetTextAlign(commands) {
7308
- return "setTextAlign" in commands;
7648
+ const blockTypes = allowedBlockTypes || TURN_INTO_BLOCKS;
7649
+ const { selection } = editor.state;
7650
+ if (selection instanceof import_state10.NodeSelection) {
7651
+ const nodeType2 = selection.node.type.name;
7652
+ return blockTypes.includes(nodeType2);
7653
+ }
7654
+ const { $anchor } = selection;
7655
+ const nodeType = $anchor.parent.type.name;
7656
+ return blockTypes.includes(nodeType);
7309
7657
  }
7310
- function isTextAlignActive(editor, align) {
7311
- if (!editor || !editor.isEditable) return false;
7312
- return editor.isActive({ textAlign: align });
7658
+ function getFilteredBlockTypeOptions(blockTypes) {
7659
+ if (!blockTypes) return blockTypeOptions;
7660
+ return blockTypeOptions.filter((option) => {
7661
+ return blockTypes.includes(option.type);
7662
+ });
7313
7663
  }
7314
- function setTextAlign(editor, align) {
7315
- if (!editor || !editor.isEditable) return false;
7316
- if (!canSetTextAlign(editor, align)) return false;
7317
- const chain = editor.chain().focus();
7318
- if (hasSetTextAlign(chain)) {
7319
- return chain.setTextAlign(align).run();
7320
- }
7321
- return false;
7664
+ function getActiveBlockType(editor, blockTypes) {
7665
+ if (!editor) return getFilteredBlockTypeOptions(blockTypes)[0];
7666
+ const filteredOptions = getFilteredBlockTypeOptions(blockTypes);
7667
+ const activeOption = filteredOptions.find(
7668
+ (option) => option.isActive(editor)
7669
+ );
7670
+ return activeOption || filteredOptions[0];
7322
7671
  }
7323
- function shouldShowButton5(props) {
7324
- const { editor, hideWhenUnavailable, align } = props;
7672
+ function shouldShowTurnInto(params) {
7673
+ const { editor, hideWhenUnavailable, blockTypes } = params;
7325
7674
  if (!editor || !editor.isEditable) return false;
7326
- if (!(0, import_editor_utils24.isExtensionAvailable)(editor, "textAlign")) return false;
7327
7675
  if (hideWhenUnavailable && !editor.isActive("code")) {
7328
- return canSetTextAlign(editor, align);
7676
+ return canTurnInto(editor, blockTypes);
7329
7677
  }
7330
7678
  return true;
7331
7679
  }
7332
- function useTextAlign(config) {
7680
+ function useTurnIntoDropdown(config) {
7333
7681
  const {
7334
7682
  editor: providedEditor,
7335
- align,
7336
7683
  hideWhenUnavailable = false,
7337
- onAligned
7338
- } = config;
7339
- const { editor } = (0, import_editor_utils24.useTiptapEditor)(providedEditor);
7340
- const [isVisible, setIsVisible] = (0, import_react52.useState)(true);
7341
- const canAlign = canSetTextAlign(editor, align);
7342
- const isActive = isTextAlignActive(editor, align);
7343
- (0, import_react52.useEffect)(() => {
7684
+ blockTypes,
7685
+ onOpenChange
7686
+ } = config || {};
7687
+ const { editor } = (0, import_editor_utils27.useTiptapEditor)(providedEditor);
7688
+ const [isOpen, setIsOpen] = (0, import_react55.useState)(false);
7689
+ const [isVisible, setIsVisible] = (0, import_react55.useState)(true);
7690
+ const canToggle3 = canTurnInto(editor, blockTypes);
7691
+ const activeBlockType = getActiveBlockType(editor, blockTypes);
7692
+ const handleOpenChange = (0, import_react55.useCallback)(
7693
+ (open) => {
7694
+ if (!editor || !canToggle3) return;
7695
+ setIsOpen(open);
7696
+ onOpenChange == null ? void 0 : onOpenChange(open);
7697
+ },
7698
+ [canToggle3, editor, onOpenChange]
7699
+ );
7700
+ (0, import_react55.useEffect)(() => {
7344
7701
  if (!editor) return;
7345
7702
  const handleSelectionUpdate = () => {
7346
- setIsVisible(shouldShowButton5({ editor, align, hideWhenUnavailable }));
7703
+ setIsVisible(
7704
+ shouldShowTurnInto({
7705
+ editor,
7706
+ hideWhenUnavailable,
7707
+ blockTypes
7708
+ })
7709
+ );
7347
7710
  };
7348
7711
  handleSelectionUpdate();
7349
7712
  editor.on("selectionUpdate", handleSelectionUpdate);
7350
7713
  return () => {
7351
7714
  editor.off("selectionUpdate", handleSelectionUpdate);
7352
7715
  };
7353
- }, [editor, hideWhenUnavailable, align]);
7354
- const handleTextAlign = (0, import_react52.useCallback)(() => {
7355
- if (!editor) return false;
7356
- const success = setTextAlign(editor, align);
7357
- if (success) {
7358
- onAligned == null ? void 0 : onAligned();
7359
- }
7360
- return success;
7361
- }, [editor, align, onAligned]);
7716
+ }, [editor, hideWhenUnavailable, blockTypes]);
7362
7717
  return {
7363
7718
  isVisible,
7364
- isActive,
7365
- handleTextAlign,
7366
- canAlign,
7367
- label: textAlignLabels[align],
7368
- shortcutKeys: TEXT_ALIGN_SHORTCUT_KEYS[align],
7369
- Icon: textAlignIcons[align]
7719
+ canToggle: canToggle3,
7720
+ isOpen,
7721
+ setIsOpen,
7722
+ activeBlockType,
7723
+ handleOpenChange,
7724
+ filteredOptions: getFilteredBlockTypeOptions(blockTypes),
7725
+ label: `Turn into (current: ${(activeBlockType == null ? void 0 : activeBlockType.label) || "Text"})`,
7726
+ Icon: import_icons24.ChevronDownIcon
7370
7727
  };
7371
7728
  }
7372
7729
 
7373
- // src/ui/text-align-button/text-align-button.tsx
7374
- var import_jsx_runtime30 = require("react/jsx-runtime");
7375
- var TextAlignButton = ({
7376
- editor: providedEditor,
7377
- align,
7378
- text,
7379
- hideWhenUnavailable = false,
7380
- onAligned,
7381
- showShortcut = false,
7382
- onClick,
7383
- children,
7384
- ...buttonProps
7385
- }) => {
7386
- const { editor } = (0, import_editor_utils25.useTiptapEditor)(providedEditor);
7387
- const {
7388
- isVisible,
7389
- handleTextAlign,
7390
- label,
7391
- canAlign,
7392
- isActive,
7393
- Icon,
7394
- shortcutKeys
7395
- } = useTextAlign({
7396
- editor,
7397
- align,
7398
- hideWhenUnavailable,
7399
- onAligned
7400
- });
7401
- const handleClick = (0, import_react53.useCallback)(
7402
- (e) => {
7403
- onClick == null ? void 0 : onClick(e);
7404
- if (e.defaultPrevented) return;
7405
- handleTextAlign();
7406
- },
7407
- [handleTextAlign, onClick]
7408
- );
7409
- if (!isVisible) {
7410
- return null;
7411
- }
7412
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7413
- import_button16.IconButton,
7414
- {
7415
- type: "button",
7416
- disabled: canAlign,
7417
- variant: "ghost",
7418
- color: "default",
7419
- "data-active-state": isActive ? "on" : "off",
7420
- "data-disabled": canAlign,
7421
- tabIndex: -1,
7422
- "aria-label": label,
7423
- "aria-pressed": isActive,
7424
- tooltip: label,
7425
- shortcutKeys,
7426
- onClick: handleClick,
7427
- ...buttonProps,
7428
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon, {})
7730
+ // src/ui/turn-into-dropdown/turn-into-dropdown.tsx
7731
+ var import_jsx_runtime31 = require("react/jsx-runtime");
7732
+ var TurnIntoDropdownContent = ({ blockTypes }) => {
7733
+ const filteredOptions = getFilteredBlockTypeOptions(blockTypes);
7734
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Group, { children: filteredOptions.map(
7735
+ (option, index) => {
7736
+ var _a;
7737
+ return renderBlockTypeButton(
7738
+ option,
7739
+ `${option.type}-${(_a = option.level) != null ? _a : index}`
7740
+ );
7429
7741
  }
7430
- );
7742
+ ) });
7431
7743
  };
7744
+ function renderBlockTypeButton(option, key) {
7745
+ switch (option.type) {
7746
+ case "paragraph":
7747
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7748
+ TextButton,
7749
+ {
7750
+ fullWidth: true,
7751
+ spacing: "start",
7752
+ tooltip: "",
7753
+ text: option.label
7754
+ }
7755
+ ) }, key);
7756
+ case "heading":
7757
+ if (!option.level) {
7758
+ return null;
7759
+ }
7760
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7761
+ HeadingButton,
7762
+ {
7763
+ level: option.level || 1,
7764
+ fullWidth: true,
7765
+ spacing: "start",
7766
+ tooltip: "",
7767
+ text: option.label
7768
+ }
7769
+ ) }, key);
7770
+ case "bulletList":
7771
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7772
+ ListButton,
7773
+ {
7774
+ type: "bulletList",
7775
+ fullWidth: true,
7776
+ spacing: "start",
7777
+ tooltip: "",
7778
+ text: option.label
7779
+ }
7780
+ ) }, key);
7781
+ case "orderedList":
7782
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7783
+ ListButton,
7784
+ {
7785
+ type: "orderedList",
7786
+ fullWidth: true,
7787
+ spacing: "start",
7788
+ tooltip: "",
7789
+ text: option.label
7790
+ }
7791
+ ) }, key);
7792
+ case "taskList":
7793
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7794
+ ListButton,
7795
+ {
7796
+ type: "taskList",
7797
+ fullWidth: true,
7798
+ spacing: "start",
7799
+ tooltip: "",
7800
+ text: option.label
7801
+ }
7802
+ ) }, key);
7803
+ case "blockquote":
7804
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7805
+ BlockquoteButton,
7806
+ {
7807
+ className: "w-full justify-start",
7808
+ title: "",
7809
+ tooltip: "",
7810
+ text: option.label
7811
+ }
7812
+ ) }, key);
7813
+ case "codeBlock":
7814
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7815
+ CodeBlockButton,
7816
+ {
7817
+ className: "w-full justify-start",
7818
+ title: "",
7819
+ tooltip: "",
7820
+ text: option.label
7821
+ }
7822
+ ) }, key);
7823
+ default:
7824
+ return null;
7825
+ }
7826
+ }
7827
+ var TurnIntoDropdown = (0, import_react56.forwardRef)(
7828
+ ({
7829
+ editor: providedEditor,
7830
+ hideWhenUnavailable = false,
7831
+ blockTypes,
7832
+ onOpenChange,
7833
+ children,
7834
+ ...buttonProps
7835
+ }, ref) => {
7836
+ const { editor } = (0, import_editor_utils28.useTiptapEditor)(providedEditor);
7837
+ const {
7838
+ isVisible,
7839
+ canToggle: canToggle3,
7840
+ isOpen,
7841
+ activeBlockType,
7842
+ handleOpenChange,
7843
+ label,
7844
+ Icon
7845
+ } = useTurnIntoDropdown({
7846
+ editor,
7847
+ hideWhenUnavailable,
7848
+ blockTypes,
7849
+ onOpenChange
7850
+ });
7851
+ if (!isVisible) {
7852
+ return null;
7853
+ }
7854
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_dropdown_menu2.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOpenChange, children: [
7855
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7856
+ import_button17.Button,
7857
+ {
7858
+ type: "button",
7859
+ variant: "ghost",
7860
+ color: "default",
7861
+ disabled: !canToggle3,
7862
+ "data-disabled": !canToggle3,
7863
+ tabIndex: -1,
7864
+ "aria-label": label,
7865
+ tooltip: "Turn into",
7866
+ endContent: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Icon, {}),
7867
+ ...buttonProps,
7868
+ ref,
7869
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { children: (activeBlockType == null ? void 0 : activeBlockType.label) || "Text" })
7870
+ }
7871
+ ) }),
7872
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_dropdown_menu2.DropdownMenu.Content, { align: "start", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TurnIntoDropdownContent, { blockTypes }) })
7873
+ ] });
7874
+ }
7875
+ );
7876
+ TurnIntoDropdown.displayName = "TurnIntoDropdown";
7432
7877
 
7433
7878
  // src/ui/undo-redo-button/undo-redo-button.tsx
7434
- var import_editor_utils27 = require("@kopexa/editor-utils");
7879
+ var import_editor_utils30 = require("@kopexa/editor-utils");
7435
7880
  var import_toolbar9 = require("@kopexa/toolbar");
7436
- var import_react55 = require("react");
7881
+ var import_react58 = require("react");
7437
7882
 
7438
7883
  // src/ui/undo-redo-button/use-undo-redo.ts
7439
- var import_editor_utils26 = require("@kopexa/editor-utils");
7440
- var import_icons24 = require("@kopexa/icons");
7441
- var import_react54 = require("react");
7884
+ var import_editor_utils29 = require("@kopexa/editor-utils");
7885
+ var import_icons25 = require("@kopexa/icons");
7886
+ var import_react57 = require("react");
7442
7887
  var UNDO_REDO_SHORTCUT_KEYS = {
7443
7888
  undo: "mod+z",
7444
7889
  redo: "mod+shift+z"
@@ -7448,12 +7893,12 @@ var historyActionLabels = {
7448
7893
  redo: "Redo"
7449
7894
  };
7450
7895
  var historyIcons = {
7451
- undo: import_icons24.UndoIcon,
7452
- redo: import_icons24.RedoIcon
7896
+ undo: import_icons25.UndoIcon,
7897
+ redo: import_icons25.RedoIcon
7453
7898
  };
7454
7899
  function canExecuteUndoRedoAction(editor, action) {
7455
7900
  if (!editor || !editor.isEditable) return false;
7456
- if ((0, import_editor_utils26.isNodeTypeSelected)(editor, ["image"])) return false;
7901
+ if ((0, import_editor_utils29.isNodeTypeSelected)(editor, ["image"])) return false;
7457
7902
  return action === "undo" ? editor.can().undo() : editor.can().redo();
7458
7903
  }
7459
7904
  function executeUndoRedoAction(editor, action) {
@@ -7462,7 +7907,7 @@ function executeUndoRedoAction(editor, action) {
7462
7907
  const chain = editor.chain().focus();
7463
7908
  return action === "undo" ? chain.undo().run() : chain.redo().run();
7464
7909
  }
7465
- function shouldShowButton6(props) {
7910
+ function shouldShowButton7(props) {
7466
7911
  const { editor, hideWhenUnavailable, action } = props;
7467
7912
  if (!editor || !editor.isEditable) return false;
7468
7913
  if (hideWhenUnavailable && !editor.isActive("code")) {
@@ -7477,13 +7922,13 @@ function useUndoRedo(config) {
7477
7922
  hideWhenUnavailable = false,
7478
7923
  onExecuted
7479
7924
  } = config;
7480
- const { editor } = (0, import_editor_utils26.useTiptapEditor)(providedEditor);
7481
- const [isVisible, setIsVisible] = (0, import_react54.useState)(true);
7925
+ const { editor } = (0, import_editor_utils29.useTiptapEditor)(providedEditor);
7926
+ const [isVisible, setIsVisible] = (0, import_react57.useState)(true);
7482
7927
  const canExecute = canExecuteUndoRedoAction(editor, action);
7483
- (0, import_react54.useEffect)(() => {
7928
+ (0, import_react57.useEffect)(() => {
7484
7929
  if (!editor) return;
7485
7930
  const handleUpdate = () => {
7486
- setIsVisible(shouldShowButton6({ editor, hideWhenUnavailable, action }));
7931
+ setIsVisible(shouldShowButton7({ editor, hideWhenUnavailable, action }));
7487
7932
  };
7488
7933
  handleUpdate();
7489
7934
  editor.on("transaction", handleUpdate);
@@ -7491,7 +7936,7 @@ function useUndoRedo(config) {
7491
7936
  editor.off("transaction", handleUpdate);
7492
7937
  };
7493
7938
  }, [editor, hideWhenUnavailable, action]);
7494
- const handleAction = (0, import_react54.useCallback)(() => {
7939
+ const handleAction = (0, import_react57.useCallback)(() => {
7495
7940
  if (!editor) return false;
7496
7941
  const success = executeUndoRedoAction(editor, action);
7497
7942
  if (success) {
@@ -7510,7 +7955,7 @@ function useUndoRedo(config) {
7510
7955
  }
7511
7956
 
7512
7957
  // src/ui/undo-redo-button/undo-redo-button.tsx
7513
- var import_jsx_runtime31 = require("react/jsx-runtime");
7958
+ var import_jsx_runtime32 = require("react/jsx-runtime");
7514
7959
  var UndoRedoButton = ({
7515
7960
  editor: providedEditor,
7516
7961
  action,
@@ -7522,14 +7967,14 @@ var UndoRedoButton = ({
7522
7967
  children,
7523
7968
  ...buttonProps
7524
7969
  }) => {
7525
- const { editor } = (0, import_editor_utils27.useTiptapEditor)(providedEditor);
7970
+ const { editor } = (0, import_editor_utils30.useTiptapEditor)(providedEditor);
7526
7971
  const { isVisible, handleAction, label, canExecute, Icon, shortcutKeys } = useUndoRedo({
7527
7972
  editor,
7528
7973
  action,
7529
7974
  hideWhenUnavailable,
7530
7975
  onExecuted
7531
7976
  });
7532
- const handleClick = (0, import_react55.useCallback)(
7977
+ const handleClick = (0, import_react58.useCallback)(
7533
7978
  (event) => {
7534
7979
  onClick == null ? void 0 : onClick(event);
7535
7980
  if (event.defaultPrevented) return;
@@ -7540,7 +7985,7 @@ var UndoRedoButton = ({
7540
7985
  if (!isVisible) {
7541
7986
  return null;
7542
7987
  }
7543
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7988
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7544
7989
  import_toolbar9.ToolbarButton,
7545
7990
  {
7546
7991
  type: "button",
@@ -7555,23 +8000,23 @@ var UndoRedoButton = ({
7555
8000
  onClick: handleClick,
7556
8001
  isIconOnly: true,
7557
8002
  ...buttonProps,
7558
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Icon, {})
8003
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, {})
7559
8004
  }
7560
8005
  );
7561
8006
  };
7562
8007
 
7563
8008
  // src/presets/basic/editor-header.tsx
7564
- var import_jsx_runtime32 = require("react/jsx-runtime");
8009
+ var import_jsx_runtime33 = require("react/jsx-runtime");
7565
8010
  var EditorHeader = ({
7566
8011
  editor: providedEditor,
7567
8012
  variant
7568
8013
  }) => {
7569
8014
  var _a, _b;
7570
- const { editor } = (0, import_editor_utils28.useTiptapEditor)(providedEditor);
7571
- const isMobile = (0, import_use_is_mobile2.useIsMobile)();
8015
+ const { editor } = (0, import_editor_utils31.useTiptapEditor)(providedEditor);
8016
+ const isMobile = (0, import_use_is_mobile3.useIsMobile)();
7572
8017
  const windowSize = useWindowSize();
7573
8018
  const { styles } = useEditorUIContext();
7574
- const toolbarRef = (0, import_react56.useRef)(null);
8019
+ const toolbarRef = (0, import_react59.useRef)(null);
7575
8020
  const bodyRect = useCursorVisibility({
7576
8021
  editor,
7577
8022
  overlayHeight: (_b = (_a = toolbarRef.current) == null ? void 0 : _a.getBoundingClientRect().height) != null ? _b : 0
@@ -7580,7 +8025,7 @@ var EditorHeader = ({
7580
8025
  return null;
7581
8026
  }
7582
8027
  const ToolbarContent = variant === "comment" ? CommentToolbarContent : variant === "field" ? FieldToolbarContent : MainToolbarContent;
7583
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: styles.toolbarContainer(), "data-slot": "editor-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
8028
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: styles.toolbarContainer(), "data-slot": "editor-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7584
8029
  import_toolbar10.Toolbar,
7585
8030
  {
7586
8031
  sticky: true,
@@ -7590,63 +8035,58 @@ var EditorHeader = ({
7590
8035
  bottom: `calc(100% - ${windowSize.height - bodyRect.y}px)`
7591
8036
  } : {},
7592
8037
  className: styles.toolbar(),
7593
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ToolbarContent, {})
8038
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ToolbarContent, {})
7594
8039
  }
7595
8040
  ) });
7596
8041
  };
7597
- var MainToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
7598
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7599
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(UndoRedoButton, { action: "undo" }),
7600
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(UndoRedoButton, { action: "redo" })
8042
+ var MainToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
8043
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8044
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(UndoRedoButton, { action: "undo" }),
8045
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(UndoRedoButton, { action: "redo" })
7601
8046
  ] }),
7602
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7603
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7604
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(HeadingDropdownMenu, { levels: [1, 2, 3, 4] }),
7605
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ListDropdownMenu, { types: ["bulletList", "orderedList", "taskList"] }),
7606
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(BlockquoteButton, {}),
7607
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CodeBlockButton, {})
8047
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8048
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TurnIntoDropdown, {}) }),
8049
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8050
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8051
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "bold" }),
8052
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "italic" }),
8053
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "strike" }),
8054
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "code" }),
8055
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "underline" }),
8056
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ColorHighlightPopover, {}),
8057
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LinkPopover, {})
7608
8058
  ] }),
7609
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7610
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7611
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "bold" }),
7612
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "italic" }),
7613
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "strike" }),
7614
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "code" }),
7615
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "underline" }),
7616
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ColorHighlightPopover, {}),
7617
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LinkPopover, {})
7618
- ] }),
7619
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7620
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TableButton, {}) }),
7621
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MoreOptions, { hideWhenUnavailable: true })
8059
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8060
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TableButton, {}) }),
8061
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MoreOptions, { hideWhenUnavailable: true })
7622
8062
  ] });
7623
- var CommentToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
7624
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7625
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "bold" }),
7626
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "italic" }),
7627
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "strike" }),
7628
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "code" })
8063
+ var CommentToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
8064
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8065
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "bold" }),
8066
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "italic" }),
8067
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "strike" }),
8068
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "code" })
7629
8069
  ] }),
7630
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7631
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7632
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LinkPopover, {}),
7633
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ListDropdownMenu, { types: ["bulletList", "orderedList"] })
8070
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8071
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8072
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LinkPopover, {}),
8073
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ListDropdownMenu, { types: ["bulletList", "orderedList"] })
7634
8074
  ] })
7635
8075
  ] });
7636
- var FieldToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7637
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "bold" }),
7638
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "italic" }),
7639
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "strike" }),
7640
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LinkPopover, {})
8076
+ var FieldToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8077
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "bold" }),
8078
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "italic" }),
8079
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "strike" }),
8080
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LinkPopover, {})
7641
8081
  ] });
7642
8082
  function MoreOptions({
7643
8083
  editor: providedEditor,
7644
8084
  hideWhenUnavailable = false,
7645
8085
  ...props
7646
8086
  }) {
7647
- const { editor } = (0, import_editor_utils28.useTiptapEditor)(providedEditor);
7648
- const [show, setShow] = (0, import_react56.useState)(false);
7649
- (0, import_react56.useEffect)(() => {
8087
+ const { editor } = (0, import_editor_utils31.useTiptapEditor)(providedEditor);
8088
+ const [show, setShow] = (0, import_react59.useState)(false);
8089
+ (0, import_react59.useEffect)(() => {
7650
8090
  if (!editor) return;
7651
8091
  const handleSelectionUpdate = () => {
7652
8092
  setShow(
@@ -7665,13 +8105,13 @@ function MoreOptions({
7665
8105
  if (!show || !editor || !editor.isEditable) {
7666
8106
  return null;
7667
8107
  }
7668
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
7669
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7670
- /* @__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: [
7671
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
8108
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
8109
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8110
+ /* @__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: [
8111
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7672
8112
  import_popover3.Popover.Trigger,
7673
8113
  {
7674
- render: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
8114
+ render: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7675
8115
  import_toolbar10.ToolbarButton,
7676
8116
  {
7677
8117
  type: "button",
@@ -7683,29 +8123,29 @@ function MoreOptions({
7683
8123
  title: "More options",
7684
8124
  isIconOnly: true,
7685
8125
  ...props,
7686
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_icons25.MoreVerticalIcon, {})
8126
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_icons26.MoreVerticalIcon, {})
7687
8127
  }
7688
8128
  )
7689
8129
  }
7690
8130
  ),
7691
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
8131
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7692
8132
  import_popover3.Popover.Content,
7693
8133
  {
7694
8134
  side: "top",
7695
8135
  align: "end",
7696
8136
  alignOffset: 4,
7697
8137
  sideOffset: 4,
7698
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.Toolbar, { children: [
7699
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7700
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "superscript" }),
7701
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MarkButton, { type: "subscript" })
8138
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.Toolbar, { children: [
8139
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8140
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "superscript" }),
8141
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MarkButton, { type: "subscript" })
7702
8142
  ] }),
7703
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_toolbar10.ToolbarSeparator, {}),
7704
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_toolbar10.ToolbarGroup, { children: [
7705
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextAlignButton, { align: "left" }),
7706
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextAlignButton, { align: "center" }),
7707
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextAlignButton, { align: "right" }),
7708
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextAlignButton, { align: "justify" })
8143
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_toolbar10.ToolbarSeparator, {}),
8144
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_toolbar10.ToolbarGroup, { children: [
8145
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TextAlignButton, { align: "left" }),
8146
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TextAlignButton, { align: "center" }),
8147
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TextAlignButton, { align: "right" }),
8148
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TextAlignButton, { align: "justify" })
7709
8149
  ] })
7710
8150
  ] })
7711
8151
  }
@@ -7737,7 +8177,7 @@ function shouldShowMoreOptions(params) {
7737
8177
  }
7738
8178
 
7739
8179
  // src/presets/basic/index.tsx
7740
- var import_jsx_runtime33 = require("react/jsx-runtime");
8180
+ var import_jsx_runtime34 = require("react/jsx-runtime");
7741
8181
  var BasicEditor = ({
7742
8182
  variant,
7743
8183
  bordered,
@@ -7755,19 +8195,19 @@ var BasicEditor = ({
7755
8195
  ...options
7756
8196
  });
7757
8197
  const styles = (0, import_theme9.editorBasic)({ variant, bordered });
7758
- const resolveVariable = (0, import_react58.useCallback)(
8198
+ const resolveVariable = (0, import_react61.useCallback)(
7759
8199
  (name) => variableValues == null ? void 0 : variableValues[name],
7760
8200
  [variableValues]
7761
8201
  );
7762
8202
  if (!editor) {
7763
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LoadingSpinner, {});
8203
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(LoadingSpinner, {});
7764
8204
  }
7765
8205
  const isBottomToolbar = variant === "field";
7766
8206
  const hasVariables = variables && variables.length > 0;
7767
8207
  const hasPagination = !!pagesOptions;
7768
- 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_react57.EditorContext.Provider, { value: { editor }, children: [
7769
- showToolbar && !isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(EditorHeader, { editor, variant }),
7770
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
8208
+ 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: [
8209
+ showToolbar && !isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(EditorHeader, { editor, variant }),
8210
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7771
8211
  EditorContentArea,
7772
8212
  {
7773
8213
  variant,
@@ -7775,10 +8215,10 @@ var BasicEditor = ({
7775
8215
  hasPagination
7776
8216
  }
7777
8217
  ),
7778
- showToolbar && isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(EditorHeader, { editor, variant })
8218
+ showToolbar && isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(EditorHeader, { editor, variant })
7779
8219
  ] }) }) });
7780
8220
  if (hasVariables) {
7781
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VariableProvider, { variables, resolveVariable, children: editorContent });
8221
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(VariableProvider, { variables, resolveVariable, children: editorContent });
7782
8222
  }
7783
8223
  return editorContent;
7784
8224
  };
@@ -7788,10 +8228,10 @@ var EditorContentArea = ({
7788
8228
  hasPagination
7789
8229
  }) => {
7790
8230
  const styles = (0, import_theme9.editorBasic)({ variant });
7791
- const { editor } = (0, import_react58.useContext)(import_react57.EditorContext);
8231
+ const { editor } = (0, import_react61.useContext)(import_react60.EditorContext);
7792
8232
  const { isDragging } = useUiEditorState(editor);
7793
8233
  useScrollToHash();
7794
- const handleKeyDown = (0, import_react58.useCallback)(
8234
+ const handleKeyDown = (0, import_react61.useCallback)(
7795
8235
  (e) => {
7796
8236
  if (!(editor == null ? void 0 : editor.isFocused)) return;
7797
8237
  const isMod = e.metaKey || e.ctrlKey;
@@ -7833,9 +8273,9 @@ var EditorContentArea = ({
7833
8273
  const contentClassName = hasPagination ? "w-full min-w-0 h-auto min-h-0" : styles.content();
7834
8274
  return (
7835
8275
  // biome-ignore lint/a11y/noStaticElementInteractions: Wrapper intercepts keyboard shortcuts to prevent propagation
7836
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: styles.wrapper(), onKeyDown: handleKeyDown, children: [
7837
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7838
- import_react57.EditorContent,
8276
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: styles.wrapper(), onKeyDown: handleKeyDown, children: [
8277
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
8278
+ import_react60.EditorContent,
7839
8279
  {
7840
8280
  editor,
7841
8281
  role: "presentation",
@@ -7844,20 +8284,20 @@ var EditorContentArea = ({
7844
8284
  cursor: isDragging ? "grabbing" : "auto"
7845
8285
  },
7846
8286
  children: [
7847
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SlashDropdownMenu, {}),
7848
- isEditable && variables && variables.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VariableSuggestion, { editor, variables })
8287
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SlashDropdownMenu, {}),
8288
+ isEditable && variables && variables.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(VariableSuggestion, { editor, variables })
7849
8289
  ]
7850
8290
  }
7851
8291
  ),
7852
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(BubbleMenu, { editor }),
7853
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LinkBubble, { editor }),
7854
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
7855
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_extension_table2.TableHandle, { editor }),
7856
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
8292
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(BubbleMenu, { editor }),
8293
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(LinkBubble, { editor }),
8294
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
8295
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_extension_table2.TableHandle, { editor }),
8296
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7857
8297
  import_extension_table2.TableSelectionOverlay,
7858
8298
  {
7859
8299
  showResizeHandles: true,
7860
- cellMenu: (props) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
8300
+ cellMenu: (props) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7861
8301
  import_extension_table2.TableCellHandleMenu,
7862
8302
  {
7863
8303
  editor: props.editor,
@@ -7872,8 +8312,8 @@ var EditorContentArea = ({
7872
8312
  };
7873
8313
  function LoadingSpinner({ text = "Connecting..." }) {
7874
8314
  const styles = (0, import_theme9.editorSpinner)();
7875
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: styles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: styles.content(), children: [
7876
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
8315
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: styles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: styles.content(), children: [
8316
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
7877
8317
  "svg",
7878
8318
  {
7879
8319
  className: styles.svg(),
@@ -7881,9 +8321,9 @@ function LoadingSpinner({ text = "Connecting..." }) {
7881
8321
  fill: "none",
7882
8322
  viewBox: "0 0 24 24",
7883
8323
  children: [
7884
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("title", { children: "Loading Spinner" }),
7885
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("circle", { className: styles.circle(), cx: "12", cy: "12", r: "10" }),
7886
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
8324
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("title", { children: "Loading Spinner" }),
8325
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { className: styles.circle(), cx: "12", cy: "12", r: "10" }),
8326
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7887
8327
  "path",
7888
8328
  {
7889
8329
  className: styles.path(),
@@ -7893,7 +8333,7 @@ function LoadingSpinner({ text = "Connecting..." }) {
7893
8333
  ]
7894
8334
  }
7895
8335
  ),
7896
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: styles.text(), children: text })
8336
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: styles.text(), children: text })
7897
8337
  ] }) });
7898
8338
  }
7899
8339
  // Annotate the CommonJS export names for ESM import in node: