@bigbinary/neeto-editor 1.36.2 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,20 +2,21 @@ import _extends$1 from '@babel/runtime/helpers/extends';
2
2
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
3
3
  import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
4
4
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
5
- import React__default, { createContext, useContext, useState, useEffect, useRef, useMemo } from 'react';
6
- import { isEmpty, concat, isNil, not, prop, fromPairs, assoc, last } from 'ramda';
5
+ import React__default, { forwardRef, createContext, useRef, useState, useEffect, useContext, useMemo, useCallback } from 'react';
6
+ import { isEmpty, last, not, prop, assoc, concat, isNil, fromPairs } from 'ramda';
7
7
  import { n } from './chunk-15c449f1.js';
8
8
  import { T as TextSelection, N as NodeSelection, S as Selection, c as Slice, d as dropPoint, j as DOMSerializer, F as Fragment, k as DOMParser, A as AllSelection, l as Mark$1, P as Plugin, m as liftTarget, r as replaceStep, R as ReplaceStep, n as canJoin, o as joinPoint, p as canSplit, q as ReplaceAroundStep, u as findWrapping, w as NodeRange, b as PluginKey, f as Transform, E as EditorState, x as Schema, v as validateAndFormatUrl, D as DEFAULT_EDITOR_OPTIONS } from './chunk-e876ad10.js';
9
9
  import tippy, { roundArrow } from 'tippy.js';
10
10
  import ReactDOM, { flushSync, createPortal } from 'react-dom';
11
11
  import classnames from 'classnames';
12
- import { Y as YOUTUBE_URL_REGEXP, V as VIMEO_URL_REGEXP, L as LOOM_URL_REGEXP, N as NEETO_RECORD_URL_REGEXP, a as UNSPLASH_BASE_URL, U as URL_REGEXP, E as EDITOR_OPTIONS } from './chunk-edd8b9fe.js';
13
- import { removeById, isNotPresent, isNotEmpty, noop, hyphenate, findBy } from '@bigbinary/neeto-cist';
12
+ import { Y as YOUTUBE_URL_REGEXP, V as VIMEO_URL_REGEXP, L as LOOM_URL_REGEXP, N as NEETO_RECORD_URL_REGEXP, E as EDITOR_OPTIONS, a as UNSPLASH_BASE_URL, U as URL_REGEXP } from './chunk-edd8b9fe.js';
13
+ import { isNotEmpty, removeById, isNotPresent, noop, hyphenate, findBy } from '@bigbinary/neeto-cist';
14
14
  import 'tippy.js/dist/svg-arrow.css';
15
- import { Close, ImageUpload, Check, Email, Smiley, Customize, Refresh, TextBold, TextItalic, Underline, Link, TextCross, Highlight, Quote, Code, CodeBlock, ListDot, ListNumber, Attachment, Video, MediaVideo, Undo, Redo, Column, Left, Right, File } from '@bigbinary/neeto-icons';
16
- import { Modal, Typography, Input, Button as Button$1, Toastr, Spinner, Tab, Dropdown as Dropdown$1, Avatar, Checkbox, Tooltip } from '@bigbinary/neetoui';
15
+ import { Smiley, Column, Customize, Check, Close, Refresh, Email, Undo, Redo, TextBold, TextItalic, Underline, Link, TextCross, Highlight, ListDot, ListNumber, Quote, Code, CodeBlock, Attachment, ImageUpload, Video, MediaVideo, MenuHorizontal, File } from '@bigbinary/neeto-icons';
16
+ import { Modal, Typography, Input, Button as Button$1, Dropdown as Dropdown$1, Avatar, Toastr, Spinner, Tab, Checkbox, Tooltip } from '@bigbinary/neetoui';
17
17
  import { useTranslation } from 'react-i18next';
18
18
  import { withEventTargetValue } from '@bigbinary/neeto-commons-frontend/utils';
19
+ import i18n, { t as t$1 } from 'i18next';
19
20
  import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
20
21
  import _classCallCheck$1 from '@babel/runtime/helpers/classCallCheck';
21
22
  import _createClass$1 from '@babel/runtime/helpers/createClass';
@@ -27,11 +28,10 @@ import { Picker } from 'emoji-mart';
27
28
  import axios from 'axios';
28
29
  import { useOnClickOutside } from '@bigbinary/neeto-commons-frontend/react-utils';
29
30
  import { HexColorPicker } from 'react-colorful';
30
- import i18n, { t as t$1 } from 'i18next';
31
+ import _objectWithoutProperties$1 from '@babel/runtime/helpers/objectWithoutProperties';
31
32
  import DynamicVariables from '@bigbinary/neeto-molecules/DynamicVariables';
32
33
  import { c as DEFAULT_IMAGE_UPPY_CONFIG, e as DEFAULT_VIDEO_UPPY_CONFIG, u as useUppyUploader, D as DropTarget, A as ALLOWED_IMAGE_TYPES, f as ALLOWED_VIDEO_TYPES, g as convertToFileSize, p as propTypesExports, h as getTabs } from './chunk-3aa8ee50.js';
33
34
  import { a as getAugmentedNamespace } from './chunk-65f73e5a.js';
34
- import _objectWithoutProperties$1 from '@babel/runtime/helpers/objectWithoutProperties';
35
35
  import Tippy from '@tippyjs/react';
36
36
 
37
37
  const domIndex = function (node) {
@@ -6645,6 +6645,11 @@ function sinkListItem$1(itemType) {
6645
6645
  };
6646
6646
  }
6647
6647
 
6648
+ /**
6649
+ * Takes a Transaction & Editor State and turns it into a chainable state object
6650
+ * @param config The transaction and state to create the chainable state from
6651
+ * @returns A chainable Editor state object
6652
+ */
6648
6653
  function createChainableState(config) {
6649
6654
  const { state, transaction } = config;
6650
6655
  let { selection } = transaction;
@@ -6811,6 +6816,13 @@ class EventEmitter {
6811
6816
  }
6812
6817
  }
6813
6818
 
6819
+ /**
6820
+ * Returns a field from an extension
6821
+ * @param extension The Tiptap extension
6822
+ * @param field The field, for example `renderHTML` or `priority`
6823
+ * @param context The context object that should be passed as `this` into the function
6824
+ * @returns The field value
6825
+ */
6814
6826
  function getExtensionField(extension, field, context) {
6815
6827
  if (extension.config[field] === undefined && extension.parent) {
6816
6828
  return getExtensionField(extension.parent, field, context);
@@ -7055,6 +7067,12 @@ function cleanUpSchemaItem(data) {
7055
7067
  return value !== null && value !== undefined;
7056
7068
  }));
7057
7069
  }
7070
+ /**
7071
+ * Creates a new Prosemirror schema based on the given extensions.
7072
+ * @param extensions An array of Tiptap extensions
7073
+ * @param editor The editor instance
7074
+ * @returns A Prosemirror schema
7075
+ */
7058
7076
  function getSchemaByResolvedExtensions(extensions, editor) {
7059
7077
  var _a;
7060
7078
  const allAttributes = getAttributesFromExtensions(extensions);
@@ -7156,6 +7174,12 @@ function getSchemaByResolvedExtensions(extensions, editor) {
7156
7174
  });
7157
7175
  }
7158
7176
 
7177
+ /**
7178
+ * Tries to get a node or mark type by its name.
7179
+ * @param name The name of the node or mark type
7180
+ * @param schema The Prosemiror schema to search in
7181
+ * @returns The node or mark type, or null if it doesn't exist
7182
+ */
7159
7183
  function getSchemaTypeByName(name, schema) {
7160
7184
  return schema.nodes[name] || schema.marks[name] || null;
7161
7185
  }
@@ -7172,6 +7196,12 @@ function isExtensionRulesEnabled(extension, enabled) {
7172
7196
  return enabled;
7173
7197
  }
7174
7198
 
7199
+ /**
7200
+ * Returns the text content of a resolved prosemirror position
7201
+ * @param $from The resolved position to get the text content from
7202
+ * @param maxMatch The maximum number of characters to match
7203
+ * @returns The text content
7204
+ */
7175
7205
  const getTextContentFromNodes = ($from, maxMatch = 500) => {
7176
7206
  let textBefore = '';
7177
7207
  const sliceEndPos = $from.parentOffset;
@@ -7379,6 +7409,10 @@ function isNumber(value) {
7379
7409
  return typeof value === 'number';
7380
7410
  }
7381
7411
 
7412
+ /**
7413
+ * Paste rules are used to react to pasted content.
7414
+ * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
7415
+ */
7382
7416
  class PasteRule {
7383
7417
  constructor(config) {
7384
7418
  this.find = config.find;
@@ -7577,57 +7611,14 @@ class ExtensionManager {
7577
7611
  this.editor = editor;
7578
7612
  this.extensions = ExtensionManager.resolve(extensions);
7579
7613
  this.schema = getSchemaByResolvedExtensions(this.extensions, editor);
7580
- this.extensions.forEach(extension => {
7581
- var _a;
7582
- // store extension storage in editor
7583
- this.editor.extensionStorage[extension.name] = extension.storage;
7584
- const context = {
7585
- name: extension.name,
7586
- options: extension.options,
7587
- storage: extension.storage,
7588
- editor: this.editor,
7589
- type: getSchemaTypeByName(extension.name, this.schema),
7590
- };
7591
- if (extension.type === 'mark') {
7592
- const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, 'keepOnSplit', context))) !== null && _a !== void 0 ? _a : true;
7593
- if (keepOnSplit) {
7594
- this.splittableMarks.push(extension.name);
7595
- }
7596
- }
7597
- const onBeforeCreate = getExtensionField(extension, 'onBeforeCreate', context);
7598
- if (onBeforeCreate) {
7599
- this.editor.on('beforeCreate', onBeforeCreate);
7600
- }
7601
- const onCreate = getExtensionField(extension, 'onCreate', context);
7602
- if (onCreate) {
7603
- this.editor.on('create', onCreate);
7604
- }
7605
- const onUpdate = getExtensionField(extension, 'onUpdate', context);
7606
- if (onUpdate) {
7607
- this.editor.on('update', onUpdate);
7608
- }
7609
- const onSelectionUpdate = getExtensionField(extension, 'onSelectionUpdate', context);
7610
- if (onSelectionUpdate) {
7611
- this.editor.on('selectionUpdate', onSelectionUpdate);
7612
- }
7613
- const onTransaction = getExtensionField(extension, 'onTransaction', context);
7614
- if (onTransaction) {
7615
- this.editor.on('transaction', onTransaction);
7616
- }
7617
- const onFocus = getExtensionField(extension, 'onFocus', context);
7618
- if (onFocus) {
7619
- this.editor.on('focus', onFocus);
7620
- }
7621
- const onBlur = getExtensionField(extension, 'onBlur', context);
7622
- if (onBlur) {
7623
- this.editor.on('blur', onBlur);
7624
- }
7625
- const onDestroy = getExtensionField(extension, 'onDestroy', context);
7626
- if (onDestroy) {
7627
- this.editor.on('destroy', onDestroy);
7628
- }
7629
- });
7614
+ this.setupExtensions();
7630
7615
  }
7616
+ /**
7617
+ * Returns a flattened and sorted extension list while
7618
+ * also checking for duplicated extensions and warns the user.
7619
+ * @param extensions An array of Tiptap extensions
7620
+ * @returns An flattened and sorted array of Tiptap extensions
7621
+ */
7631
7622
  static resolve(extensions) {
7632
7623
  const resolvedExtensions = ExtensionManager.sort(ExtensionManager.flatten(extensions));
7633
7624
  const duplicatedNames = findDuplicates(resolvedExtensions.map(extension => extension.name));
@@ -7638,6 +7629,11 @@ class ExtensionManager {
7638
7629
  }
7639
7630
  return resolvedExtensions;
7640
7631
  }
7632
+ /**
7633
+ * Create a flattened array of extensions by traversing the `addExtensions` field.
7634
+ * @param extensions An array of Tiptap extensions
7635
+ * @returns A flattened array of Tiptap extensions
7636
+ */
7641
7637
  static flatten(extensions) {
7642
7638
  return (extensions
7643
7639
  .map(extension => {
@@ -7655,6 +7651,11 @@ class ExtensionManager {
7655
7651
  // `Infinity` will break TypeScript so we set a number that is probably high enough
7656
7652
  .flat(10));
7657
7653
  }
7654
+ /**
7655
+ * Sort extensions by priority.
7656
+ * @param extensions An array of Tiptap extensions
7657
+ * @returns A sorted array of Tiptap extensions by priority
7658
+ */
7658
7659
  static sort(extensions) {
7659
7660
  const defaultPriority = 100;
7660
7661
  return extensions.sort((a, b) => {
@@ -7669,6 +7670,10 @@ class ExtensionManager {
7669
7670
  return 0;
7670
7671
  });
7671
7672
  }
7673
+ /**
7674
+ * Get all commands from the extensions.
7675
+ * @returns An object with all commands where the key is the command name and the value is the command function
7676
+ */
7672
7677
  get commands() {
7673
7678
  return this.extensions.reduce((commands, extension) => {
7674
7679
  const context = {
@@ -7688,6 +7693,10 @@ class ExtensionManager {
7688
7693
  };
7689
7694
  }, {});
7690
7695
  }
7696
+ /**
7697
+ * Get all registered Prosemirror plugins from the extensions.
7698
+ * @returns An array of Prosemirror plugins
7699
+ */
7691
7700
  get plugins() {
7692
7701
  const { editor } = this;
7693
7702
  // With ProseMirror, first plugins within an array are executed first.
@@ -7750,9 +7759,17 @@ class ExtensionManager {
7750
7759
  ...allPlugins,
7751
7760
  ];
7752
7761
  }
7762
+ /**
7763
+ * Get all attributes from the extensions.
7764
+ * @returns An array of attributes
7765
+ */
7753
7766
  get attributes() {
7754
7767
  return getAttributesFromExtensions(this.extensions);
7755
7768
  }
7769
+ /**
7770
+ * Get all node views from the extensions.
7771
+ * @returns An object with all node views where the key is the node name and the value is the node view function
7772
+ */
7756
7773
  get nodeViews() {
7757
7774
  const { editor } = this;
7758
7775
  const { nodeExtensions } = splitExtensions(this.extensions);
@@ -7785,6 +7802,62 @@ class ExtensionManager {
7785
7802
  return [extension.name, nodeview];
7786
7803
  }));
7787
7804
  }
7805
+ /**
7806
+ * Go through all extensions, create extension storages & setup marks
7807
+ * & bind editor event listener.
7808
+ */
7809
+ setupExtensions() {
7810
+ this.extensions.forEach(extension => {
7811
+ var _a;
7812
+ // store extension storage in editor
7813
+ this.editor.extensionStorage[extension.name] = extension.storage;
7814
+ const context = {
7815
+ name: extension.name,
7816
+ options: extension.options,
7817
+ storage: extension.storage,
7818
+ editor: this.editor,
7819
+ type: getSchemaTypeByName(extension.name, this.schema),
7820
+ };
7821
+ if (extension.type === 'mark') {
7822
+ const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, 'keepOnSplit', context))) !== null && _a !== void 0 ? _a : true;
7823
+ if (keepOnSplit) {
7824
+ this.splittableMarks.push(extension.name);
7825
+ }
7826
+ }
7827
+ const onBeforeCreate = getExtensionField(extension, 'onBeforeCreate', context);
7828
+ const onCreate = getExtensionField(extension, 'onCreate', context);
7829
+ const onUpdate = getExtensionField(extension, 'onUpdate', context);
7830
+ const onSelectionUpdate = getExtensionField(extension, 'onSelectionUpdate', context);
7831
+ const onTransaction = getExtensionField(extension, 'onTransaction', context);
7832
+ const onFocus = getExtensionField(extension, 'onFocus', context);
7833
+ const onBlur = getExtensionField(extension, 'onBlur', context);
7834
+ const onDestroy = getExtensionField(extension, 'onDestroy', context);
7835
+ if (onBeforeCreate) {
7836
+ this.editor.on('beforeCreate', onBeforeCreate);
7837
+ }
7838
+ if (onCreate) {
7839
+ this.editor.on('create', onCreate);
7840
+ }
7841
+ if (onUpdate) {
7842
+ this.editor.on('update', onUpdate);
7843
+ }
7844
+ if (onSelectionUpdate) {
7845
+ this.editor.on('selectionUpdate', onSelectionUpdate);
7846
+ }
7847
+ if (onTransaction) {
7848
+ this.editor.on('transaction', onTransaction);
7849
+ }
7850
+ if (onFocus) {
7851
+ this.editor.on('focus', onFocus);
7852
+ }
7853
+ if (onBlur) {
7854
+ this.editor.on('blur', onBlur);
7855
+ }
7856
+ if (onDestroy) {
7857
+ this.editor.on('destroy', onDestroy);
7858
+ }
7859
+ });
7860
+ }
7788
7861
  }
7789
7862
 
7790
7863
  // see: https://github.com/mesqueeb/is-what/blob/88d6e4ca92fb2baab6003c54e02eedf4e729e5ab/src/index.ts
@@ -7818,6 +7891,10 @@ function mergeDeep(target, source) {
7818
7891
  return output;
7819
7892
  }
7820
7893
 
7894
+ /**
7895
+ * The Extension class is the base class for all extensions.
7896
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
7897
+ */
7821
7898
  class Extension {
7822
7899
  constructor(config = {}) {
7823
7900
  this.type = 'extension';
@@ -7855,6 +7932,7 @@ class Extension {
7855
7932
  // return a new instance so we can use the same extension
7856
7933
  // with different calls of `configure`
7857
7934
  const extension = this.extend();
7935
+ extension.parent = this.parent;
7858
7936
  extension.options = mergeDeep(this.options, options);
7859
7937
  extension.storage = callOrReturn(getExtensionField(extension, 'addStorage', {
7860
7938
  name: extension.name,
@@ -7881,19 +7959,25 @@ class Extension {
7881
7959
  }
7882
7960
  }
7883
7961
 
7962
+ /**
7963
+ * Gets the text between two positions in a Prosemirror node
7964
+ * and serializes it using the given text serializers and block separator (see getText)
7965
+ * @param startNode The Prosemirror node to start from
7966
+ * @param range The range of the text to get
7967
+ * @param options Options for the text serializer & block separator
7968
+ * @returns The text between the two positions
7969
+ */
7884
7970
  function getTextBetween(startNode, range, options) {
7885
7971
  const { from, to } = range;
7886
7972
  const { blockSeparator = '\n\n', textSerializers = {} } = options || {};
7887
7973
  let text = '';
7888
- let separated = true;
7889
7974
  startNode.nodesBetween(from, to, (node, pos, parent, index) => {
7890
7975
  var _a;
7976
+ if (node.isBlock && pos > from) {
7977
+ text += blockSeparator;
7978
+ }
7891
7979
  const textSerializer = textSerializers === null || textSerializers === void 0 ? void 0 : textSerializers[node.type.name];
7892
7980
  if (textSerializer) {
7893
- if (node.isBlock && !separated) {
7894
- text += blockSeparator;
7895
- separated = true;
7896
- }
7897
7981
  if (parent) {
7898
7982
  text += textSerializer({
7899
7983
  node,
@@ -7908,16 +7992,16 @@ function getTextBetween(startNode, range, options) {
7908
7992
  }
7909
7993
  if (node.isText) {
7910
7994
  text += (_a = node === null || node === void 0 ? void 0 : node.text) === null || _a === void 0 ? void 0 : _a.slice(Math.max(from, pos) - pos, to - pos); // eslint-disable-line
7911
- separated = false;
7912
- }
7913
- else if (node.isBlock && !separated) {
7914
- text += blockSeparator;
7915
- separated = true;
7916
7995
  }
7917
7996
  });
7918
7997
  return text;
7919
7998
  }
7920
7999
 
8000
+ /**
8001
+ * Find text serializers `toText` in a Prosemirror schema
8002
+ * @param schema The Prosemirror schema to search in
8003
+ * @returns A record of text serializers by node name
8004
+ */
7921
8005
  function getTextSerializersFromSchema(schema) {
7922
8006
  return Object.fromEntries(Object.entries(schema.nodes)
7923
8007
  .filter(([, node]) => node.spec.toText)
@@ -8300,15 +8384,26 @@ function elementFromString(value) {
8300
8384
  return removeWhitespaces(html);
8301
8385
  }
8302
8386
 
8387
+ /**
8388
+ * Takes a JSON or HTML content and creates a Prosemirror node or fragment from it.
8389
+ * @param content The JSON or HTML content to create the node from
8390
+ * @param schema The Prosemirror schema to use for the node
8391
+ * @param options Options for the parser
8392
+ * @returns The created Prosemirror node or fragment
8393
+ */
8303
8394
  function createNodeFromContent(content, schema, options) {
8304
8395
  options = {
8305
8396
  slice: true,
8306
8397
  parseOptions: {},
8307
8398
  ...options,
8308
8399
  };
8309
- if (typeof content === 'object' && content !== null) {
8400
+ const isJSONContent = typeof content === 'object' && content !== null;
8401
+ const isTextContent = typeof content === 'string';
8402
+ if (isJSONContent) {
8310
8403
  try {
8311
- if (Array.isArray(content) && content.length > 0) {
8404
+ const isArrayContent = Array.isArray(content) && content.length > 0;
8405
+ // if the JSON Content is an array of nodes, create a fragment for each node
8406
+ if (isArrayContent) {
8312
8407
  return Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)));
8313
8408
  }
8314
8409
  return schema.nodeFromJSON(content);
@@ -8318,7 +8413,7 @@ function createNodeFromContent(content, schema, options) {
8318
8413
  return createNodeFromContent('', schema, options);
8319
8414
  }
8320
8415
  }
8321
- if (typeof content === 'string') {
8416
+ if (isTextContent) {
8322
8417
  const parser = DOMParser.fromSchema(schema);
8323
8418
  return options.slice
8324
8419
  ? parser.parseSlice(elementFromString(content), options.parseOptions).content
@@ -8618,6 +8713,12 @@ const newlineInCode = () => ({ state, dispatch }) => {
8618
8713
  return newlineInCode$1(state, dispatch);
8619
8714
  };
8620
8715
 
8716
+ /**
8717
+ * Get the type of a schema item by its name.
8718
+ * @param name The name of the schema item
8719
+ * @param schema The Prosemiror schema to search in
8720
+ * @returns The type of the schema item (`node` or `mark`), or null if it doesn't exist
8721
+ */
8621
8722
  function getSchemaTypeNameByName(name, schema) {
8622
8723
  if (schema.nodes[name]) {
8623
8724
  return 'node';
@@ -8715,6 +8816,13 @@ const selectTextblockStart = () => ({ state, dispatch }) => {
8715
8816
  return selectTextblockStart$1(state, dispatch);
8716
8817
  };
8717
8818
 
8819
+ /**
8820
+ * Create a new Prosemirror document node from content.
8821
+ * @param content The JSON or HTML content to create the document from
8822
+ * @param schema The Prosemirror schema to use for the document
8823
+ * @param parseOptions Options for the parser
8824
+ * @returns The created Prosemirror document node
8825
+ */
8718
8826
  function createDocument(content, schema, parseOptions = {}) {
8719
8827
  return createNodeFromContent(content, schema, { slice: false, parseOptions });
8720
8828
  }
@@ -8752,6 +8860,9 @@ function getMarkAttributes(state, typeOrName) {
8752
8860
 
8753
8861
  /**
8754
8862
  * Returns a new `Transform` based on all steps of the passed transactions.
8863
+ * @param oldDoc The Prosemirror node to start from
8864
+ * @param transactions The transactions to combine
8865
+ * @returns A new `Transform` with all steps of the passed transactions
8755
8866
  */
8756
8867
  function combineTransactionSteps(oldDoc, transactions) {
8757
8868
  const transform = new Transform(oldDoc);
@@ -8763,6 +8874,11 @@ function combineTransactionSteps(oldDoc, transactions) {
8763
8874
  return transform;
8764
8875
  }
8765
8876
 
8877
+ /**
8878
+ * Gets the default block type at a given match
8879
+ * @param match The content match to get the default block type from
8880
+ * @returns The default block type or null
8881
+ */
8766
8882
  function defaultBlockAt(match) {
8767
8883
  for (let i = 0; i < match.edgeCount; i += 1) {
8768
8884
  const { type } = match.edge(i);
@@ -8773,6 +8889,12 @@ function defaultBlockAt(match) {
8773
8889
  return null;
8774
8890
  }
8775
8891
 
8892
+ /**
8893
+ * Find children inside a Prosemirror node that match a predicate.
8894
+ * @param node The Prosemirror node to search in
8895
+ * @param predicate The predicate to match
8896
+ * @returns An array of nodes with their positions
8897
+ */
8776
8898
  function findChildren(node, predicate) {
8777
8899
  const nodesWithPos = [];
8778
8900
  node.descendants((child, pos) => {
@@ -8788,6 +8910,10 @@ function findChildren(node, predicate) {
8788
8910
 
8789
8911
  /**
8790
8912
  * Same as `findChildren` but searches only within a `range`.
8913
+ * @param node The Prosemirror node to search in
8914
+ * @param range The range to search in
8915
+ * @param predicate The predicate to match
8916
+ * @returns An array of nodes with their positions
8791
8917
  */
8792
8918
  function findChildrenInRange(node, range, predicate) {
8793
8919
  const nodesWithPos = [];
@@ -8811,6 +8937,15 @@ function findChildrenInRange(node, range, predicate) {
8811
8937
  return nodesWithPos;
8812
8938
  }
8813
8939
 
8940
+ /**
8941
+ * Finds the closest parent node to a resolved position that matches a predicate.
8942
+ * @param $pos The resolved position to search from
8943
+ * @param predicate The predicate to match
8944
+ * @returns The closest parent node to the resolved position that matches the predicate
8945
+ * @example ```js
8946
+ * findParentNodeClosestToPos($from, node => node.type.name === 'paragraph')
8947
+ * ```
8948
+ */
8814
8949
  function findParentNodeClosestToPos($pos, predicate) {
8815
8950
  for (let i = $pos.depth; i > 0; i -= 1) {
8816
8951
  const node = $pos.node(i);
@@ -8825,6 +8960,14 @@ function findParentNodeClosestToPos($pos, predicate) {
8825
8960
  }
8826
8961
  }
8827
8962
 
8963
+ /**
8964
+ * Finds the closest parent node to the current selection that matches a predicate.
8965
+ * @param predicate The predicate to match
8966
+ * @returns A command that finds the closest parent node to the current selection that matches the predicate
8967
+ * @example ```js
8968
+ * findParentNode(node => node.type.name === 'paragraph')
8969
+ * ```
8970
+ */
8828
8971
  function findParentNode(predicate) {
8829
8972
  return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
8830
8973
  }
@@ -8837,6 +8980,15 @@ function getHTMLFromFragment(fragment, schema) {
8837
8980
  return container.innerHTML;
8838
8981
  }
8839
8982
 
8983
+ /**
8984
+ * Gets the text of a Prosemirror node
8985
+ * @param node The Prosemirror node
8986
+ * @param options Options for the text serializer & block separator
8987
+ * @returns The text of the node
8988
+ * @example ```js
8989
+ * const text = getText(node, { blockSeparator: '\n' })
8990
+ * ```
8991
+ */
8840
8992
  function getText(node, options) {
8841
8993
  const range = {
8842
8994
  from: 0,
@@ -8859,6 +9011,12 @@ function getNodeAttributes(state, typeOrName) {
8859
9011
  return { ...node.attrs };
8860
9012
  }
8861
9013
 
9014
+ /**
9015
+ * Get node or mark attributes by type or name on the current editor state
9016
+ * @param state The current editor state
9017
+ * @param typeOrName The node or mark type or name
9018
+ * @returns The attributes of the node or mark or an empty object
9019
+ */
8862
9020
  function getAttributes(state, typeOrName) {
8863
9021
  const schemaType = getSchemaTypeNameByName(typeof typeOrName === 'string' ? typeOrName : typeOrName.name, state.schema);
8864
9022
  if (schemaType === 'node') {
@@ -8980,6 +9138,13 @@ function getMarksBetween(from, to, doc) {
8980
9138
  return marks;
8981
9139
  }
8982
9140
 
9141
+ /**
9142
+ * Return attributes of an extension that should be splitted by keepOnSplit flag
9143
+ * @param extensionAttributes Array of extension attributes
9144
+ * @param typeName The type of the extension
9145
+ * @param attributes The attributes of the extension
9146
+ * @returns The splitted attributes
9147
+ */
8983
9148
  function getSplittedAttributes(extensionAttributes, typeName, attributes) {
8984
9149
  return Object.fromEntries(Object
8985
9150
  .entries(attributes)
@@ -9803,7 +9968,12 @@ const Keymap = Extension.create({
9803
9968
  const isAtStart = (parentIsIsolating && $parentPos.parent.childCount === 1)
9804
9969
  ? parentPos === $anchor.pos
9805
9970
  : Selection.atStart(doc).from === pos;
9806
- if (!empty || !isAtStart || !parent.type.isTextblock || parent.textContent.length) {
9971
+ if (!empty
9972
+ || !parent.type.isTextblock
9973
+ || parent.textContent.length
9974
+ || !isAtStart
9975
+ || (isAtStart && $anchor.parent.type.name === 'paragraph') // prevent clearNodes when no nodes to clear, otherwise history stack is appended
9976
+ ) {
9807
9977
  return false;
9808
9978
  }
9809
9979
  return commands.clearNodes();
@@ -10055,28 +10225,30 @@ class NodePos {
10055
10225
  }
10056
10226
  querySelectorAll(selector, attributes = {}, firstItemOnly = false) {
10057
10227
  let nodes = [];
10058
- // iterate through children recursively finding all nodes which match the selector with the node name
10059
10228
  if (!this.children || this.children.length === 0) {
10060
10229
  return nodes;
10061
10230
  }
10231
+ const attrKeys = Object.keys(attributes);
10232
+ /**
10233
+ * Finds all children recursively that match the selector and attributes
10234
+ * If firstItemOnly is true, it will return the first item found
10235
+ */
10062
10236
  this.children.forEach(childPos => {
10237
+ // If we already found a node and we only want the first item, we dont need to keep going
10238
+ if (firstItemOnly && nodes.length > 0) {
10239
+ return;
10240
+ }
10063
10241
  if (childPos.node.type.name === selector) {
10064
- if (Object.keys(attributes).length > 0) {
10065
- const nodeAttributes = childPos.node.attrs;
10066
- const attrKeys = Object.keys(attributes);
10067
- for (let index = 0; index < attrKeys.length; index += 1) {
10068
- const key = attrKeys[index];
10069
- if (nodeAttributes[key] !== attributes[key]) {
10070
- return;
10071
- }
10072
- }
10073
- }
10074
- nodes.push(childPos);
10075
- if (firstItemOnly) {
10076
- return;
10242
+ const doesAllAttributesMatch = attrKeys.every(key => attributes[key] === childPos.node.attrs[key]);
10243
+ if (doesAllAttributesMatch) {
10244
+ nodes.push(childPos);
10077
10245
  }
10078
10246
  }
10079
- nodes = nodes.concat(childPos.querySelectorAll(selector));
10247
+ // If we already found a node and we only want the first item, we can stop here and skip the recursion
10248
+ if (firstItemOnly && nodes.length > 0) {
10249
+ return;
10250
+ }
10251
+ nodes = nodes.concat(childPos.querySelectorAll(selector, attributes, firstItemOnly));
10080
10252
  });
10081
10253
  return nodes;
10082
10254
  }
@@ -10563,6 +10735,7 @@ class Editor$1 extends EventEmitter {
10563
10735
  /**
10564
10736
  * Build an input rule that adds a mark when the
10565
10737
  * matched text is typed into it.
10738
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
10566
10739
  */
10567
10740
  function markInputRule(config) {
10568
10741
  return new InputRule({
@@ -10606,6 +10779,7 @@ function markInputRule(config) {
10606
10779
  /**
10607
10780
  * Build an input rule that adds a node when the
10608
10781
  * matched text is typed into it.
10782
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
10609
10783
  */
10610
10784
  function nodeInputRule(config) {
10611
10785
  return new InputRule({
@@ -10644,6 +10818,7 @@ function nodeInputRule(config) {
10644
10818
  * matched text is typed into it. When using a regular expresion you’ll
10645
10819
  * probably want the regexp to start with `^`, so that the pattern can
10646
10820
  * only occur at the start of a textblock.
10821
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
10647
10822
  */
10648
10823
  function textblockTypeInputRule(config) {
10649
10824
  return new InputRule({
@@ -10674,6 +10849,7 @@ function textblockTypeInputRule(config) {
10674
10849
  * two nodes. You can pass a join predicate, which takes a regular
10675
10850
  * expression match and the node before the wrapped node, and can
10676
10851
  * return a boolean to indicate whether a join should happen.
10852
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
10677
10853
  */
10678
10854
  function wrappingInputRule(config) {
10679
10855
  return new InputRule({
@@ -10713,6 +10889,10 @@ function wrappingInputRule(config) {
10713
10889
  });
10714
10890
  }
10715
10891
 
10892
+ /**
10893
+ * The Mark class is used to create custom mark extensions.
10894
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
10895
+ */
10716
10896
  class Mark {
10717
10897
  constructor(config = {}) {
10718
10898
  this.type = 'mark';
@@ -10796,6 +10976,10 @@ class Mark {
10796
10976
  }
10797
10977
  }
10798
10978
 
10979
+ /**
10980
+ * The Node class is used to create custom node extensions.
10981
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
10982
+ */
10799
10983
  class Node {
10800
10984
  constructor(config = {}) {
10801
10985
  this.type = 'node';
@@ -10863,6 +11047,10 @@ function isAndroid() {
10863
11047
  return navigator.platform === 'Android' || /android/i.test(navigator.userAgent);
10864
11048
  }
10865
11049
 
11050
+ /**
11051
+ * Node views are used to customize the rendered DOM structure of a node.
11052
+ * @see https://tiptap.dev/guide/node-views
11053
+ */
10866
11054
  class NodeView {
10867
11055
  constructor(component, props, options) {
10868
11056
  this.isDragging = false;
@@ -11053,6 +11241,7 @@ class NodeView {
11053
11241
  /**
11054
11242
  * Build an paste rule that adds a mark when the
11055
11243
  * matched text is pasted into it.
11244
+ * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
11056
11245
  */
11057
11246
  function markPasteRule(config) {
11058
11247
  return new PasteRule({
@@ -11274,6 +11463,10 @@ const BubbleMenuPlugin = (options) => {
11274
11463
  });
11275
11464
  };
11276
11465
 
11466
+ /**
11467
+ * This extension allows you to create a bubble menu.
11468
+ * @see https://tiptap.dev/api/extensions/bubble-menu
11469
+ */
11277
11470
  Extension.create({
11278
11471
  name: 'bubbleMenu',
11279
11472
  addOptions() {
@@ -11302,41 +11495,20 @@ Extension.create({
11302
11495
  },
11303
11496
  });
11304
11497
 
11305
- const BubbleMenu = (props) => {
11306
- const [element, setElement] = useState(null);
11307
- useEffect(() => {
11308
- if (!element) {
11309
- return;
11310
- }
11311
- if (props.editor.isDestroyed) {
11312
- return;
11313
- }
11314
- const { pluginKey = 'bubbleMenu', editor, tippyOptions = {}, shouldShow = null, } = props;
11315
- const plugin = BubbleMenuPlugin({
11316
- pluginKey,
11317
- editor,
11318
- element,
11319
- tippyOptions,
11320
- shouldShow,
11498
+ const mergeRefs = (...refs) => {
11499
+ return (node) => {
11500
+ refs.forEach(ref => {
11501
+ if (typeof ref === 'function') {
11502
+ ref(node);
11503
+ }
11504
+ else if (ref) {
11505
+ ref.current = node;
11506
+ }
11321
11507
  });
11322
- editor.registerPlugin(plugin);
11323
- return () => editor.unregisterPlugin(pluginKey);
11324
- }, [
11325
- props.editor,
11326
- element,
11327
- ]);
11328
- return (React__default.createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
11329
- };
11330
-
11331
- class Editor extends Editor$1 {
11332
- constructor() {
11333
- super(...arguments);
11334
- this.contentComponent = null;
11335
- }
11336
- }
11337
-
11508
+ };
11509
+ };
11338
11510
  const Portals = ({ renderers }) => {
11339
- return (React__default.createElement(React__default.Fragment, null, Array.from(renderers).map(([key, renderer]) => {
11511
+ return (React__default.createElement(React__default.Fragment, null, Object.entries(renderers).map(([key, renderer]) => {
11340
11512
  return ReactDOM.createPortal(renderer.reactElement, renderer.element, key);
11341
11513
  })));
11342
11514
  };
@@ -11344,8 +11516,9 @@ class PureEditorContent extends React__default.Component {
11344
11516
  constructor(props) {
11345
11517
  super(props);
11346
11518
  this.editorContentRef = React__default.createRef();
11519
+ this.initialized = false;
11347
11520
  this.state = {
11348
- renderers: new Map(),
11521
+ renderers: {},
11349
11522
  };
11350
11523
  }
11351
11524
  componentDidMount() {
@@ -11367,13 +11540,46 @@ class PureEditorContent extends React__default.Component {
11367
11540
  });
11368
11541
  editor.contentComponent = this;
11369
11542
  editor.createNodeViews();
11543
+ this.initialized = true;
11544
+ }
11545
+ }
11546
+ maybeFlushSync(fn) {
11547
+ // Avoid calling flushSync until the editor is initialized.
11548
+ // Initialization happens during the componentDidMount or componentDidUpdate
11549
+ // lifecycle methods, and React doesn't allow calling flushSync from inside
11550
+ // a lifecycle method.
11551
+ if (this.initialized) {
11552
+ flushSync(fn);
11553
+ }
11554
+ else {
11555
+ fn();
11370
11556
  }
11371
11557
  }
11558
+ setRenderer(id, renderer) {
11559
+ this.maybeFlushSync(() => {
11560
+ this.setState(({ renderers }) => ({
11561
+ renderers: {
11562
+ ...renderers,
11563
+ [id]: renderer,
11564
+ },
11565
+ }));
11566
+ });
11567
+ }
11568
+ removeRenderer(id) {
11569
+ this.maybeFlushSync(() => {
11570
+ this.setState(({ renderers }) => {
11571
+ const nextRenderers = { ...renderers };
11572
+ delete nextRenderers[id];
11573
+ return { renderers: nextRenderers };
11574
+ });
11575
+ });
11576
+ }
11372
11577
  componentWillUnmount() {
11373
11578
  const { editor } = this.props;
11374
11579
  if (!editor) {
11375
11580
  return;
11376
11581
  }
11582
+ this.initialized = false;
11377
11583
  if (!editor.isDestroyed) {
11378
11584
  editor.view.setProps({
11379
11585
  nodeViews: {},
@@ -11390,49 +11596,213 @@ class PureEditorContent extends React__default.Component {
11390
11596
  });
11391
11597
  }
11392
11598
  render() {
11393
- const { editor, ...rest } = this.props;
11599
+ const { editor, innerRef, ...rest } = this.props;
11394
11600
  return (React__default.createElement(React__default.Fragment, null,
11395
- React__default.createElement("div", { ref: this.editorContentRef, ...rest }),
11601
+ React__default.createElement("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }),
11396
11602
  React__default.createElement(Portals, { renderers: this.state.renderers })));
11397
11603
  }
11398
11604
  }
11399
- const EditorContent = React__default.memo(PureEditorContent);
11400
-
11401
- const ReactNodeViewContext = createContext({
11402
- onDragStart: undefined,
11605
+ // EditorContent should be re-created whenever the Editor instance changes
11606
+ const EditorContentWithKey = forwardRef((props, ref) => {
11607
+ const key = React__default.useMemo(() => {
11608
+ return Math.floor(Math.random() * 0xFFFFFFFF).toString();
11609
+ }, [props.editor]);
11610
+ // Can't use JSX here because it conflicts with the type definition of Vue's JSX, so use createElement
11611
+ return React__default.createElement(PureEditorContent, {
11612
+ key,
11613
+ innerRef: ref,
11614
+ ...props,
11615
+ });
11403
11616
  });
11404
- const useReactNodeView = () => useContext(ReactNodeViewContext);
11405
-
11406
- const NodeViewContent = props => {
11407
- const Tag = props.as || 'div';
11408
- const { nodeViewContentRef } = useReactNodeView();
11409
- return (React__default.createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
11410
- whiteSpace: 'pre-wrap',
11411
- ...props.style,
11412
- } }));
11413
- };
11617
+ const EditorContent = React__default.memo(EditorContentWithKey);
11414
11618
 
11415
- const NodeViewWrapper = React__default.forwardRef((props, ref) => {
11416
- const { onDragStart } = useReactNodeView();
11417
- const Tag = props.as || 'div';
11418
- return (React__default.createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
11419
- whiteSpace: 'normal',
11420
- ...props.style,
11421
- } }));
11422
- });
11619
+ class Editor extends Editor$1 {
11620
+ constructor() {
11621
+ super(...arguments);
11622
+ this.contentComponent = null;
11623
+ }
11624
+ }
11423
11625
 
11424
- function isClassComponent(Component) {
11425
- return !!(typeof Component === 'function'
11426
- && Component.prototype
11427
- && Component.prototype.isReactComponent);
11626
+ /**
11627
+ * This hook allows you to create an editor instance.
11628
+ * @param options The editor options
11629
+ * @param deps The dependencies to watch for changes
11630
+ * @returns The editor instance
11631
+ * @example const editor = useEditor({ extensions: [...] })
11632
+ */
11633
+ const useEditor = (options = {}, deps = []) => {
11634
+ const editorRef = useRef(null);
11635
+ const [, forceUpdate] = useState({});
11636
+ const { onBeforeCreate, onBlur, onCreate, onDestroy, onFocus, onSelectionUpdate, onTransaction, onUpdate, } = options;
11637
+ const onBeforeCreateRef = useRef(onBeforeCreate);
11638
+ const onBlurRef = useRef(onBlur);
11639
+ const onCreateRef = useRef(onCreate);
11640
+ const onDestroyRef = useRef(onDestroy);
11641
+ const onFocusRef = useRef(onFocus);
11642
+ const onSelectionUpdateRef = useRef(onSelectionUpdate);
11643
+ const onTransactionRef = useRef(onTransaction);
11644
+ const onUpdateRef = useRef(onUpdate);
11645
+ // This effect will handle updating the editor instance
11646
+ // when the event handlers change.
11647
+ useEffect(() => {
11648
+ if (!editorRef.current) {
11649
+ return;
11650
+ }
11651
+ if (onBeforeCreate) {
11652
+ editorRef.current.off('beforeCreate', onBeforeCreateRef.current);
11653
+ editorRef.current.on('beforeCreate', onBeforeCreate);
11654
+ onBeforeCreateRef.current = onBeforeCreate;
11655
+ }
11656
+ if (onBlur) {
11657
+ editorRef.current.off('blur', onBlurRef.current);
11658
+ editorRef.current.on('blur', onBlur);
11659
+ onBlurRef.current = onBlur;
11660
+ }
11661
+ if (onCreate) {
11662
+ editorRef.current.off('create', onCreateRef.current);
11663
+ editorRef.current.on('create', onCreate);
11664
+ onCreateRef.current = onCreate;
11665
+ }
11666
+ if (onDestroy) {
11667
+ editorRef.current.off('destroy', onDestroyRef.current);
11668
+ editorRef.current.on('destroy', onDestroy);
11669
+ onDestroyRef.current = onDestroy;
11670
+ }
11671
+ if (onFocus) {
11672
+ editorRef.current.off('focus', onFocusRef.current);
11673
+ editorRef.current.on('focus', onFocus);
11674
+ onFocusRef.current = onFocus;
11675
+ }
11676
+ if (onSelectionUpdate) {
11677
+ editorRef.current.off('selectionUpdate', onSelectionUpdateRef.current);
11678
+ editorRef.current.on('selectionUpdate', onSelectionUpdate);
11679
+ onSelectionUpdateRef.current = onSelectionUpdate;
11680
+ }
11681
+ if (onTransaction) {
11682
+ editorRef.current.off('transaction', onTransactionRef.current);
11683
+ editorRef.current.on('transaction', onTransaction);
11684
+ onTransactionRef.current = onTransaction;
11685
+ }
11686
+ if (onUpdate) {
11687
+ editorRef.current.off('update', onUpdateRef.current);
11688
+ editorRef.current.on('update', onUpdate);
11689
+ onUpdateRef.current = onUpdate;
11690
+ }
11691
+ }, [onBeforeCreate, onBlur, onCreate, onDestroy, onFocus, onSelectionUpdate, onTransaction, onUpdate, editorRef.current]);
11692
+ useEffect(() => {
11693
+ let isMounted = true;
11694
+ const editor = new Editor(options);
11695
+ editorRef.current = editor;
11696
+ editorRef.current.on('transaction', () => {
11697
+ requestAnimationFrame(() => {
11698
+ requestAnimationFrame(() => {
11699
+ if (isMounted) {
11700
+ forceUpdate({});
11701
+ }
11702
+ });
11703
+ });
11704
+ });
11705
+ return () => {
11706
+ isMounted = false;
11707
+ editor.destroy();
11708
+ };
11709
+ }, deps);
11710
+ return editorRef.current;
11711
+ };
11712
+
11713
+ const EditorContext = createContext({
11714
+ editor: null,
11715
+ });
11716
+ EditorContext.Consumer;
11717
+ const useCurrentEditor = () => useContext(EditorContext);
11718
+
11719
+ const BubbleMenu = (props) => {
11720
+ const [element, setElement] = useState(null);
11721
+ const { editor: currentEditor } = useCurrentEditor();
11722
+ useEffect(() => {
11723
+ var _a;
11724
+ if (!element) {
11725
+ return;
11726
+ }
11727
+ if (((_a = props.editor) === null || _a === void 0 ? void 0 : _a.isDestroyed) || (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.isDestroyed)) {
11728
+ return;
11729
+ }
11730
+ const { pluginKey = 'bubbleMenu', editor, tippyOptions = {}, updateDelay, shouldShow = null, } = props;
11731
+ const menuEditor = editor || currentEditor;
11732
+ if (!menuEditor) {
11733
+ console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.');
11734
+ return;
11735
+ }
11736
+ const plugin = BubbleMenuPlugin({
11737
+ updateDelay,
11738
+ editor: menuEditor,
11739
+ element,
11740
+ pluginKey,
11741
+ shouldShow,
11742
+ tippyOptions,
11743
+ });
11744
+ menuEditor.registerPlugin(plugin);
11745
+ return () => menuEditor.unregisterPlugin(pluginKey);
11746
+ }, [props.editor, currentEditor, element]);
11747
+ return (React__default.createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
11748
+ };
11749
+
11750
+ const ReactNodeViewContext = createContext({
11751
+ onDragStart: undefined,
11752
+ });
11753
+ const useReactNodeView = () => useContext(ReactNodeViewContext);
11754
+
11755
+ const NodeViewContent = props => {
11756
+ const Tag = props.as || 'div';
11757
+ const { nodeViewContentRef } = useReactNodeView();
11758
+ return (React__default.createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
11759
+ whiteSpace: 'pre-wrap',
11760
+ ...props.style,
11761
+ } }));
11762
+ };
11763
+
11764
+ const NodeViewWrapper = React__default.forwardRef((props, ref) => {
11765
+ const { onDragStart } = useReactNodeView();
11766
+ const Tag = props.as || 'div';
11767
+ return (React__default.createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
11768
+ whiteSpace: 'normal',
11769
+ ...props.style,
11770
+ } }));
11771
+ });
11772
+
11773
+ /**
11774
+ * Check if a component is a class component.
11775
+ * @param Component
11776
+ * @returns {boolean}
11777
+ */
11778
+ function isClassComponent(Component) {
11779
+ return !!(typeof Component === 'function'
11780
+ && Component.prototype
11781
+ && Component.prototype.isReactComponent);
11428
11782
  }
11783
+ /**
11784
+ * Check if a component is a forward ref component.
11785
+ * @param Component
11786
+ * @returns {boolean}
11787
+ */
11429
11788
  function isForwardRefComponent(Component) {
11430
11789
  var _a;
11431
11790
  return !!(typeof Component === 'object'
11432
11791
  && ((_a = Component.$$typeof) === null || _a === void 0 ? void 0 : _a.toString()) === 'Symbol(react.forward_ref)');
11433
11792
  }
11793
+ /**
11794
+ * The ReactRenderer class. It's responsible for rendering React components inside the editor.
11795
+ * @example
11796
+ * new ReactRenderer(MyComponent, {
11797
+ * editor,
11798
+ * props: {
11799
+ * foo: 'bar',
11800
+ * },
11801
+ * as: 'span',
11802
+ * })
11803
+ */
11434
11804
  class ReactRenderer {
11435
- constructor(component, { editor, props = {}, as = 'div', className = '', }) {
11805
+ constructor(component, { editor, props = {}, as = 'div', className = '', attrs, }) {
11436
11806
  this.ref = null;
11437
11807
  this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString();
11438
11808
  this.component = component;
@@ -11443,9 +11813,15 @@ class ReactRenderer {
11443
11813
  if (className) {
11444
11814
  this.element.classList.add(...className.split(' '));
11445
11815
  }
11816
+ if (attrs) {
11817
+ Object.keys(attrs).forEach(key => {
11818
+ this.element.setAttribute(key, attrs[key]);
11819
+ });
11820
+ }
11446
11821
  this.render();
11447
11822
  }
11448
11823
  render() {
11824
+ var _a, _b;
11449
11825
  const Component = this.component;
11450
11826
  const props = this.props;
11451
11827
  if (isClassComponent(Component) || isForwardRefComponent(Component)) {
@@ -11454,16 +11830,7 @@ class ReactRenderer {
11454
11830
  };
11455
11831
  }
11456
11832
  this.reactElement = React__default.createElement(Component, { ...props });
11457
- queueMicrotask(() => {
11458
- flushSync(() => {
11459
- var _a;
11460
- if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) {
11461
- this.editor.contentComponent.setState({
11462
- renderers: this.editor.contentComponent.state.renderers.set(this.id, this),
11463
- });
11464
- }
11465
- });
11466
- });
11833
+ (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.setRenderer(this.id, this);
11467
11834
  }
11468
11835
  updateProps(props = {}) {
11469
11836
  this.props = {
@@ -11473,18 +11840,8 @@ class ReactRenderer {
11473
11840
  this.render();
11474
11841
  }
11475
11842
  destroy() {
11476
- queueMicrotask(() => {
11477
- flushSync(() => {
11478
- var _a;
11479
- if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) {
11480
- const { renderers } = this.editor.contentComponent.state;
11481
- renderers.delete(this.id);
11482
- this.editor.contentComponent.setState({
11483
- renderers,
11484
- });
11485
- }
11486
- });
11487
- });
11843
+ var _a, _b;
11844
+ (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.removeRenderer(this.id);
11488
11845
  }
11489
11846
  }
11490
11847
 
@@ -11514,13 +11871,20 @@ class ReactNodeView extends NodeView {
11514
11871
  element.appendChild(this.contentDOMElement);
11515
11872
  }
11516
11873
  };
11517
- return (React__default.createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } },
11518
- React__default.createElement(Component, { ...componentProps })));
11874
+ return (React__default.createElement(React__default.Fragment, null,
11875
+ React__default.createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } },
11876
+ React__default.createElement(Component, { ...componentProps }))));
11519
11877
  };
11520
11878
  ReactNodeViewProvider.displayName = 'ReactNodeView';
11521
- this.contentDOMElement = this.node.isLeaf
11522
- ? null
11523
- : document.createElement(this.node.isInline ? 'span' : 'div');
11879
+ if (this.node.isLeaf) {
11880
+ this.contentDOMElement = null;
11881
+ }
11882
+ else if (this.options.contentDOMElementTag) {
11883
+ this.contentDOMElement = document.createElement(this.options.contentDOMElementTag);
11884
+ }
11885
+ else {
11886
+ this.contentDOMElement = document.createElement(this.node.isInline ? 'span' : 'div');
11887
+ }
11524
11888
  if (this.contentDOMElement) {
11525
11889
  // For some reason the whiteSpace prop is not inherited properly in Chrome and Safari
11526
11890
  // With this fix it seems to work fine
@@ -11532,11 +11896,14 @@ class ReactNodeView extends NodeView {
11532
11896
  as = this.options.as;
11533
11897
  }
11534
11898
  const { className = '' } = this.options;
11899
+ this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
11900
+ this.editor.on('selectionUpdate', this.handleSelectionUpdate);
11535
11901
  this.renderer = new ReactRenderer(ReactNodeViewProvider, {
11536
11902
  editor: this.editor,
11537
11903
  props,
11538
11904
  as,
11539
11905
  className: `node-${this.node.type.name} ${className}`.trim(),
11906
+ attrs: this.options.attrs,
11540
11907
  });
11541
11908
  }
11542
11909
  get dom() {
@@ -11553,6 +11920,21 @@ class ReactNodeView extends NodeView {
11553
11920
  }
11554
11921
  return this.contentDOMElement;
11555
11922
  }
11923
+ handleSelectionUpdate() {
11924
+ const { from, to } = this.editor.state.selection;
11925
+ if (from <= this.getPos() && to >= this.getPos() + this.node.nodeSize) {
11926
+ if (this.renderer.props.selected) {
11927
+ return;
11928
+ }
11929
+ this.selectNode();
11930
+ }
11931
+ else {
11932
+ if (!this.renderer.props.selected) {
11933
+ return;
11934
+ }
11935
+ this.deselectNode();
11936
+ }
11937
+ }
11556
11938
  update(node, decorations) {
11557
11939
  const updateProps = (props) => {
11558
11940
  this.renderer.updateProps(props);
@@ -11585,14 +11967,17 @@ class ReactNodeView extends NodeView {
11585
11967
  this.renderer.updateProps({
11586
11968
  selected: true,
11587
11969
  });
11970
+ this.renderer.element.classList.add('ProseMirror-selectednode');
11588
11971
  }
11589
11972
  deselectNode() {
11590
11973
  this.renderer.updateProps({
11591
11974
  selected: false,
11592
11975
  });
11976
+ this.renderer.element.classList.remove('ProseMirror-selectednode');
11593
11977
  }
11594
11978
  destroy() {
11595
11979
  this.renderer.destroy();
11980
+ this.editor.off('selectionUpdate', this.handleSelectionUpdate);
11596
11981
  this.contentDOMElement = null;
11597
11982
  }
11598
11983
  }
@@ -11608,34 +11993,6 @@ function ReactNodeViewRenderer(component, options) {
11608
11993
  };
11609
11994
  }
11610
11995
 
11611
- function useForceUpdate() {
11612
- const [, setValue] = useState(0);
11613
- return () => setValue(value => value + 1);
11614
- }
11615
- const useEditor = (options = {}, deps = []) => {
11616
- const [editor, setEditor] = useState(null);
11617
- const forceUpdate = useForceUpdate();
11618
- useEffect(() => {
11619
- let isMounted = true;
11620
- const instance = new Editor(options);
11621
- setEditor(instance);
11622
- instance.on('transaction', () => {
11623
- requestAnimationFrame(() => {
11624
- requestAnimationFrame(() => {
11625
- if (isMounted) {
11626
- forceUpdate();
11627
- }
11628
- });
11629
- });
11630
- });
11631
- return () => {
11632
- instance.destroy();
11633
- isMounted = false;
11634
- };
11635
- }, deps);
11636
- return editor;
11637
- };
11638
-
11639
11996
  var validateUrl = function validateUrl(url) {
11640
11997
  return url ? validateNeetoRecordUrl(url) || validateYouTubeUrl(url) || validateLoomUrl(url) || validateVimeoUrl(url) : false;
11641
11998
  };
@@ -11749,8 +12106,8 @@ var emojiPickerApi = {
11749
12106
  fetch: fetch
11750
12107
  };
11751
12108
 
11752
- function ownKeys$5(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11753
- function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12109
+ function ownKeys$7(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12110
+ function _objectSpread$7(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$7(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$7(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11754
12111
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn$1(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
11755
12112
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
11756
12113
  var EmojiPickerMenu = /*#__PURE__*/function (_React$Component) {
@@ -11802,7 +12159,7 @@ var EmojiPickerMenu = /*#__PURE__*/function (_React$Component) {
11802
12159
  return _createClass$1(EmojiPickerMenu, [{
11803
12160
  key: "componentDidMount",
11804
12161
  value: function componentDidMount() {
11805
- new Picker(_objectSpread$5(_objectSpread$5({}, this.props), {}, {
12162
+ new Picker(_objectSpread$7(_objectSpread$7({}, this.props), {}, {
11806
12163
  onEmojiSelect: this.handleSelect,
11807
12164
  style: {
11808
12165
  maxWidth: "100%"
@@ -11848,55 +12205,825 @@ var generateFocusProps = function generateFocusProps() {
11848
12205
  return highlight ? focusProps : {};
11849
12206
  };
11850
12207
 
11851
- function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11852
- function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11853
- var Progress = function Progress(_ref) {
11854
- var uppy = _ref.uppy,
11855
- pendingUploads = _ref.pendingUploads,
11856
- setPendingUploads = _ref.setPendingUploads;
11857
- var _useTranslation = useTranslation(),
11858
- t = _useTranslation.t;
11859
- var handleUploadProgress = function handleUploadProgress(file, progress) {
11860
- setPendingUploads(function (prevState) {
11861
- return prevState.map(function (uploadingFile) {
11862
- return _objectSpread$4(_objectSpread$4({}, uploadingFile), {}, {
11863
- progress: uploadingFile.filename !== file.name ? uploadingFile.progress : progress.progress
11864
- });
12208
+ var MenuButton = function MenuButton(_ref) {
12209
+ var icon = _ref.icon,
12210
+ command = _ref.command,
12211
+ optionName = _ref.optionName,
12212
+ highlight = _ref.highlight,
12213
+ disabled = _ref.disabled,
12214
+ label = _ref.label,
12215
+ editor = _ref.editor;
12216
+ return /*#__PURE__*/React__default.createElement(Button$1, _extends$1({
12217
+ disabled: disabled,
12218
+ icon: icon,
12219
+ className: "neeto-editor-fixed-menu__item",
12220
+ "data-cy": "neeto-editor-fixed-menu-".concat(optionName, "-option"),
12221
+ style: editor.isActive(optionName) ? "secondary" : "text",
12222
+ tabIndex: "-1",
12223
+ tooltipProps: {
12224
+ content: label,
12225
+ position: "bottom"
12226
+ },
12227
+ onClick: command
12228
+ }, generateFocusProps(highlight)));
12229
+ };
12230
+
12231
+ var MenuItem$3 = Dropdown$1.MenuItem;
12232
+ var SecondaryMenuTarget = function SecondaryMenuTarget(_ref) {
12233
+ var Icon = _ref.icon,
12234
+ label = _ref.label;
12235
+ return /*#__PURE__*/React__default.createElement(MenuItem$3.Button, null, /*#__PURE__*/React__default.createElement(Icon, null), " ", label);
12236
+ };
12237
+
12238
+ var EmojiOption = function EmojiOption(_ref) {
12239
+ var editor = _ref.editor,
12240
+ isActive = _ref.isActive,
12241
+ setActive = _ref.setActive,
12242
+ tooltipContent = _ref.tooltipContent,
12243
+ _ref$isSecondaryMenu = _ref.isSecondaryMenu,
12244
+ isSecondaryMenu = _ref$isSecondaryMenu === void 0 ? false : _ref$isSecondaryMenu,
12245
+ label = _ref.label;
12246
+ return /*#__PURE__*/React__default.createElement(Dropdown$1, {
12247
+ buttonStyle: "text",
12248
+ closeOnSelect: false,
12249
+ dropdownProps: {
12250
+ classNames: "neeto-editor-fixed-menu__emoji-dropdown"
12251
+ },
12252
+ icon: Smiley,
12253
+ isOpen: isActive,
12254
+ position: isSecondaryMenu ? "left-start" : "bottom-start",
12255
+ strategy: "fixed",
12256
+ buttonProps: {
12257
+ tabIndex: -1,
12258
+ tooltipProps: {
12259
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label,
12260
+ position: "bottom"
12261
+ },
12262
+ className: "neeto-editor-fixed-menu__item"
12263
+ },
12264
+ customTarget: isSecondaryMenu && /*#__PURE__*/React__default.createElement(SecondaryMenuTarget, {
12265
+ label: label,
12266
+ icon: Smiley
12267
+ }),
12268
+ onClose: function onClose() {
12269
+ return setActive(false);
12270
+ },
12271
+ onClick: function onClick(e) {
12272
+ setActive(function (active) {
12273
+ return !active;
11865
12274
  });
12275
+ isSecondaryMenu && e.stopPropagation();
12276
+ }
12277
+ }, /*#__PURE__*/React__default.createElement(EmojiPickerMenu, {
12278
+ editor: editor,
12279
+ setActive: setActive
12280
+ }));
12281
+ };
12282
+
12283
+ var Menu$4 = Dropdown$1.Menu,
12284
+ MenuItem$2 = Dropdown$1.MenuItem;
12285
+ var FontSizeOption = function FontSizeOption(_ref) {
12286
+ var editor = _ref.editor,
12287
+ tooltipContent = _ref.tooltipContent,
12288
+ label = _ref.label;
12289
+ var dropdownRef = useRef(null);
12290
+ var isActive = function isActive(level) {
12291
+ return editor.isActive("heading", {
12292
+ level: level
11866
12293
  });
11867
12294
  };
11868
- var removeUploadingFile = function removeUploadingFile(id) {
11869
- uppy.removeFile(id);
11870
- setPendingUploads(function (prevState) {
11871
- return removeById(id, prevState);
11872
- });
12295
+ var activeOption = FONT_SIZE_OPTIONS.find(function (_ref2) {
12296
+ var value = _ref2.value;
12297
+ return isActive(value);
12298
+ }) || last(FONT_SIZE_OPTIONS);
12299
+ var handleClick = function handleClick(level) {
12300
+ return level ? editor.chain().focus().toggleHeading({
12301
+ level: level
12302
+ }).run() : editor.chain().focus().setNode("paragraph").run();
11873
12303
  };
11874
- useEffect(function () {
11875
- uppy.on("upload-progress", handleUploadProgress);
11876
- return function () {
11877
- uppy.off("upload-progress", handleUploadProgress);
11878
- };
11879
- }, [uppy]);
11880
- return /*#__PURE__*/React__default.createElement("div", {
11881
- className: "ne-media-uploader__wrapper"
11882
- }, pendingUploads.map(function (_ref2) {
11883
- var id = _ref2.id,
11884
- filename = _ref2.filename,
11885
- progress = _ref2.progress;
11886
- return /*#__PURE__*/React__default.createElement("div", {
11887
- className: "ne-media-uploader__media",
11888
- key: id
11889
- }, /*#__PURE__*/React__default.createElement("div", {
11890
- className: "ne-media-uploader__media__info"
11891
- }, /*#__PURE__*/React__default.createElement(Typography, {
11892
- style: "body2"
11893
- }, filename), /*#__PURE__*/React__default.createElement(Button$1, {
11894
- "data-cy": "neeto-editor-image-upload-cancel-button",
11895
- icon: Close,
11896
- size: "small",
12304
+ return /*#__PURE__*/React__default.createElement(Dropdown$1, {
12305
+ autoWidth: true,
12306
+ "data-cy": "neeto-editor-fixed-menu-font-size-option",
12307
+ label: activeOption === null || activeOption === void 0 ? void 0 : activeOption.label,
12308
+ placement: "bottom-start",
12309
+ strategy: "fixed",
12310
+ buttonProps: {
12311
+ ref: dropdownRef,
12312
+ onKeyDown: function onKeyDown(event) {
12313
+ var _dropdownRef$current;
12314
+ return event.key === "ArrowDown" && ((_dropdownRef$current = dropdownRef.current) === null || _dropdownRef$current === void 0 ? void 0 : _dropdownRef$current.click());
12315
+ },
12316
+ tooltipProps: {
12317
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label,
12318
+ position: "bottom"
12319
+ },
11897
12320
  style: "text",
12321
+ size: "small",
12322
+ className: "neeto-editor-fixed-menu__item neeto-editor-font-size__wrapper"
12323
+ }
12324
+ }, /*#__PURE__*/React__default.createElement(Menu$4, {
12325
+ onKeyDown: function onKeyDown(event) {
12326
+ var _editor$commands;
12327
+ return event.key === "Escape" && ((_editor$commands = editor.commands) === null || _editor$commands === void 0 ? void 0 : _editor$commands.focus());
12328
+ }
12329
+ }, FONT_SIZE_OPTIONS.map(function (_ref3) {
12330
+ var label = _ref3.label,
12331
+ value = _ref3.value,
12332
+ key = _ref3.key;
12333
+ return /*#__PURE__*/React__default.createElement(MenuItem$2.Button, {
12334
+ "data-cy": "neeto-editor-fixed-menu-font-size-option-".concat(key),
12335
+ key: value,
11898
12336
  onClick: function onClick() {
11899
- return removeUploadingFile(id);
12337
+ return handleClick(value);
12338
+ }
12339
+ }, /*#__PURE__*/React__default.createElement(Typography, {
12340
+ style: key
12341
+ }, label));
12342
+ })));
12343
+ };
12344
+
12345
+ var Menu$3 = Dropdown$1.Menu;
12346
+ var TableOption$1 = function TableOption(_ref) {
12347
+ var editor = _ref.editor,
12348
+ tooltipContent = _ref.tooltipContent,
12349
+ _ref$isSecondaryMenu = _ref.isSecondaryMenu,
12350
+ isSecondaryMenu = _ref$isSecondaryMenu === void 0 ? false : _ref$isSecondaryMenu,
12351
+ label = _ref.label;
12352
+ var _useTranslation = useTranslation(),
12353
+ t = _useTranslation.t;
12354
+ var _useState = useState(false),
12355
+ _useState2 = _slicedToArray(_useState, 2),
12356
+ isOpen = _useState2[0],
12357
+ setIsOpen = _useState2[1];
12358
+ var _useState3 = useState(3),
12359
+ _useState4 = _slicedToArray(_useState3, 2),
12360
+ rows = _useState4[0],
12361
+ setRows = _useState4[1];
12362
+ var _useState5 = useState(3),
12363
+ _useState6 = _slicedToArray(_useState5, 2),
12364
+ columns = _useState6[0],
12365
+ setColumns = _useState6[1];
12366
+ var handleClose = function handleClose() {
12367
+ setRows(3);
12368
+ setColumns(3);
12369
+ setIsOpen(false);
12370
+ };
12371
+ var handleSubmit = function handleSubmit() {
12372
+ editor.chain().focus().insertTable({
12373
+ rows: rows,
12374
+ cols: columns,
12375
+ withHeaderRow: true
12376
+ }).run();
12377
+ handleClose();
12378
+ };
12379
+ var handleDropdownClick = function handleDropdownClick(e) {
12380
+ isSecondaryMenu && e.stopPropagation();
12381
+ setIsOpen(not);
12382
+ };
12383
+ return /*#__PURE__*/React__default.createElement(Dropdown$1, {
12384
+ isOpen: isOpen,
12385
+ buttonStyle: isOpen ? "secondary" : "text",
12386
+ closeOnSelect: false,
12387
+ "data-cy": "neeto-editor-fixed-menu-link-option",
12388
+ icon: Column,
12389
+ position: isSecondaryMenu ? "left-start" : "bottom",
12390
+ buttonProps: {
12391
+ tabIndex: -1,
12392
+ tooltipProps: {
12393
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label,
12394
+ position: "bottom"
12395
+ },
12396
+ className: "neeto-editor-fixed-menu__item"
12397
+ },
12398
+ customTarget: isSecondaryMenu && /*#__PURE__*/React__default.createElement(SecondaryMenuTarget, {
12399
+ label: label,
12400
+ icon: Column
12401
+ }),
12402
+ onClick: handleDropdownClick,
12403
+ onClose: handleClose
12404
+ }, /*#__PURE__*/React__default.createElement(Menu$3, {
12405
+ className: "neeto-editor-table__item"
12406
+ }, /*#__PURE__*/React__default.createElement(Input, {
12407
+ autoFocus: true,
12408
+ "data-cy": "neeto-editor-fixed-menu-table-option-input",
12409
+ min: "1",
12410
+ placeholder: t("neetoEditor.placeholders.rows"),
12411
+ size: "small",
12412
+ type: "number",
12413
+ value: rows,
12414
+ onChange: withEventTargetValue(setRows)
12415
+ }), /*#__PURE__*/React__default.createElement(Input, {
12416
+ "data-cy": "neeto-editor-fixed-menu-table-option-input",
12417
+ min: "1",
12418
+ placeholder: t("neetoEditor.placeholders.rows"),
12419
+ size: "small",
12420
+ type: "number",
12421
+ value: columns,
12422
+ onChange: withEventTargetValue(setColumns)
12423
+ }), /*#__PURE__*/React__default.createElement(Button$1, {
12424
+ "data-cy": "neeto-editor-fixed-menu-table-option-create-button",
12425
+ label: t("neetoEditor.common.create"),
12426
+ size: "small",
12427
+ onClick: handleSubmit
12428
+ })));
12429
+ };
12430
+
12431
+ var TextColorOption = function TextColorOption(_ref) {
12432
+ var editor = _ref.editor,
12433
+ tooltipContent = _ref.tooltipContent,
12434
+ _ref$isSecondaryMenu = _ref.isSecondaryMenu,
12435
+ isSecondaryMenu = _ref$isSecondaryMenu === void 0 ? false : _ref$isSecondaryMenu,
12436
+ label = _ref.label;
12437
+ var _useState = useState(false),
12438
+ _useState2 = _slicedToArray(_useState, 2),
12439
+ isOpen = _useState2[0],
12440
+ setIsOpen = _useState2[1];
12441
+ var _useState3 = useState(null),
12442
+ _useState4 = _slicedToArray(_useState3, 2),
12443
+ color = _useState4[0],
12444
+ setColor = _useState4[1];
12445
+ var dropdownWrapperRef = useRef(null);
12446
+ var _useTranslation = useTranslation(),
12447
+ t = _useTranslation.t;
12448
+ var handleSave = function handleSave() {
12449
+ editor.chain().focus().setColor(color).run();
12450
+ setIsOpen(false);
12451
+ };
12452
+ var handleUnset = function handleUnset() {
12453
+ editor.chain().focus().unsetColor().run();
12454
+ setColor(null);
12455
+ setIsOpen(false);
12456
+ };
12457
+ useOnClickOutside(dropdownWrapperRef, function (event) {
12458
+ if (!isOpen) return;
12459
+ event.preventDefault();
12460
+ editor.commands.focus();
12461
+ setIsOpen(false);
12462
+ });
12463
+ useEffect(function () {
12464
+ setColor(editor.getAttributes("textStyle").color);
12465
+ }, [isOpen, editor.getAttributes("textStyle").color]);
12466
+ var openColorPicker = function openColorPicker(e) {
12467
+ isSecondaryMenu && e.stopPropagation();
12468
+ setColor(editor.getAttributes("textStyle").color);
12469
+ setIsOpen(not);
12470
+ };
12471
+ return /*#__PURE__*/React__default.createElement(Dropdown$1, {
12472
+ isOpen: isOpen,
12473
+ buttonStyle: isOpen || color ? "secondary" : "text",
12474
+ icon: Customize,
12475
+ position: isSecondaryMenu ? "left-start" : "bottom-start",
12476
+ buttonProps: {
12477
+ tabIndex: -1,
12478
+ tooltipProps: {
12479
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label
12480
+ },
12481
+ className: "neeto-editor-fixed-menu__item neeto-editor-text-color-option"
12482
+ },
12483
+ customTarget: isSecondaryMenu && /*#__PURE__*/React__default.createElement(SecondaryMenuTarget, {
12484
+ label: label,
12485
+ icon: Customize
12486
+ }),
12487
+ onClick: openColorPicker
12488
+ }, /*#__PURE__*/React__default.createElement("div", {
12489
+ ref: dropdownWrapperRef,
12490
+ style: {
12491
+ "min-width": "236px"
12492
+ },
12493
+ onClick: function onClick(e) {
12494
+ e.stopPropagation();
12495
+ }
12496
+ }, /*#__PURE__*/React__default.createElement(HexColorPicker, {
12497
+ color: color || "#000000",
12498
+ onChange: setColor
12499
+ }), /*#__PURE__*/React__default.createElement("div", {
12500
+ className: "neeto-editor-text-color-option__options-group"
12501
+ }, /*#__PURE__*/React__default.createElement(Input, {
12502
+ autoFocus: true,
12503
+ className: "neeto-editor-text-color-option__options-group__input",
12504
+ placeholder: t("neetoEditor.placeholders.pickColor"),
12505
+ size: "small",
12506
+ value: color,
12507
+ onChange: withEventTargetValue(setColor),
12508
+ onClick: function onClick(event) {
12509
+ return event.stopPropagation();
12510
+ }
12511
+ }), /*#__PURE__*/React__default.createElement(Button$1, {
12512
+ icon: Check,
12513
+ size: "small",
12514
+ onClick: handleSave
12515
+ }), /*#__PURE__*/React__default.createElement(Button$1, {
12516
+ icon: Close,
12517
+ size: "small",
12518
+ style: "text",
12519
+ onClick: function onClick() {
12520
+ editor.commands.focus();
12521
+ setIsOpen(false);
12522
+ }
12523
+ }), /*#__PURE__*/React__default.createElement(Button$1, {
12524
+ icon: Refresh,
12525
+ size: "small",
12526
+ style: "text",
12527
+ tooltipProps: {
12528
+ content: t("neetoEditor.common.resetToDefault"),
12529
+ position: "top"
12530
+ },
12531
+ onClick: handleUnset
12532
+ }))));
12533
+ };
12534
+
12535
+ var Menu$2 = Dropdown$1.Menu,
12536
+ MenuItem$1 = Dropdown$1.MenuItem;
12537
+ var Mentions = function Mentions(_ref) {
12538
+ var editor = _ref.editor,
12539
+ mentions = _ref.mentions,
12540
+ tooltipContent = _ref.tooltipContent,
12541
+ _ref$isSecondaryMenu = _ref.isSecondaryMenu,
12542
+ isSecondaryMenu = _ref$isSecondaryMenu === void 0 ? false : _ref$isSecondaryMenu,
12543
+ label = _ref.label;
12544
+ if (isEmpty(mentions)) return null;
12545
+ return /*#__PURE__*/React__default.createElement(Dropdown$1, {
12546
+ buttonStyle: "text",
12547
+ "data-cy": "neeto-editor-mention-option",
12548
+ icon: Email,
12549
+ position: isSecondaryMenu ? "left-start" : "bottom-start",
12550
+ strategy: "fixed",
12551
+ buttonProps: {
12552
+ tooltipProps: {
12553
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label,
12554
+ position: "bottom"
12555
+ },
12556
+ className: "neeto-editor-fixed-menu__item"
12557
+ },
12558
+ customTarget: isSecondaryMenu && /*#__PURE__*/React__default.createElement(SecondaryMenuTarget, {
12559
+ label: label,
12560
+ icon: Email
12561
+ }),
12562
+ onClick: function onClick(e) {
12563
+ return isSecondaryMenu && e.stopPropagation();
12564
+ }
12565
+ }, /*#__PURE__*/React__default.createElement(Menu$2, null, mentions.map(function (_ref2) {
12566
+ var key = _ref2.key,
12567
+ name = _ref2.name,
12568
+ imageUrl = _ref2.imageUrl;
12569
+ return /*#__PURE__*/React__default.createElement(MenuItem$1.Button, {
12570
+ "data-cy": "neeto-editor-mention-option-".concat(key),
12571
+ key: key,
12572
+ onClick: function onClick() {
12573
+ return editor.commands.setMention({
12574
+ id: key,
12575
+ label: name
12576
+ });
12577
+ }
12578
+ }, /*#__PURE__*/React__default.createElement(Avatar, {
12579
+ size: "small",
12580
+ user: {
12581
+ name: name,
12582
+ imageUrl: imageUrl
12583
+ }
12584
+ }), /*#__PURE__*/React__default.createElement(Typography, {
12585
+ style: "body2"
12586
+ }, name));
12587
+ })));
12588
+ };
12589
+
12590
+ var FONT_SIZE_OPTIONS = [{
12591
+ label: t$1("neetoEditor.menu.heading1"),
12592
+ value: 1,
12593
+ key: "h1"
12594
+ }, {
12595
+ label: t$1("neetoEditor.menu.heading2"),
12596
+ value: 2,
12597
+ key: "h2"
12598
+ }, {
12599
+ label: t$1("neetoEditor.menu.heading3"),
12600
+ value: 3,
12601
+ key: "h3"
12602
+ }, {
12603
+ label: t$1("neetoEditor.menu.heading4"),
12604
+ value: 4,
12605
+ key: "h4"
12606
+ }, {
12607
+ label: t$1("neetoEditor.menu.heading5"),
12608
+ value: 5,
12609
+ key: "h5"
12610
+ }, {
12611
+ label: t$1("neetoEditor.menu.normalText"),
12612
+ value: 0,
12613
+ key: "body2"
12614
+ }];
12615
+ var MENU_ELEMENT_TYPES = {
12616
+ BUTTON: "button",
12617
+ FONT_SIZE: "fontSize",
12618
+ TABLE: "table",
12619
+ TEXT_COLOR: "textColor",
12620
+ EMOJI: "emoji",
12621
+ MENTIONS: "mentions"
12622
+ };
12623
+ var MENU_ELEMENTS = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, MENU_ELEMENT_TYPES.BUTTON, MenuButton), MENU_ELEMENT_TYPES.FONT_SIZE, FontSizeOption), MENU_ELEMENT_TYPES.TABLE, TableOption$1), MENU_ELEMENT_TYPES.TEXT_COLOR, TextColorOption), MENU_ELEMENT_TYPES.EMOJI, EmojiOption), MENU_ELEMENT_TYPES.MENTIONS, Mentions);
12624
+ var MENU_ELEMENT_WIDTHS = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, MENU_ELEMENT_TYPES.BUTTON, 36), MENU_ELEMENT_TYPES.FONT_SIZE, 103), MENU_ELEMENT_TYPES.TABLE, 36), MENU_ELEMENT_TYPES.TEXT_COLOR, 36), MENU_ELEMENT_TYPES.EMOJI, 36), MENU_ELEMENT_TYPES.MENTIONS, 36);
12625
+
12626
+ function ownKeys$6(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12627
+ function _objectSpread$6(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$6(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$6(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12628
+ var createMenuOptions$2 = function createMenuOptions(_ref) {
12629
+ var _tooltips$undo, _tooltips$redo, _tooltips$fontSize, _tooltips$bold, _tooltips$italic, _tooltips$underline, _tooltips$link, _tooltips$strike, _tooltips$highlight, _tooltips$bulletList, _tooltips$orderedList, _tooltips$blockQuote, _tooltips$code, _tooltips$codeBlock, _tooltips$table, _tooltips$attachments, _tooltips$imageUpload, _tooltips$videoUpload, _tooltips$videoEmbed, _tooltips$textColor, _tooltips$emoji, _tooltips$mention;
12630
+ var tooltips = _ref.tooltips,
12631
+ editor = _ref.editor,
12632
+ setMediaUploader = _ref.setMediaUploader,
12633
+ attachmentProps = _ref.attachmentProps,
12634
+ setIsEmbedModalOpen = _ref.setIsEmbedModalOpen,
12635
+ setIsAddLinkActive = _ref.setIsAddLinkActive,
12636
+ options = _ref.options,
12637
+ mentions = _ref.mentions,
12638
+ addonCommandOptions = _ref.addonCommandOptions,
12639
+ setIsEmojiPickerActive = _ref.setIsEmojiPickerActive,
12640
+ isEmojiPickerActive = _ref.isEmojiPickerActive;
12641
+ var fontSizeOptions = options.filter(function (option) {
12642
+ return option.match(/^h[1-6]$/);
12643
+ });
12644
+ return [
12645
+ // history
12646
+ [{
12647
+ icon: Undo,
12648
+ command: function command() {
12649
+ return editor.chain().focus().undo().run();
12650
+ },
12651
+ isEnabled: options.includes(EDITOR_OPTIONS.UNDO),
12652
+ disabled: !editor.can().undo(),
12653
+ optionName: EDITOR_OPTIONS.UNDO,
12654
+ label: (_tooltips$undo = tooltips.undo) !== null && _tooltips$undo !== void 0 ? _tooltips$undo : t$1("neetoEditor.menu.undo"),
12655
+ type: MENU_ELEMENT_TYPES.BUTTON
12656
+ }, {
12657
+ icon: Redo,
12658
+ command: function command() {
12659
+ return editor.chain().focus().redo().run();
12660
+ },
12661
+ isEnabled: options.includes(EDITOR_OPTIONS.REDO),
12662
+ disabled: !editor.can().redo(),
12663
+ optionName: EDITOR_OPTIONS.REDO,
12664
+ label: (_tooltips$redo = tooltips.redo) !== null && _tooltips$redo !== void 0 ? _tooltips$redo : t$1("neetoEditor.menu.redo"),
12665
+ type: MENU_ELEMENT_TYPES.BUTTON
12666
+ }],
12667
+ // font
12668
+ [{
12669
+ type: MENU_ELEMENT_TYPES.FONT_SIZE,
12670
+ options: fontSizeOptions,
12671
+ label: (_tooltips$fontSize = tooltips.fontSize) !== null && _tooltips$fontSize !== void 0 ? _tooltips$fontSize : t$1("neetoEditor.menu.fontSize"),
12672
+ isEnabled: isNotEmpty(fontSizeOptions),
12673
+ optionName: "fontSizeOptions"
12674
+ }, {
12675
+ type: MENU_ELEMENT_TYPES.BUTTON,
12676
+ icon: TextBold,
12677
+ isEnabled: options.includes(EDITOR_OPTIONS.BOLD),
12678
+ command: function command() {
12679
+ return editor.chain().focus().toggleBold().run();
12680
+ },
12681
+ optionName: EDITOR_OPTIONS.BOLD,
12682
+ label: (_tooltips$bold = tooltips.bold) !== null && _tooltips$bold !== void 0 ? _tooltips$bold : t$1("neetoEditor.menu.bold")
12683
+ }, {
12684
+ type: MENU_ELEMENT_TYPES.BUTTON,
12685
+ icon: TextItalic,
12686
+ isEnabled: options.includes(EDITOR_OPTIONS.ITALIC),
12687
+ command: function command() {
12688
+ return editor.chain().focus().toggleItalic().run();
12689
+ },
12690
+ optionName: EDITOR_OPTIONS.ITALIC,
12691
+ label: (_tooltips$italic = tooltips.italic) !== null && _tooltips$italic !== void 0 ? _tooltips$italic : t$1("neetoEditor.menu.italic")
12692
+ }, {
12693
+ type: MENU_ELEMENT_TYPES.BUTTON,
12694
+ icon: Underline,
12695
+ isEnabled: options.includes(EDITOR_OPTIONS.UNDERLINE),
12696
+ command: function command() {
12697
+ return editor.chain().focus().toggleUnderline().run();
12698
+ },
12699
+ optionName: EDITOR_OPTIONS.UNDERLINE,
12700
+ label: (_tooltips$underline = tooltips.underline) !== null && _tooltips$underline !== void 0 ? _tooltips$underline : t$1("neetoEditor.menu.underline")
12701
+ }, {
12702
+ type: MENU_ELEMENT_TYPES.BUTTON,
12703
+ icon: Link,
12704
+ isEnabled: options.includes(EDITOR_OPTIONS.LINK),
12705
+ command: function command() {
12706
+ return setIsAddLinkActive(not);
12707
+ },
12708
+ optionName: EDITOR_OPTIONS.LINK,
12709
+ label: (_tooltips$link = tooltips.link) !== null && _tooltips$link !== void 0 ? _tooltips$link : t$1("neetoEditor.menu.link")
12710
+ }, {
12711
+ type: MENU_ELEMENT_TYPES.BUTTON,
12712
+ icon: TextCross,
12713
+ isEnabled: options.includes(EDITOR_OPTIONS.STRIKETHROUGH),
12714
+ command: function command() {
12715
+ return editor.chain().focus().toggleStrike().run();
12716
+ },
12717
+ optionName: EDITOR_OPTIONS.STRIKETHROUGH,
12718
+ label: (_tooltips$strike = tooltips.strike) !== null && _tooltips$strike !== void 0 ? _tooltips$strike : t$1("neetoEditor.menu.strike")
12719
+ }, {
12720
+ type: MENU_ELEMENT_TYPES.BUTTON,
12721
+ icon: Highlight,
12722
+ isEnabled: options.includes(EDITOR_OPTIONS.HIGHLIGHT),
12723
+ command: function command() {
12724
+ return editor.chain().focus().toggleHighlight().run();
12725
+ },
12726
+ optionName: EDITOR_OPTIONS.HIGHLIGHT,
12727
+ label: (_tooltips$highlight = tooltips.highlight) !== null && _tooltips$highlight !== void 0 ? _tooltips$highlight : t$1("neetoEditor.menu.highlight")
12728
+ }],
12729
+ // list
12730
+ [{
12731
+ type: MENU_ELEMENT_TYPES.BUTTON,
12732
+ icon: ListDot,
12733
+ command: function command() {
12734
+ return editor.chain().focus().toggleBulletList().run();
12735
+ },
12736
+ isEnabled: options.includes(EDITOR_OPTIONS.LIST_BULLETS),
12737
+ optionName: "bulletList",
12738
+ highlight: true,
12739
+ label: (_tooltips$bulletList = tooltips.bulletList) !== null && _tooltips$bulletList !== void 0 ? _tooltips$bulletList : t$1("neetoEditor.menu.bulletedList")
12740
+ }, {
12741
+ type: MENU_ELEMENT_TYPES.BUTTON,
12742
+ icon: ListNumber,
12743
+ command: function command() {
12744
+ return editor.chain().focus().toggleOrderedList().run();
12745
+ },
12746
+ isEnabled: options.includes(EDITOR_OPTIONS.LIST_ORDERED),
12747
+ optionName: "orderedList",
12748
+ highlight: true,
12749
+ label: (_tooltips$orderedList = tooltips.orderedList) !== null && _tooltips$orderedList !== void 0 ? _tooltips$orderedList : t$1("neetoEditor.menu.orderedList")
12750
+ }],
12751
+ // block
12752
+ [{
12753
+ type: MENU_ELEMENT_TYPES.BUTTON,
12754
+ icon: Quote,
12755
+ command: function command() {
12756
+ return editor.chain().focus().toggleBlockquote().run();
12757
+ },
12758
+ isEnabled: options.includes(EDITOR_OPTIONS.BLOCKQUOTE),
12759
+ optionName: "blockquote",
12760
+ highlight: true,
12761
+ label: (_tooltips$blockQuote = tooltips.blockQuote) !== null && _tooltips$blockQuote !== void 0 ? _tooltips$blockQuote : t$1("neetoEditor.menu.blockQuote")
12762
+ }, {
12763
+ type: MENU_ELEMENT_TYPES.BUTTON,
12764
+ icon: Code,
12765
+ command: function command() {
12766
+ return editor.chain().focus().toggleCode().run();
12767
+ },
12768
+ isEnabled: options.includes(EDITOR_OPTIONS.CODE),
12769
+ optionName: EDITOR_OPTIONS.CODE,
12770
+ label: (_tooltips$code = tooltips.code) !== null && _tooltips$code !== void 0 ? _tooltips$code : t$1("neetoEditor.menu.code")
12771
+ }, {
12772
+ type: MENU_ELEMENT_TYPES.BUTTON,
12773
+ icon: CodeBlock,
12774
+ command: function command() {
12775
+ return editor.chain().focus().toggleCodeBlock().run();
12776
+ },
12777
+ isEnabled: options.includes(EDITOR_OPTIONS.CODE_BLOCK),
12778
+ optionName: "codeBlock",
12779
+ label: (_tooltips$codeBlock = tooltips.codeBlock) !== null && _tooltips$codeBlock !== void 0 ? _tooltips$codeBlock : t$1("neetoEditor.menu.codeBlock")
12780
+ }],
12781
+ // misc
12782
+ [{
12783
+ type: MENU_ELEMENT_TYPES.TABLE,
12784
+ label: (_tooltips$table = tooltips.table) !== null && _tooltips$table !== void 0 ? _tooltips$table : t$1("neetoEditor.menu.table"),
12785
+ isEnabled: options.includes(EDITOR_OPTIONS.TABLE),
12786
+ optionName: EDITOR_OPTIONS.TABLE
12787
+ }, {
12788
+ type: MENU_ELEMENT_TYPES.BUTTON,
12789
+ icon: Attachment,
12790
+ command: function command() {
12791
+ return attachmentProps === null || attachmentProps === void 0 ? void 0 : attachmentProps.handleUploadAttachments();
12792
+ },
12793
+ disabled: attachmentProps === null || attachmentProps === void 0 ? void 0 : attachmentProps.isDisabled,
12794
+ isEnabled: options.includes(EDITOR_OPTIONS.ATTACHMENTS),
12795
+ optionName: EDITOR_OPTIONS.ATTACHMENTS,
12796
+ label: (_tooltips$attachments = tooltips.attachments) !== null && _tooltips$attachments !== void 0 ? _tooltips$attachments : t$1("neetoEditor.menu.attachments")
12797
+ }, {
12798
+ type: MENU_ELEMENT_TYPES.BUTTON,
12799
+ icon: ImageUpload,
12800
+ command: function command() {
12801
+ return setMediaUploader(assoc("image", true));
12802
+ },
12803
+ isEnabled: options.includes(EDITOR_OPTIONS.IMAGE_UPLOAD),
12804
+ optionName: EDITOR_OPTIONS.IMAGE_UPLOAD,
12805
+ label: (_tooltips$imageUpload = tooltips.imageUpload) !== null && _tooltips$imageUpload !== void 0 ? _tooltips$imageUpload : t$1("neetoEditor.menu.imageUpload")
12806
+ }, {
12807
+ type: MENU_ELEMENT_TYPES.BUTTON,
12808
+ icon: Video,
12809
+ command: function command() {
12810
+ return setMediaUploader(assoc("video", true));
12811
+ },
12812
+ isEnabled: options.includes(EDITOR_OPTIONS.VIDEO_UPLOAD),
12813
+ optionName: EDITOR_OPTIONS.VIDEO_UPLOAD,
12814
+ label: (_tooltips$videoUpload = tooltips.videoUpload) !== null && _tooltips$videoUpload !== void 0 ? _tooltips$videoUpload : t$1("neetoEditor.menu.videoUpload")
12815
+ }, {
12816
+ type: MENU_ELEMENT_TYPES.BUTTON,
12817
+ icon: MediaVideo,
12818
+ command: function command() {
12819
+ return setIsEmbedModalOpen(true);
12820
+ },
12821
+ isEnabled: options.includes(EDITOR_OPTIONS.VIDEO_EMBED),
12822
+ optionName: EDITOR_OPTIONS.VIDEO_EMBED,
12823
+ label: (_tooltips$videoEmbed = tooltips.videoEmbed) !== null && _tooltips$videoEmbed !== void 0 ? _tooltips$videoEmbed : t$1("neetoEditor.menu.videoEmbed")
12824
+ }],
12825
+ // extras
12826
+ [{
12827
+ type: MENU_ELEMENT_TYPES.TEXT_COLOR,
12828
+ label: (_tooltips$textColor = tooltips.textColor) !== null && _tooltips$textColor !== void 0 ? _tooltips$textColor : t$1("neetoEditor.menu.textColor"),
12829
+ isEnabled: options.includes(EDITOR_OPTIONS.TEXT_COLOR),
12830
+ optionName: EDITOR_OPTIONS.TEXT_COLOR
12831
+ }, {
12832
+ type: MENU_ELEMENT_TYPES.EMOJI,
12833
+ label: (_tooltips$emoji = tooltips.emoji) !== null && _tooltips$emoji !== void 0 ? _tooltips$emoji : t$1("neetoEditor.menu.emoji"),
12834
+ isEnabled: options.includes(EDITOR_OPTIONS.EMOJI),
12835
+ optionName: EDITOR_OPTIONS.EMOJI,
12836
+ setActive: setIsEmojiPickerActive,
12837
+ isActive: isEmojiPickerActive
12838
+ }, {
12839
+ type: MENU_ELEMENT_TYPES.MENTIONS,
12840
+ label: (_tooltips$mention = tooltips.mention) !== null && _tooltips$mention !== void 0 ? _tooltips$mention : t$1("neetoEditor.menu.mention"),
12841
+ isEnabled: isNotEmpty(mentions),
12842
+ optionName: "mentions",
12843
+ mentions: mentions
12844
+ }], //addons
12845
+ _toConsumableArray(addonCommandOptions)];
12846
+ };
12847
+ var buildMenuOptions$1 = function buildMenuOptions(_ref2) {
12848
+ var tooltips = _ref2.tooltips,
12849
+ editor = _ref2.editor,
12850
+ options = _ref2.options,
12851
+ setMediaUploader = _ref2.setMediaUploader,
12852
+ attachmentProps = _ref2.attachmentProps,
12853
+ setIsEmbedModalOpen = _ref2.setIsEmbedModalOpen,
12854
+ setIsAddLinkActive = _ref2.setIsAddLinkActive,
12855
+ mentions = _ref2.mentions,
12856
+ addonCommands = _ref2.addonCommands,
12857
+ setIsEmojiPickerActive = _ref2.setIsEmojiPickerActive,
12858
+ isEmojiPickerActive = _ref2.isEmojiPickerActive;
12859
+ if (!editor) return [];
12860
+ var addonCommandOptions = buildOptionsFromAddonCommands({
12861
+ editor: editor,
12862
+ commands: addonCommands
12863
+ });
12864
+ var menuOptions = createMenuOptions$2({
12865
+ tooltips: tooltips,
12866
+ editor: editor,
12867
+ setMediaUploader: setMediaUploader,
12868
+ attachmentProps: attachmentProps,
12869
+ setIsEmbedModalOpen: setIsEmbedModalOpen,
12870
+ setIsAddLinkActive: setIsAddLinkActive,
12871
+ options: options,
12872
+ mentions: mentions,
12873
+ addonCommandOptions: addonCommandOptions,
12874
+ setIsEmojiPickerActive: setIsEmojiPickerActive,
12875
+ isEmojiPickerActive: isEmojiPickerActive
12876
+ });
12877
+ return menuOptions.map(function (option) {
12878
+ return option.filter(prop("isEnabled"));
12879
+ });
12880
+ };
12881
+ var buildOptionsFromAddonCommands = function buildOptionsFromAddonCommands(_ref3) {
12882
+ var editor = _ref3.editor,
12883
+ commands = _ref3.commands;
12884
+ var to = editor.state.selection.to;
12885
+ return commands.map(function (option) {
12886
+ var _option$active;
12887
+ return _objectSpread$6(_objectSpread$6({}, option), {}, {
12888
+ type: MENU_ELEMENT_TYPES.BUTTON,
12889
+ active: (_option$active = option.active) === null || _option$active === void 0 ? void 0 : _option$active.call(option, {
12890
+ editor: editor
12891
+ }),
12892
+ command: function command() {
12893
+ var _option$command;
12894
+ return (_option$command = option.command) === null || _option$command === void 0 ? void 0 : _option$command.call(option, {
12895
+ editor: editor,
12896
+ range: {
12897
+ from: to,
12898
+ to: to
12899
+ }
12900
+ });
12901
+ }
12902
+ });
12903
+ });
12904
+ };
12905
+ var getCursorPos = function getCursorPos(editor, to) {
12906
+ return editor === null || editor === void 0 ? void 0 : editor.view.coordsAtPos(to);
12907
+ };
12908
+ var reGroupMenuItems = function reGroupMenuItems(menuRef, menuGroups) {
12909
+ var toolbarWidth = menuRef.current.offsetWidth;
12910
+ var totalWidth = 0;
12911
+ var visibleMenuGroups = [];
12912
+ var invisibleMenuGroups = [];
12913
+ menuGroups.forEach(function (group, groupIndex) {
12914
+ group.forEach(function (item, itemIndex) {
12915
+ var width = MENU_ELEMENT_WIDTHS[item.type];
12916
+ if (totalWidth + width < toolbarWidth) {
12917
+ var _visibleMenuGroups$gr;
12918
+ totalWidth += width;
12919
+ visibleMenuGroups[groupIndex] = (_visibleMenuGroups$gr = visibleMenuGroups[groupIndex]) !== null && _visibleMenuGroups$gr !== void 0 ? _visibleMenuGroups$gr : [];
12920
+ visibleMenuGroups[groupIndex][itemIndex] = item;
12921
+ } else {
12922
+ var _invisibleMenuGroups$;
12923
+ var visibleMenuGroupsLength = visibleMenuGroups.length;
12924
+ var index = groupIndex - visibleMenuGroupsLength + 1;
12925
+ invisibleMenuGroups[index] = (_invisibleMenuGroups$ = invisibleMenuGroups[index]) !== null && _invisibleMenuGroups$ !== void 0 ? _invisibleMenuGroups$ : [];
12926
+ invisibleMenuGroups[index][itemIndex] = item;
12927
+ }
12928
+ });
12929
+ });
12930
+ return {
12931
+ visibleMenuGroups: visibleMenuGroups,
12932
+ invisibleMenuGroups: invisibleMenuGroups
12933
+ };
12934
+ };
12935
+ var getLinkPopoverPosition = function getLinkPopoverPosition(editor, popoverRef) {
12936
+ var _editor$view$state$se = editor.view.state.selection,
12937
+ selectionEnd = _editor$view$state$se.$to.pos,
12938
+ selectionStart = _editor$view$state$se.$from.pos;
12939
+ var selectionLength = selectionEnd - selectionStart;
12940
+ var offset = 0;
12941
+ if (selectionLength > 1) offset = Math.round(selectionLength / 2);
12942
+ if (selectionLength === 1) offset = 1;
12943
+
12944
+ // Calculate the arrow position
12945
+ var arrowCoords = editor.view.coordsAtPos(selectionStart + offset);
12946
+ var arrowPosition = {
12947
+ top: "".concat(arrowCoords.top + 21, "px"),
12948
+ left: "".concat(arrowCoords.left - 8.5, "px")
12949
+ };
12950
+
12951
+ // Calculate the popover position
12952
+ var popoverCoords = editor.view.coordsAtPos(selectionStart);
12953
+ var adjustedLeft = popoverCoords === null || popoverCoords === void 0 ? void 0 : popoverCoords.left,
12954
+ adjustedTop = popoverCoords === null || popoverCoords === void 0 ? void 0 : popoverCoords.top;
12955
+ if (popoverRef !== null && popoverRef !== void 0 && popoverRef.current) {
12956
+ var _popoverRef$current;
12957
+ var popoverRect = (_popoverRef$current = popoverRef.current) === null || _popoverRef$current === void 0 ? void 0 : _popoverRef$current.getBoundingClientRect();
12958
+ var screenWidth = window.innerWidth;
12959
+ var screenHeight = window.innerHeight;
12960
+ var maxLeft = screenWidth - popoverRect.width;
12961
+ var maxTop = screenHeight - popoverRect.height - 50;
12962
+ adjustedLeft = popoverCoords !== null && popoverCoords !== void 0 && popoverCoords.left ? Math.min(popoverCoords.left - 50, maxLeft) : 0;
12963
+ adjustedTop = popoverCoords !== null && popoverCoords !== void 0 && popoverCoords.top ? Math.min(popoverCoords.top - 22, maxTop) : 0;
12964
+ } else {
12965
+ adjustedLeft = popoverCoords.left - 50;
12966
+ adjustedTop = popoverCoords.top - 22;
12967
+ }
12968
+ var popoverPosition = {
12969
+ top: "".concat(adjustedTop, "px"),
12970
+ left: "".concat(adjustedLeft, "px")
12971
+ };
12972
+ return {
12973
+ arrowPosition: arrowPosition,
12974
+ popoverPosition: popoverPosition
12975
+ };
12976
+ };
12977
+
12978
+ function ownKeys$5(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12979
+ function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12980
+ var Progress = function Progress(_ref) {
12981
+ var uppy = _ref.uppy,
12982
+ pendingUploads = _ref.pendingUploads,
12983
+ setPendingUploads = _ref.setPendingUploads;
12984
+ var _useTranslation = useTranslation(),
12985
+ t = _useTranslation.t;
12986
+ var handleUploadProgress = function handleUploadProgress(file, progress) {
12987
+ setPendingUploads(function (prevState) {
12988
+ return prevState.map(function (uploadingFile) {
12989
+ return _objectSpread$5(_objectSpread$5({}, uploadingFile), {}, {
12990
+ progress: uploadingFile.filename !== file.name ? uploadingFile.progress : progress.progress
12991
+ });
12992
+ });
12993
+ });
12994
+ };
12995
+ var removeUploadingFile = function removeUploadingFile(id) {
12996
+ uppy.removeFile(id);
12997
+ setPendingUploads(function (prevState) {
12998
+ return removeById(id, prevState);
12999
+ });
13000
+ };
13001
+ useEffect(function () {
13002
+ uppy.on("upload-progress", handleUploadProgress);
13003
+ return function () {
13004
+ uppy.off("upload-progress", handleUploadProgress);
13005
+ };
13006
+ }, [uppy]);
13007
+ return /*#__PURE__*/React__default.createElement("div", {
13008
+ className: "ne-media-uploader__wrapper"
13009
+ }, pendingUploads.map(function (_ref2) {
13010
+ var id = _ref2.id,
13011
+ filename = _ref2.filename,
13012
+ progress = _ref2.progress;
13013
+ return /*#__PURE__*/React__default.createElement("div", {
13014
+ className: "ne-media-uploader__media",
13015
+ key: id
13016
+ }, /*#__PURE__*/React__default.createElement("div", {
13017
+ className: "ne-media-uploader__media__info"
13018
+ }, /*#__PURE__*/React__default.createElement(Typography, {
13019
+ style: "body2"
13020
+ }, filename), /*#__PURE__*/React__default.createElement(Button$1, {
13021
+ "data-cy": "neeto-editor-image-upload-cancel-button",
13022
+ icon: Close,
13023
+ size: "small",
13024
+ style: "text",
13025
+ onClick: function onClick() {
13026
+ return removeUploadingFile(id);
11900
13027
  }
11901
13028
  })), progress !== 100 ? /*#__PURE__*/React__default.createElement("div", {
11902
13029
  className: "ne-media-uploader__media__progress"
@@ -13148,7 +14275,7 @@ var MediaUploader = function MediaUploader(_ref) {
13148
14275
  }))));
13149
14276
  };
13150
14277
 
13151
- var css = ".neeto-editor-fixed-menu{background-color:rgb(var(--neeto-ui-white));border:thin solid rgb(var(--neeto-ui-gray-300));border-bottom:none;border-radius:var(--neeto-ui-rounded) var(--neeto-ui-rounded) 0 0;position:relative}.neeto-editor-fixed-menu--independant{border-bottom:thin solid rgb(var(--neeto-ui-gray-300));border-radius:0;border-radius:initial}.neeto-editor-fixed-menu--independant .neeto-editor-fixed-menu__wrapper{border-bottom:0!important}.neeto-editor-fixed-menu__item{border-radius:0}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item{align-items:center;height:36px;justify-content:center;min-width:-moz-fit-content;min-width:fit-content;padding:0;width:36px;--neeto-ui-btn-border-radius:0;--neeto-ui-btn-icon-size:22px;--neeto-ui-btn-padding-x:0;--neeto-ui-btn-padding-y:0;--neeto-ui-btn-focus-box-shadow:none}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item .neeto-ui-btn__icon{color:rgb(var(--neeto-ui-black))}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item .neeto-ui-btn__icon path{stroke-width:1.8px}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item:hover{background-color:rgb(var(--neeto-ui-gray-100))}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item.neeto-ui-btn--style-secondary{background-color:rgb(var(--neeto-ui-primary-100))}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item.neeto-ui-btn--style-secondary .neeto-ui-btn__icon{color:rgb(var(--neeto-ui-primary-800))}.neeto-editor-fixed-menu__wrapper{align-items:center;border-bottom:thin solid rgb(var(--neeto-ui-gray-300));display:flex;justify-content:flex-start;overflow:auto;padding:0;width:100%}.neeto-editor-fixed-menu__wrapper--collapsible{align-items:center;display:flex;flex-grow:1}.neeto-editor-fixed-menu__wrapper--collapsible--fade button.neeto-editor-fixed-menu__item{animation:fade-in .3s ease-in}.neeto-editor-fixed-menu__wrapper__button-group{display:flex}.neeto-editor-fixed-menu__variables{bottom:-24px;position:absolute;right:8px;z-index:10}.neeto-editor-fixed-menu__variables .neeto-editor-menu__item{background-color:rgb(var(--neeto-ui-gray-700));border-radius:var(--neeto-ui-rounded-sm);padding:4px}.neeto-editor-fixed-menu__variables .neeto-editor-menu__item.active,.neeto-editor-fixed-menu__variables .neeto-editor-menu__item:hover{background-color:rgb(var(--neeto-ui-gray-600))}.neeto-editor-fixed-menu__right-options{display:flex}.neeto-editor-fixed-menu__emoji-dropdown{max-height:none!important}.neeto-editor-fixed-menu__separator{display:flex;height:28px;width:32px}.neeto-editor-fixed-menu__separator span{width:100%}.neeto-editor-fixed-menu__separator span:first-child{border-right:1px solid rgb(var(--neeto-ui-gray-200))}.neeto-editor-text-color-option__options-group{align-items:center;display:flex;gap:8px;margin:8px 4px}.neeto-editor-text-color-option__options-group__input{max-width:120px}.neeto-editor-text-color-option__options-group__reset-button{align-self:center}.react-colorful{width:100%!important}.neeto-editor-menu__item{align-items:center;border-radius:2px;cursor:pointer;display:flex;flex-direction:row;gap:4px;justify-content:center;padding:8px;transition:var(--neeto-ui-transition)}.neeto-editor-menu__item p{color:rgb(var(--neeto-ui-gray-600));font-size:var(--neeto-ui-text-xs);line-height:1;white-space:nowrap}.neeto-editor-menu__item.active,.neeto-editor-menu__item:hover{background-color:rgb(var(--neeto-ui-gray-200))}.neeto-editor-menu__item:focus,.neeto-editor-menu__item:focus-visible{outline:rgb(var(--neeto-ui-gray-300)) auto 1px}.neeto-editor-menu__item input[type=color]{height:0;visibility:hidden;width:0}.neeto-editor-menu__item:disabled{background-color:rgb(var(--neeto-ui-gray-100));opacity:.5}.neeto-editor-link__item{align-items:flex-start;justify-content:flex-start}.neeto-editor-link__item,.neeto-editor-table__item{display:flex!important;flex-direction:row;gap:8px;padding:8px!important}.neeto-editor-table__item input{max-width:60px!important}.neeto-editor-table__options-menu{display:flex;flex-direction:column;gap:8px;max-height:150px!important;overflow:scroll;padding:8px!important}.neeto-editor-font-size__wrapper{font-weight:var(--neeto-ui-font-normal)!important;padding-left:4px!important;padding-right:4px!important}.neeto-editor-bubble-menu{align-items:center;background:rgb(var(--neeto-ui-gray-800));border-radius:var(--neeto-ui-rounded);display:flex;flex-direction:row;gap:1px;justify-content:flex-start;padding:0 4px;position:relative}.neeto-editor-bubble-menu button.neeto-ui-btn--style-text{color:rgb(var(--neeto-ui-gray-200));min-width:-moz-fit-content;min-width:fit-content}.neeto-editor-bubble-menu button.neeto-ui-btn--style-text.active,.neeto-editor-bubble-menu button.neeto-ui-btn--style-text:active,.neeto-editor-bubble-menu button.neeto-ui-btn--style-text:hover{background-color:rgb(var(--neeto-ui-gray-600))!important;color:rgb(var(--neeto-ui-gray-200))!important}.neeto-editor-bubble-menu button.neeto-ui-btn--style-secondary{background-color:rgb(var(--neeto-ui-gray-400));min-width:-moz-fit-content;min-width:fit-content}.neeto-editor-bubble-menu .neeto-ui-dropdown__popup{background-color:rgb(var(--neeto-ui-gray-700))}.neeto-editor-bubble-menu .neeto-ui-dropdown__popup-menu-item-btn{background-color:inherit!important;color:rgb(var(--neeto-ui-gray-200))!important}.neeto-editor-bubble-menu .neeto-ui-dropdown__popup-menu-item-btn.active,.neeto-editor-bubble-menu .neeto-ui-dropdown__popup-menu-item-btn:active,.neeto-editor-bubble-menu .neeto-ui-dropdown__popup-menu-item-btn:hover{background-color:rgb(var(--neeto-ui-gray-600))!important}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link{align-items:center;display:flex;gap:8px;justify-content:space-between;padding:6px;width:256px}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .neeto-editor-bubble-menu-link__input{background-color:transparent;color:rgb(var(--neeto-ui-gray-200));line-height:20px;outline:none;width:100%}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .neeto-editor-bubble-menu-link__input::-moz-placeholder{color:rgba(.4);color:rgba(var(--neeto-ui-white,.4))}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .neeto-editor-bubble-menu-link__input::placeholder{color:rgba(.4);color:rgba(var(--neeto-ui-white,.4))}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .ne-btn--icon-only{min-height:0;opacity:.8;padding:0}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .ne-btn--icon-only:hover{opacity:1}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table{align-items:center;display:flex;gap:6px;justify-content:space-between;max-width:256px;padding:4px}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table input{background-color:rgba(var(--neeto-ui-gray-400),.2);height:24px;line-height:20px;outline:none;width:60px}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table input::-moz-placeholder{color:rgba(.4);color:rgba(var(--neeto-ui-white,.4))}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table input::placeholder{color:rgba(.4);color:rgba(var(--neeto-ui-white,.4))}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table__buttons{align-items:center;display:flex;gap:4px;justify-content:space-between}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table__options{display:flex;flex-direction:column;gap:2px;max-height:190px;overflow:scroll}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown-target{align-items:center;display:flex;font-size:var(--neeto-ui-text-xs);gap:4px;line-height:var(--neeto-ui-leading-normal);white-space:nowrap}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown{align-items:flex-start;display:flex;flex-direction:column}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown .neeto-editor-bubble-menu__dropdown-item{font-size:var(--neeto-ui-text-xs);padding:8px 12px;text-align:left;width:100%}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown .neeto-editor-bubble-menu__dropdown-item:first-child{border-top-left-radius:var(--neeto-ui-rounded);border-top-right-radius:var(--neeto-ui-rounded)}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown .neeto-editor-bubble-menu__dropdown-item:last-child{border-bottom-left-radius:var(--neeto-ui-rounded);border-bottom-right-radius:var(--neeto-ui-rounded)}.neeto-editor-bubble-menu-animate-shake{animation:shake 1s linear infinite alternate both}.neeto-editor__image-menu .neeto-ui-dropdown__popup{display:flex;min-width:0;min-width:auto}.neeto-editor__image-menu .neeto-ui-dropdown__popup .neeto-ui-btn .neeto-ui-btn__icon{height:18px!important;width:18px!important}.neeto-editor__image-menu-btn{border-radius:100%;position:absolute!important;right:6px;top:6px;z-index:1}";
14278
+ var css = ".neeto-editor-fixed-menu{background-color:rgb(var(--neeto-ui-white));border:thin solid rgb(var(--neeto-ui-gray-300));border-bottom:none;border-radius:var(--neeto-ui-rounded) var(--neeto-ui-rounded) 0 0;display:flex;position:relative}.neeto-editor-fixed-menu--independant{border-bottom:thin solid rgb(var(--neeto-ui-gray-300));border-radius:0;border-radius:initial}.neeto-editor-fixed-menu--independant .neeto-editor-fixed-menu__wrapper{border-bottom:0!important}.neeto-editor-fixed-menu__item{border-radius:0}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item{align-items:center;height:36px;justify-content:center;min-width:-moz-fit-content;min-width:fit-content;padding:0;width:36px;--neeto-ui-btn-border-radius:0;--neeto-ui-btn-icon-size:22px;--neeto-ui-btn-padding-x:0;--neeto-ui-btn-padding-y:0;--neeto-ui-btn-focus-box-shadow:none}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item .neeto-ui-btn__icon{color:rgb(var(--neeto-ui-black))}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item .neeto-ui-btn__icon path{stroke-width:1.8px}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item:hover{background-color:rgb(var(--neeto-ui-gray-100))}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item.neeto-ui-btn--style-secondary{background-color:rgb(var(--neeto-ui-primary-100))}.neeto-editor-fixed-menu button.neeto-editor-fixed-menu__item.neeto-ui-btn--style-secondary .neeto-ui-btn__icon{color:rgb(var(--neeto-ui-primary-800))}.neeto-editor-fixed-menu__wrapper{align-items:center;border-bottom:thin solid rgb(var(--neeto-ui-gray-300));display:flex;flex-grow:1;justify-content:flex-start;padding:0 2px;width:100%}.neeto-editor-fixed-menu__wrapper__button-group{display:flex}.neeto-editor-fixed-menu__variables{bottom:-24px;position:absolute;right:8px;z-index:10}.neeto-editor-fixed-menu__variables .neeto-editor-menu__item{background-color:rgb(var(--neeto-ui-gray-700));border-radius:var(--neeto-ui-rounded-sm);padding:4px}.neeto-editor-fixed-menu__variables .neeto-editor-menu__item.active,.neeto-editor-fixed-menu__variables .neeto-editor-menu__item:hover{background-color:rgb(var(--neeto-ui-gray-600))}.neeto-editor-fixed-menu__right-options{display:flex}.neeto-editor-fixed-menu__emoji-dropdown{max-height:none!important}.neeto-editor-fixed-menu__separator{display:flex;height:28px;width:32px}.neeto-editor-fixed-menu__separator span{width:100%}.neeto-editor-fixed-menu__separator span:first-child{border-right:1px solid rgb(var(--neeto-ui-gray-200))}.neeto-editor-text-color-option__options-group{align-items:center;display:flex;gap:8px;margin:8px 4px}.neeto-editor-text-color-option__options-group__input{max-width:120px}.neeto-editor-text-color-option__options-group__reset-button{align-self:center}.react-colorful{width:100%!important}.neeto-editor-menu__item{align-items:center;border-radius:2px;cursor:pointer;display:flex;flex-direction:row;gap:4px;justify-content:center;padding:8px;transition:var(--neeto-ui-transition)}.neeto-editor-menu__item p{color:rgb(var(--neeto-ui-gray-600));font-size:var(--neeto-ui-text-xs);line-height:1;white-space:nowrap}.neeto-editor-menu__item.active,.neeto-editor-menu__item:hover{background-color:rgb(var(--neeto-ui-gray-200))}.neeto-editor-menu__item:focus,.neeto-editor-menu__item:focus-visible{outline:rgb(var(--neeto-ui-gray-300)) auto 1px}.neeto-editor-menu__item input[type=color]{height:0;visibility:hidden;width:0}.neeto-editor-menu__item:disabled{background-color:rgb(var(--neeto-ui-gray-100));opacity:.5}.neeto-editor-link__item{align-items:flex-start;justify-content:flex-start}.neeto-editor-link__item,.neeto-editor-table__item{display:flex!important;flex-direction:row;gap:8px;padding:8px!important}.neeto-editor-table__item{min-width:210px}.neeto-editor-table__item input{max-width:60px!important}.neeto-editor-table__options-menu{display:flex;flex-direction:column;gap:8px;max-height:150px!important;overflow:scroll;padding:8px!important}.neeto-editor-font-size__wrapper{font-weight:var(--neeto-ui-font-normal)!important;padding-left:4px!important;padding-right:4px!important}.neeto-editor-bubble-menu{align-items:center;background:rgb(var(--neeto-ui-gray-800));border-radius:var(--neeto-ui-rounded);display:flex;flex-direction:row;gap:1px;justify-content:flex-start;padding:0 4px;position:relative}.neeto-editor-bubble-menu button.neeto-ui-btn--style-text{color:rgb(var(--neeto-ui-gray-200));min-width:-moz-fit-content;min-width:fit-content}.neeto-editor-bubble-menu button.neeto-ui-btn--style-text.active,.neeto-editor-bubble-menu button.neeto-ui-btn--style-text:active,.neeto-editor-bubble-menu button.neeto-ui-btn--style-text:hover{background-color:rgb(var(--neeto-ui-gray-600))!important;color:rgb(var(--neeto-ui-gray-200))!important}.neeto-editor-bubble-menu button.neeto-ui-btn--style-secondary{background-color:rgb(var(--neeto-ui-gray-400));min-width:-moz-fit-content;min-width:fit-content}.neeto-editor-bubble-menu .neeto-ui-dropdown__popup{background-color:rgb(var(--neeto-ui-gray-700))}.neeto-editor-bubble-menu .neeto-ui-dropdown__popup-menu-item-btn{background-color:inherit!important;color:rgb(var(--neeto-ui-gray-200))!important}.neeto-editor-bubble-menu .neeto-ui-dropdown__popup-menu-item-btn.active,.neeto-editor-bubble-menu .neeto-ui-dropdown__popup-menu-item-btn:active,.neeto-editor-bubble-menu .neeto-ui-dropdown__popup-menu-item-btn:hover{background-color:rgb(var(--neeto-ui-gray-600))!important}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link{align-items:center;display:flex;gap:8px;justify-content:space-between;padding:6px;width:256px}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .neeto-editor-bubble-menu-link__input{background-color:transparent;color:rgb(var(--neeto-ui-gray-200));line-height:20px;outline:none;width:100%}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .neeto-editor-bubble-menu-link__input::-moz-placeholder{color:rgba(.4);color:rgba(var(--neeto-ui-white,.4))}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .neeto-editor-bubble-menu-link__input::placeholder{color:rgba(.4);color:rgba(var(--neeto-ui-white,.4))}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .ne-btn--icon-only{min-height:0;opacity:.8;padding:0}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__link .ne-btn--icon-only:hover{opacity:1}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table{align-items:center;display:flex;gap:6px;justify-content:space-between;max-width:256px;padding:4px}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table input{background-color:rgba(var(--neeto-ui-gray-400),.2);height:24px;line-height:20px;outline:none;width:60px}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table input::-moz-placeholder{color:rgba(.4);color:rgba(var(--neeto-ui-white,.4))}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table input::placeholder{color:rgba(.4);color:rgba(var(--neeto-ui-white,.4))}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table__buttons{align-items:center;display:flex;gap:4px;justify-content:space-between}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__table__options{display:flex;flex-direction:column;gap:2px;max-height:190px;overflow:scroll}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown-target{align-items:center;display:flex;font-size:var(--neeto-ui-text-xs);gap:4px;line-height:var(--neeto-ui-leading-normal);white-space:nowrap}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown{align-items:flex-start;display:flex;flex-direction:column}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown .neeto-editor-bubble-menu__dropdown-item{font-size:var(--neeto-ui-text-xs);padding:8px 12px;text-align:left;width:100%}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown .neeto-editor-bubble-menu__dropdown-item:first-child{border-top-left-radius:var(--neeto-ui-rounded);border-top-right-radius:var(--neeto-ui-rounded)}.neeto-editor-bubble-menu .neeto-editor-bubble-menu__dropdown .neeto-editor-bubble-menu__dropdown-item:last-child{border-bottom-left-radius:var(--neeto-ui-rounded);border-bottom-right-radius:var(--neeto-ui-rounded)}.neeto-editor-bubble-menu-animate-shake{animation:shake 1s linear infinite alternate both}.neeto-editor__image-menu .neeto-ui-dropdown__popup{display:flex;min-width:0;min-width:auto}.neeto-editor__image-menu .neeto-ui-dropdown__popup .neeto-ui-btn .neeto-ui-btn__icon{height:18px!important;width:18px!important}.neeto-editor__image-menu-btn{border-radius:100%;position:absolute!important;right:6px;top:6px;z-index:1}";
13152
14279
  n(css,{});
13153
14280
 
13154
14281
  var LinkOption = function LinkOption(_ref) {
@@ -13167,361 +14294,109 @@ var LinkOption = function LinkOption(_ref) {
13167
14294
  var handleKeyDown = function handleKeyDown(event) {
13168
14295
  if (event.key === "Escape") {
13169
14296
  handleClose();
13170
- } else if (event.key === "Enter") {
13171
- handleSubmit();
13172
- }
13173
- };
13174
- var handleSubmit = function handleSubmit() {
13175
- if (URL_REGEXP.test(link)) {
13176
- editor.chain().focus().setLink({
13177
- href: link
13178
- }).run();
13179
- handleClose();
13180
- } else if (isNotPresent(link)) {
13181
- editor.chain().focus().unsetLink().run();
13182
- handleClose();
13183
- } else {
13184
- setLink("");
13185
- handleAnimateInvalidLink();
13186
- }
13187
- };
13188
- var handleReset = function handleReset() {
13189
- if (link) {
13190
- setLink("");
13191
- editor.chain().focus().unsetLink().run();
13192
- } else {
13193
- handleClose();
13194
- }
13195
- };
13196
- return /*#__PURE__*/React__default.createElement("div", {
13197
- className: "neeto-editor-bubble-menu__link",
13198
- onKeyDown: handleKeyDown
13199
- }, /*#__PURE__*/React__default.createElement("input", {
13200
- autoFocus: true,
13201
- className: "neeto-editor-bubble-menu-link__input",
13202
- "data-cy": "neeto-editor-link-input",
13203
- name: "url",
13204
- placeholder: t("neetoEditor.placeholders.linkInput"),
13205
- value: link,
13206
- onChange: function onChange(_ref2) {
13207
- var value = _ref2.target.value;
13208
- return setLink(value);
13209
- }
13210
- }), /*#__PURE__*/React__default.createElement(Button$1, {
13211
- "data-cy": "neeto-editor-link-cancel-button",
13212
- icon: Close,
13213
- size: "small",
13214
- style: "secondary",
13215
- onClick: handleReset
13216
- }));
13217
- };
13218
-
13219
- var TableOption$1 = function TableOption(_ref) {
13220
- var editor = _ref.editor,
13221
- handleClose = _ref.handleClose;
13222
- var _useTranslation = useTranslation(),
13223
- t = _useTranslation.t;
13224
- var _useState = useState(3),
13225
- _useState2 = _slicedToArray(_useState, 2),
13226
- rows = _useState2[0],
13227
- setRows = _useState2[1];
13228
- var _useState3 = useState(3),
13229
- _useState4 = _slicedToArray(_useState3, 2),
13230
- columns = _useState4[0],
13231
- setColumns = _useState4[1];
13232
- var handleSubmit = function handleSubmit() {
13233
- editor.chain().focus().insertTable({
13234
- rows: rows,
13235
- cols: columns,
13236
- withHeaderRow: true
13237
- }).run(), setRows(3);
13238
- setColumns(3);
13239
- handleClose();
13240
- };
13241
- return /*#__PURE__*/React__default.createElement("div", {
13242
- className: "neeto-editor-bubble-menu__table"
13243
- }, /*#__PURE__*/React__default.createElement("input", {
13244
- autoFocus: true,
13245
- "data-cy": "neeto-editor-fixed-menu-table-option-input",
13246
- min: "1",
13247
- placeholder: t("neetoEditor.placeholders.rows"),
13248
- type: "number",
13249
- value: rows,
13250
- onChange: withEventTargetValue(setRows)
13251
- }), /*#__PURE__*/React__default.createElement("input", {
13252
- "data-cy": "neeto-editor-bubble-menu-table-option-input",
13253
- min: "1",
13254
- placeholder: t("neetoEditor.placeholders.columns"),
13255
- type: "number",
13256
- value: columns,
13257
- onChange: withEventTargetValue(setColumns)
13258
- }), /*#__PURE__*/React__default.createElement("div", {
13259
- className: "neeto-editor-bubble-menu__table__buttons"
13260
- }, /*#__PURE__*/React__default.createElement(Button$1, {
13261
- "data-cy": "neeto-editor-bubble-menu-table-option-create-button",
13262
- icon: Check,
13263
- style: "secondary",
13264
- onClick: handleSubmit
13265
- }), /*#__PURE__*/React__default.createElement(Button$1, {
13266
- "data-cy": "neeto-editor-bubble-menu-table-option-create-button",
13267
- icon: Close,
13268
- style: "secondary",
13269
- onClick: handleClose
13270
- })));
13271
- };
13272
-
13273
- var getTextMenuDropdownOptions = function getTextMenuDropdownOptions(_ref2) {
13274
- var editor = _ref2.editor;
13275
- return [{
13276
- optionName: "Heading 1",
13277
- active: editor.isActive("heading", {
13278
- level: 1
13279
- }),
13280
- command: function command() {
13281
- return editor.chain().focus().setNode("heading", {
13282
- level: 1
13283
- }).run();
13284
- }
13285
- }, {
13286
- optionName: "Heading 2",
13287
- active: editor.isActive("heading", {
13288
- level: 2
13289
- }),
13290
- command: function command() {
13291
- return editor.chain().focus().setNode("heading", {
13292
- level: 2
13293
- }).run();
13294
- }
13295
- }, {
13296
- optionName: "Heading 3",
13297
- active: editor.isActive("heading", {
13298
- level: 3
13299
- }),
13300
- command: function command() {
13301
- return editor.chain().focus().setNode("heading", {
13302
- level: 3
13303
- }).run();
13304
- }
13305
- }, {
13306
- optionName: "Ordered List",
13307
- active: editor.isActive("orderedList"),
13308
- command: function command() {
13309
- return editor.chain().focus().toggleOrderedList().run();
13310
- }
13311
- }, {
13312
- optionName: "Bulleted List",
13313
- active: editor.isActive("bulletList"),
13314
- command: function command() {
13315
- return editor.chain().focus().toggleBulletList().run();
13316
- }
13317
- }, {
13318
- optionName: "Text",
13319
- active: editor.isActive("paragraph"),
13320
- command: function command() {
13321
- return editor.chain().focus().setNode("paragraph").run();
13322
- }
13323
- }];
13324
- };
13325
- var getNodeType = function getNodeType(options) {
13326
- var _options$find;
13327
- return ((_options$find = options.find(prop("active"))) === null || _options$find === void 0 ? void 0 : _options$find.optionName) || "Text";
13328
- };
13329
- var renderOptionButton$1 = function renderOptionButton(_ref3) {
13330
- var tooltip = _ref3.tooltip,
13331
- Icon = _ref3.Icon,
13332
- command = _ref3.command,
13333
- active = _ref3.active,
13334
- optionName = _ref3.optionName,
13335
- highlight = _ref3.highlight;
13336
- return /*#__PURE__*/React__default.createElement(Button$1, _extends$1({
13337
- "data-cy": "neeto-editor-bubble-menu-".concat(optionName, "-option"),
13338
- icon: Icon,
13339
- key: optionName,
13340
- size: "small",
13341
- style: active ? "secondary" : "text",
13342
- tooltipProps: {
13343
- content: tooltip,
13344
- position: "bottom",
13345
- theme: "dark",
13346
- delay: [500]
13347
- },
13348
- onClick: command
13349
- }, generateFocusProps(highlight)));
13350
- };
13351
-
13352
- var Mentions = function Mentions(_ref) {
13353
- var editor = _ref.editor,
13354
- mentions = _ref.mentions,
13355
- tooltipContent = _ref.tooltipContent;
13356
- var Menu = Dropdown$1.Menu,
13357
- MenuItem = Dropdown$1.MenuItem;
13358
- if (isEmpty(mentions)) return null;
13359
- return /*#__PURE__*/React__default.createElement(Dropdown$1, {
13360
- buttonStyle: "text",
13361
- "data-cy": "neeto-editor-mention-option",
13362
- icon: Email,
13363
- strategy: "fixed",
13364
- buttonProps: {
13365
- tooltipProps: {
13366
- content: tooltipContent,
13367
- position: "bottom"
13368
- },
13369
- className: "neeto-editor-fixed-menu__item"
13370
- }
13371
- }, /*#__PURE__*/React__default.createElement(Menu, null, mentions.map(function (_ref2) {
13372
- var key = _ref2.key,
13373
- name = _ref2.name,
13374
- imageUrl = _ref2.imageUrl;
13375
- return /*#__PURE__*/React__default.createElement(MenuItem.Button, {
13376
- "data-cy": "neeto-editor-mention-option-".concat(key),
13377
- key: key,
13378
- onClick: function onClick() {
13379
- return editor.commands.setMention({
13380
- id: key,
13381
- label: name
13382
- });
13383
- }
13384
- }, /*#__PURE__*/React__default.createElement(Avatar, {
13385
- size: "small",
13386
- user: {
13387
- name: name,
13388
- imageUrl: imageUrl
13389
- }
13390
- }), /*#__PURE__*/React__default.createElement(Typography, {
13391
- style: "body2"
13392
- }, name));
13393
- })));
13394
- };
13395
-
13396
- var EmojiOption = function EmojiOption(_ref) {
13397
- var editor = _ref.editor,
13398
- isActive = _ref.isActive,
13399
- setActive = _ref.setActive,
13400
- tooltipContent = _ref.tooltipContent;
13401
- return /*#__PURE__*/React__default.createElement(Dropdown$1, {
13402
- buttonStyle: "text",
13403
- closeOnSelect: false,
13404
- dropdownProps: {
13405
- classNames: "neeto-editor-fixed-menu__emoji-dropdown"
13406
- },
13407
- icon: Smiley,
13408
- isOpen: isActive,
13409
- position: "bottom-start",
13410
- strategy: "fixed",
13411
- buttonProps: {
13412
- tabIndex: -1,
13413
- tooltipProps: {
13414
- content: tooltipContent,
13415
- position: "bottom"
13416
- },
13417
- className: "neeto-editor-fixed-menu__item"
13418
- },
13419
- onClick: function onClick() {
13420
- return setActive(function (active) {
13421
- return !active;
13422
- });
13423
- },
13424
- onClose: function onClose() {
13425
- return setActive(false);
14297
+ } else if (event.key === "Enter") {
14298
+ handleSubmit();
13426
14299
  }
13427
- }, /*#__PURE__*/React__default.createElement(EmojiPickerMenu, {
13428
- editor: editor,
13429
- setActive: setActive
14300
+ };
14301
+ var handleSubmit = function handleSubmit() {
14302
+ if (URL_REGEXP.test(link)) {
14303
+ editor.chain().focus().setLink({
14304
+ href: link
14305
+ }).run();
14306
+ handleClose();
14307
+ } else if (isNotPresent(link)) {
14308
+ editor.chain().focus().unsetLink().run();
14309
+ handleClose();
14310
+ } else {
14311
+ setLink("");
14312
+ handleAnimateInvalidLink();
14313
+ }
14314
+ };
14315
+ var handleReset = function handleReset() {
14316
+ if (link) {
14317
+ setLink("");
14318
+ editor.chain().focus().unsetLink().run();
14319
+ } else {
14320
+ handleClose();
14321
+ }
14322
+ };
14323
+ return /*#__PURE__*/React__default.createElement("div", {
14324
+ className: "neeto-editor-bubble-menu__link",
14325
+ onKeyDown: handleKeyDown
14326
+ }, /*#__PURE__*/React__default.createElement("input", {
14327
+ autoFocus: true,
14328
+ className: "neeto-editor-bubble-menu-link__input",
14329
+ "data-cy": "neeto-editor-link-input",
14330
+ name: "url",
14331
+ placeholder: t("neetoEditor.placeholders.linkInput"),
14332
+ value: link,
14333
+ onChange: function onChange(_ref2) {
14334
+ var value = _ref2.target.value;
14335
+ return setLink(value);
14336
+ }
14337
+ }), /*#__PURE__*/React__default.createElement(Button$1, {
14338
+ "data-cy": "neeto-editor-link-cancel-button",
14339
+ icon: Close,
14340
+ size: "small",
14341
+ style: "secondary",
14342
+ onClick: handleReset
13430
14343
  }));
13431
14344
  };
13432
14345
 
13433
- var TextColorOption = function TextColorOption(_ref) {
14346
+ var TableOption = function TableOption(_ref) {
13434
14347
  var editor = _ref.editor,
13435
- tooltipContent = _ref.tooltipContent;
13436
- var _useState = useState(false),
13437
- _useState2 = _slicedToArray(_useState, 2),
13438
- isOpen = _useState2[0],
13439
- setIsOpen = _useState2[1];
13440
- var _useState3 = useState(null),
13441
- _useState4 = _slicedToArray(_useState3, 2),
13442
- color = _useState4[0],
13443
- setColor = _useState4[1];
13444
- var dropdownWrapperRef = useRef(null);
14348
+ handleClose = _ref.handleClose;
13445
14349
  var _useTranslation = useTranslation(),
13446
14350
  t = _useTranslation.t;
13447
- var handleSave = function handleSave() {
13448
- editor.chain().focus().setColor(color).run();
13449
- setIsOpen(false);
13450
- };
13451
- var handleUnset = function handleUnset() {
13452
- editor.chain().focus().unsetColor().run();
13453
- setColor(null);
13454
- setIsOpen(false);
14351
+ var _useState = useState(3),
14352
+ _useState2 = _slicedToArray(_useState, 2),
14353
+ rows = _useState2[0],
14354
+ setRows = _useState2[1];
14355
+ var _useState3 = useState(3),
14356
+ _useState4 = _slicedToArray(_useState3, 2),
14357
+ columns = _useState4[0],
14358
+ setColumns = _useState4[1];
14359
+ var handleSubmit = function handleSubmit() {
14360
+ editor.chain().focus().insertTable({
14361
+ rows: rows,
14362
+ cols: columns,
14363
+ withHeaderRow: true
14364
+ }).run(), setRows(3);
14365
+ setColumns(3);
14366
+ handleClose();
13455
14367
  };
13456
- useOnClickOutside(dropdownWrapperRef, function (event) {
13457
- if (isOpen) {
13458
- event.preventDefault();
13459
- editor.commands.focus();
13460
- setIsOpen(false);
13461
- }
13462
- });
13463
- useEffect(function () {
13464
- setColor(editor.getAttributes("textStyle").color);
13465
- }, [isOpen, editor.getAttributes("textStyle").color]);
13466
14368
  return /*#__PURE__*/React__default.createElement("div", {
13467
- ref: dropdownWrapperRef
13468
- }, /*#__PURE__*/React__default.createElement(Dropdown$1, {
13469
- buttonStyle: isOpen || color ? "secondary" : "text",
13470
- icon: Customize,
13471
- isOpen: isOpen,
13472
- buttonProps: {
13473
- tabIndex: -1,
13474
- tooltipProps: {
13475
- content: tooltipContent,
13476
- position: "bottom"
13477
- },
13478
- className: "neeto-editor-fixed-menu__item neeto-editor-text-color-option"
13479
- },
13480
- onClick: function onClick() {
13481
- setColor(editor.getAttributes("textStyle").color);
13482
- setIsOpen(not);
13483
- }
13484
- }, /*#__PURE__*/React__default.createElement(HexColorPicker, {
13485
- color: color || "#000000",
13486
- onChange: setColor
13487
- }), /*#__PURE__*/React__default.createElement("div", {
13488
- className: "neeto-editor-text-color-option__options-group"
13489
- }, /*#__PURE__*/React__default.createElement(Input, {
14369
+ className: "neeto-editor-bubble-menu__table"
14370
+ }, /*#__PURE__*/React__default.createElement("input", {
13490
14371
  autoFocus: true,
13491
- className: "neeto-editor-text-color-option__options-group__input",
13492
- placeholder: t("neetoEditor.placeholders.pickColor"),
13493
- size: "small",
13494
- value: color,
13495
- onChange: withEventTargetValue(setColor),
13496
- onClick: function onClick(event) {
13497
- return event.stopPropagation();
13498
- }
13499
- }), /*#__PURE__*/React__default.createElement(Button$1, {
14372
+ "data-cy": "neeto-editor-fixed-menu-table-option-input",
14373
+ min: "1",
14374
+ placeholder: t("neetoEditor.placeholders.rows"),
14375
+ type: "number",
14376
+ value: rows,
14377
+ onChange: withEventTargetValue(setRows)
14378
+ }), /*#__PURE__*/React__default.createElement("input", {
14379
+ "data-cy": "neeto-editor-bubble-menu-table-option-input",
14380
+ min: "1",
14381
+ placeholder: t("neetoEditor.placeholders.columns"),
14382
+ type: "number",
14383
+ value: columns,
14384
+ onChange: withEventTargetValue(setColumns)
14385
+ }), /*#__PURE__*/React__default.createElement("div", {
14386
+ className: "neeto-editor-bubble-menu__table__buttons"
14387
+ }, /*#__PURE__*/React__default.createElement(Button$1, {
14388
+ "data-cy": "neeto-editor-bubble-menu-table-option-create-button",
13500
14389
  icon: Check,
13501
- size: "small",
13502
- onClick: handleSave
14390
+ style: "secondary",
14391
+ onClick: handleSubmit
13503
14392
  }), /*#__PURE__*/React__default.createElement(Button$1, {
14393
+ "data-cy": "neeto-editor-bubble-menu-table-option-create-button",
13504
14394
  icon: Close,
13505
- size: "small",
13506
- style: "text",
13507
- onClick: function onClick() {
13508
- editor.commands.focus();
13509
- setIsOpen(false);
13510
- }
13511
- }), /*#__PURE__*/React__default.createElement(Button$1, {
13512
- icon: Refresh,
13513
- size: "small",
13514
- style: "text",
13515
- tooltipProps: {
13516
- content: t("neetoEditor.common.resetToDefault"),
13517
- position: "top"
13518
- },
13519
- onClick: handleUnset
13520
- }))));
14395
+ style: "secondary",
14396
+ onClick: handleClose
14397
+ })));
13521
14398
  };
13522
14399
 
13523
- function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
13524
- function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
13525
14400
  var createMenuOptions$1 = function createMenuOptions(_ref) {
13526
14401
  var tooltips = _ref.tooltips,
13527
14402
  editor = _ref.editor,
@@ -13673,7 +14548,7 @@ var createMenuOptions$1 = function createMenuOptions(_ref) {
13673
14548
  }]
13674
14549
  };
13675
14550
  };
13676
- var buildMenuOptions$1 = function buildMenuOptions(_ref2) {
14551
+ var buildBubbleMenuOptions = function buildBubbleMenuOptions(_ref2) {
13677
14552
  var tooltips = _ref2.tooltips,
13678
14553
  editor = _ref2.editor,
13679
14554
  options = _ref2.options,
@@ -13695,54 +14570,83 @@ var buildMenuOptions$1 = function buildMenuOptions(_ref2) {
13695
14570
  })];
13696
14571
  }));
13697
14572
  };
13698
- var renderOptionButton = function renderOptionButton(_ref3) {
13699
- var Icon = _ref3.Icon,
13700
- command = _ref3.command,
13701
- active = _ref3.active,
13702
- optionName = _ref3.optionName,
13703
- highlight = _ref3.highlight,
13704
- disabled = _ref3.disabled,
13705
- tooltip = _ref3.tooltip;
14573
+ var getTextMenuDropdownOptions = function getTextMenuDropdownOptions(_ref3) {
14574
+ var editor = _ref3.editor;
14575
+ return [{
14576
+ optionName: "Heading 1",
14577
+ active: editor.isActive("heading", {
14578
+ level: 1
14579
+ }),
14580
+ command: function command() {
14581
+ return editor.chain().focus().setNode("heading", {
14582
+ level: 1
14583
+ }).run();
14584
+ }
14585
+ }, {
14586
+ optionName: "Heading 2",
14587
+ active: editor.isActive("heading", {
14588
+ level: 2
14589
+ }),
14590
+ command: function command() {
14591
+ return editor.chain().focus().setNode("heading", {
14592
+ level: 2
14593
+ }).run();
14594
+ }
14595
+ }, {
14596
+ optionName: "Heading 3",
14597
+ active: editor.isActive("heading", {
14598
+ level: 3
14599
+ }),
14600
+ command: function command() {
14601
+ return editor.chain().focus().setNode("heading", {
14602
+ level: 3
14603
+ }).run();
14604
+ }
14605
+ }, {
14606
+ optionName: "Ordered List",
14607
+ active: editor.isActive("orderedList"),
14608
+ command: function command() {
14609
+ return editor.chain().focus().toggleOrderedList().run();
14610
+ }
14611
+ }, {
14612
+ optionName: "Bulleted List",
14613
+ active: editor.isActive("bulletList"),
14614
+ command: function command() {
14615
+ return editor.chain().focus().toggleBulletList().run();
14616
+ }
14617
+ }, {
14618
+ optionName: "Text",
14619
+ active: editor.isActive("paragraph"),
14620
+ command: function command() {
14621
+ return editor.chain().focus().setNode("paragraph").run();
14622
+ }
14623
+ }];
14624
+ };
14625
+ var getNodeType = function getNodeType(options) {
14626
+ var _options$find;
14627
+ return ((_options$find = options.find(prop("active"))) === null || _options$find === void 0 ? void 0 : _options$find.optionName) || "Text";
14628
+ };
14629
+ var renderOptionButton = function renderOptionButton(_ref4) {
14630
+ var tooltip = _ref4.tooltip,
14631
+ Icon = _ref4.Icon,
14632
+ command = _ref4.command,
14633
+ active = _ref4.active,
14634
+ optionName = _ref4.optionName,
14635
+ highlight = _ref4.highlight;
13706
14636
  return /*#__PURE__*/React__default.createElement(Button$1, _extends$1({
13707
- disabled: disabled,
13708
- className: "neeto-editor-fixed-menu__item",
13709
- "data-cy": "neeto-editor-fixed-menu-".concat(optionName, "-option"),
14637
+ "data-cy": "neeto-editor-bubble-menu-".concat(optionName, "-option"),
13710
14638
  icon: Icon,
13711
14639
  key: optionName,
13712
- style: active ? "secondary" : "text",
13713
- tabIndex: "-1",
13714
- tooltipProps: {
13715
- content: tooltip,
13716
- position: "bottom"
13717
- },
13718
- onClick: command
13719
- }, generateFocusProps(highlight)));
13720
- };
13721
- var buildOptionsFromAddonCommands = function buildOptionsFromAddonCommands(_ref4) {
13722
- var editor = _ref4.editor,
13723
- commands = _ref4.commands;
13724
- var to = editor.state.selection.to;
13725
- return commands.map(function (option) {
13726
- var _option$active;
13727
- return _objectSpread$3(_objectSpread$3({}, option), {}, {
13728
- active: (_option$active = option.active) === null || _option$active === void 0 ? void 0 : _option$active.call(option, {
13729
- editor: editor
13730
- }),
13731
- command: function command() {
13732
- var _option$command;
13733
- return (_option$command = option.command) === null || _option$command === void 0 ? void 0 : _option$command.call(option, {
13734
- editor: editor,
13735
- range: {
13736
- from: to,
13737
- to: to
13738
- }
13739
- });
13740
- }
13741
- });
13742
- });
13743
- };
13744
- var getCursorPos = function getCursorPos(editor, to) {
13745
- return editor === null || editor === void 0 ? void 0 : editor.view.coordsAtPos(to);
14640
+ size: "small",
14641
+ style: active ? "secondary" : "text",
14642
+ tooltipProps: {
14643
+ content: tooltip,
14644
+ position: "bottom",
14645
+ theme: "dark",
14646
+ delay: [500]
14647
+ },
14648
+ onClick: command
14649
+ }, generateFocusProps(highlight)));
13746
14650
  };
13747
14651
 
13748
14652
  var Options = function Options(_ref) {
@@ -13773,7 +14677,7 @@ var Options = function Options(_ref) {
13773
14677
  var isTextColorOptionActive = options.includes(EDITOR_OPTIONS.TEXT_COLOR);
13774
14678
  var isLinkActive = options.includes(EDITOR_OPTIONS.LINK);
13775
14679
  var isTableActive = options.includes(EDITOR_OPTIONS.TABLE);
13776
- var _buildMenuOptions = buildMenuOptions$1({
14680
+ var _buildBubbleMenuOptio = buildBubbleMenuOptions({
13777
14681
  editor: editor,
13778
14682
  options: options,
13779
14683
  setMediaUploader: setMediaUploader,
@@ -13782,9 +14686,9 @@ var Options = function Options(_ref) {
13782
14686
  setIsEmbedModalOpen: setIsEmbedModalOpen,
13783
14687
  setIsAddLinkActive: setIsLinkOptionActive
13784
14688
  }),
13785
- fontStyleOptions = _buildMenuOptions.font,
13786
- blockStyleOptions = _buildMenuOptions.block,
13787
- listStyleOptions = _buildMenuOptions.list;
14689
+ fontStyleOptions = _buildBubbleMenuOptio.font,
14690
+ blockStyleOptions = _buildBubbleMenuOptio.block,
14691
+ listStyleOptions = _buildBubbleMenuOptio.list;
13788
14692
  var handleAnimateInvalidLink = function handleAnimateInvalidLink() {
13789
14693
  setIsInvalidLink(true);
13790
14694
  setTimeout(function () {
@@ -13801,7 +14705,7 @@ var Options = function Options(_ref) {
13801
14705
  });
13802
14706
  }
13803
14707
  if (isTableOptionActive) {
13804
- return /*#__PURE__*/React__default.createElement(TableOption$1, {
14708
+ return /*#__PURE__*/React__default.createElement(TableOption, {
13805
14709
  editor: editor,
13806
14710
  handleClose: function handleClose() {
13807
14711
  return setIsTableOptionActive(false);
@@ -13820,7 +14724,7 @@ var Options = function Options(_ref) {
13820
14724
  key: optionName,
13821
14725
  onClick: command
13822
14726
  }, optionName);
13823
- }))), fontStyleOptions.map(renderOptionButton$1), blockStyleOptions.map(renderOptionButton$1), isTextColorOptionActive && /*#__PURE__*/React__default.createElement(TextColorOption, {
14727
+ }))), fontStyleOptions.map(renderOptionButton), blockStyleOptions.map(renderOptionButton), isTextColorOptionActive && /*#__PURE__*/React__default.createElement(TextColorOption, {
13824
14728
  editor: editor,
13825
14729
  tooltipContent: tooltips.textColor || t("neetoEditor.menu.textColor")
13826
14730
  }), isEmojiActive && /*#__PURE__*/React__default.createElement(EmojiOption, {
@@ -13828,7 +14732,7 @@ var Options = function Options(_ref) {
13828
14732
  isActive: isEmojiPickerActive,
13829
14733
  setActive: setIsEmojiPickerActive,
13830
14734
  tooltipContent: tooltips.emoji || t("neetoEditor.menu.emoji")
13831
- }), listStyleOptions.map(renderOptionButton$1), isLinkActive && renderOptionButton$1({
14735
+ }), listStyleOptions.map(renderOptionButton), isLinkActive && renderOptionButton({
13832
14736
  Icon: Link,
13833
14737
  command: function command() {
13834
14738
  return setIsLinkOptionActive(true);
@@ -13837,7 +14741,7 @@ var Options = function Options(_ref) {
13837
14741
  optionName: "link",
13838
14742
  highlight: false,
13839
14743
  tooltip: tooltips.link || t("neetoEditor.menu.link")
13840
- }), isTableActive && renderOptionButton$1({
14744
+ }), isTableActive && renderOptionButton({
13841
14745
  Icon: Column,
13842
14746
  command: function command() {
13843
14747
  return setIsTableOptionActive(true);
@@ -13920,93 +14824,6 @@ var Bubble = function Bubble(_ref) {
13920
14824
  }, children)));
13921
14825
  };
13922
14826
 
13923
- var FONT_SIZE_OPTIONS = [{
13924
- label: t$1("neetoEditor.menu.heading1"),
13925
- value: 1,
13926
- key: "h1"
13927
- }, {
13928
- label: t$1("neetoEditor.menu.heading2"),
13929
- value: 2,
13930
- key: "h2"
13931
- }, {
13932
- label: t$1("neetoEditor.menu.heading3"),
13933
- value: 3,
13934
- key: "h3"
13935
- }, {
13936
- label: t$1("neetoEditor.menu.heading4"),
13937
- value: 4,
13938
- key: "h4"
13939
- }, {
13940
- label: t$1("neetoEditor.menu.heading5"),
13941
- value: 5,
13942
- key: "h5"
13943
- }, {
13944
- label: t$1("neetoEditor.menu.normalText"),
13945
- value: 0,
13946
- key: "body2"
13947
- }];
13948
-
13949
- var Menu$2 = Dropdown$1.Menu,
13950
- MenuItem = Dropdown$1.MenuItem;
13951
- var FontSizeOption = function FontSizeOption(_ref) {
13952
- var editor = _ref.editor,
13953
- tooltipContent = _ref.tooltipContent;
13954
- var dropdownRef = useRef(null);
13955
- var isActive = function isActive(level) {
13956
- return editor.isActive("heading", {
13957
- level: level
13958
- });
13959
- };
13960
- var activeOption = FONT_SIZE_OPTIONS.find(function (_ref2) {
13961
- var value = _ref2.value;
13962
- return isActive(value);
13963
- }) || last(FONT_SIZE_OPTIONS);
13964
- var handleClick = function handleClick(level) {
13965
- return level ? editor.chain().focus().toggleHeading({
13966
- level: level
13967
- }).run() : editor.chain().focus().setNode("paragraph").run();
13968
- };
13969
- return /*#__PURE__*/React__default.createElement(Dropdown$1, {
13970
- autoWidth: true,
13971
- "data-cy": "neeto-editor-fixed-menu-font-size-option",
13972
- label: activeOption === null || activeOption === void 0 ? void 0 : activeOption.label,
13973
- placement: "bottom-start",
13974
- strategy: "fixed",
13975
- buttonProps: {
13976
- ref: dropdownRef,
13977
- onKeyDown: function onKeyDown(event) {
13978
- var _dropdownRef$current;
13979
- return event.key === "ArrowDown" && ((_dropdownRef$current = dropdownRef.current) === null || _dropdownRef$current === void 0 ? void 0 : _dropdownRef$current.click());
13980
- },
13981
- tooltipProps: {
13982
- content: tooltipContent,
13983
- position: "bottom"
13984
- },
13985
- style: "text",
13986
- size: "small",
13987
- className: "neeto-editor-fixed-menu__item neeto-editor-font-size__wrapper"
13988
- }
13989
- }, /*#__PURE__*/React__default.createElement(Menu$2, {
13990
- onKeyDown: function onKeyDown(event) {
13991
- var _editor$commands;
13992
- return event.key === "Escape" && ((_editor$commands = editor.commands) === null || _editor$commands === void 0 ? void 0 : _editor$commands.focus());
13993
- }
13994
- }, FONT_SIZE_OPTIONS.map(function (_ref3) {
13995
- var label = _ref3.label,
13996
- value = _ref3.value,
13997
- key = _ref3.key;
13998
- return /*#__PURE__*/React__default.createElement(MenuItem.Button, {
13999
- "data-cy": "neeto-editor-fixed-menu-font-size-option-".concat(key),
14000
- key: value,
14001
- onClick: function onClick() {
14002
- return handleClick(value);
14003
- }
14004
- }, /*#__PURE__*/React__default.createElement(Typography, {
14005
- style: key
14006
- }, label));
14007
- })));
14008
- };
14009
-
14010
14827
  var LinkAddPopOver = function LinkAddPopOver(_ref) {
14011
14828
  var isAddLinkActive = _ref.isAddLinkActive,
14012
14829
  setIsAddLinkActive = _ref.setIsAddLinkActive,
@@ -14043,7 +14860,7 @@ var LinkAddPopOver = function LinkAddPopOver(_ref) {
14043
14860
  _useState12 = _slicedToArray(_useState11, 2),
14044
14861
  arrowPosition = _useState12[0],
14045
14862
  setArrowPosition = _useState12[1];
14046
- var popOverRef = useRef(null);
14863
+ var popoverRef = useRef(null);
14047
14864
  var _useTranslation = useTranslation(),
14048
14865
  t = _useTranslation.t;
14049
14866
  var isLinkTextPresent = !isNotPresent(linkText);
@@ -14092,26 +14909,13 @@ var LinkAddPopOver = function LinkAddPopOver(_ref) {
14092
14909
  }
14093
14910
  };
14094
14911
  var updatePopoverPosition = function updatePopoverPosition() {
14095
- var _popOverRef$current;
14096
- if (!popOverRef.current) return;
14097
- var newPos = editor.view.coordsAtPos(editor.view.state.selection.$to.pos);
14098
- setArrowPosition({
14099
- top: "".concat(newPos.top + 20, "px"),
14100
- left: "".concat(newPos.left - 10, "px")
14101
- });
14102
- var popoverRect = (_popOverRef$current = popOverRef.current) === null || _popOverRef$current === void 0 ? void 0 : _popOverRef$current.getBoundingClientRect();
14103
- var screenWidth = window.innerWidth;
14104
- var screenHeight = window.innerHeight;
14105
- var maxLeft = screenWidth - popoverRect.width;
14106
- var maxTop = screenHeight - popoverRect.height - 50;
14107
- var adjustedLeft = newPos !== null && newPos !== void 0 && newPos.left ? Math.min(newPos.left - 50, maxLeft) : 0;
14108
- var adjustedTop = newPos !== null && newPos !== void 0 && newPos.top ? Math.min(newPos.top - 22, maxTop) : 0;
14109
- setPopoverPosition({
14110
- top: "".concat(adjustedTop, "px"),
14111
- left: "".concat(adjustedLeft, "px")
14112
- });
14912
+ var _getLinkPopoverPositi = getLinkPopoverPosition(editor, popoverRef),
14913
+ arrowPosition = _getLinkPopoverPositi.arrowPosition,
14914
+ popoverPosition = _getLinkPopoverPositi.popoverPosition;
14915
+ setPopoverPosition(popoverPosition);
14916
+ setArrowPosition(arrowPosition);
14113
14917
  };
14114
- useOnClickOutside(popOverRef, removePopover);
14918
+ useOnClickOutside(popoverRef, removePopover);
14115
14919
  useEffect(function () {
14116
14920
  if (editor && isAddLinkActive) {
14117
14921
  updatePopoverPosition();
@@ -14124,15 +14928,15 @@ var LinkAddPopOver = function LinkAddPopOver(_ref) {
14124
14928
  };
14125
14929
  }, []);
14126
14930
  return isAddLinkActive ? /*#__PURE__*/createPortal( /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("div", {
14127
- className: "ne-link-arrow",
14931
+ className: "ne-link-arrow fade-in",
14128
14932
  style: {
14129
14933
  top: arrowPosition.top,
14130
14934
  left: arrowPosition.left
14131
14935
  }
14132
14936
  }), /*#__PURE__*/React__default.createElement("div", {
14133
- className: "ne-link-popover",
14937
+ className: "ne-link-popover fade-in",
14134
14938
  id: "ne-link-add-popover",
14135
- ref: popOverRef,
14939
+ ref: popoverRef,
14136
14940
  style: popoverStyle
14137
14941
  }, /*#__PURE__*/React__default.createElement(Input, {
14138
14942
  required: true,
@@ -14196,85 +15000,52 @@ var LinkAddPopOver = function LinkAddPopOver(_ref) {
14196
15000
  })))), document.body) : null;
14197
15001
  };
14198
15002
 
14199
- var Menu$1 = Dropdown$1.Menu;
14200
- var TableOption = function TableOption(_ref) {
14201
- var editor = _ref.editor,
14202
- tooltipContent = _ref.tooltipContent;
14203
- var _useTranslation = useTranslation(),
14204
- t = _useTranslation.t;
14205
- var _useState = useState(false),
14206
- _useState2 = _slicedToArray(_useState, 2),
14207
- isOpen = _useState2[0],
14208
- setIsOpen = _useState2[1];
14209
- var _useState3 = useState(3),
14210
- _useState4 = _slicedToArray(_useState3, 2),
14211
- rows = _useState4[0],
14212
- setRows = _useState4[1];
14213
- var _useState5 = useState(3),
14214
- _useState6 = _slicedToArray(_useState5, 2),
14215
- columns = _useState6[0],
14216
- setColumns = _useState6[1];
14217
- var handleClose = function handleClose() {
14218
- setRows(3);
14219
- setColumns(3);
14220
- setIsOpen(false);
14221
- };
14222
- var handleSubmit = function handleSubmit() {
14223
- editor.chain().focus().insertTable({
14224
- rows: rows,
14225
- cols: columns,
14226
- withHeaderRow: true
14227
- }).run();
14228
- handleClose();
14229
- };
15003
+ var _excluded$3 = ["type"];
15004
+ function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
15005
+ function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15006
+ var Menu$1 = Dropdown$1.Menu,
15007
+ MenuItem = Dropdown$1.MenuItem;
15008
+ var MoreMenu = function MoreMenu(_ref) {
15009
+ var groups = _ref.groups,
15010
+ editor = _ref.editor;
14230
15011
  return /*#__PURE__*/React__default.createElement(Dropdown$1, {
14231
- isOpen: isOpen,
14232
- buttonStyle: isOpen ? "secondary" : "text",
14233
- closeOnSelect: false,
14234
- "data-cy": "neeto-editor-fixed-menu-link-option",
14235
- icon: Column,
14236
- position: "bottom",
14237
15012
  buttonProps: {
14238
- tabIndex: -1,
14239
- tooltipProps: {
14240
- content: tooltipContent,
14241
- position: "bottom"
14242
- },
14243
- className: "neeto-editor-fixed-menu__item"
14244
- },
14245
- onClick: function onClick() {
14246
- return setIsOpen(function (isOpen) {
14247
- return !isOpen;
14248
- });
15013
+ className: "flex-shrink-0"
14249
15014
  },
14250
- onClose: handleClose
14251
- }, /*#__PURE__*/React__default.createElement(Menu$1, {
14252
- className: "neeto-editor-table__item"
14253
- }, /*#__PURE__*/React__default.createElement(Input, {
14254
- autoFocus: true,
14255
- "data-cy": "neeto-editor-fixed-menu-table-option-input",
14256
- min: "1",
14257
- placeholder: t("neetoEditor.placeholders.rows"),
14258
- size: "small",
14259
- type: "number",
14260
- value: rows,
14261
- onChange: withEventTargetValue(setRows)
14262
- }), /*#__PURE__*/React__default.createElement(Input, {
14263
- "data-cy": "neeto-editor-fixed-menu-table-option-input",
14264
- min: "1",
14265
- placeholder: t("neetoEditor.placeholders.rows"),
14266
- size: "small",
14267
- type: "number",
14268
- value: columns,
14269
- onChange: withEventTargetValue(setColumns)
14270
- }), /*#__PURE__*/React__default.createElement(Button$1, {
14271
- "data-cy": "neeto-editor-fixed-menu-table-option-create-button",
14272
- label: t("neetoEditor.common.create"),
14273
- size: "small",
14274
- onClick: handleSubmit
15015
+ buttonStyle: "text",
15016
+ icon: MenuHorizontal,
15017
+ strategy: "fixed"
15018
+ }, /*#__PURE__*/React__default.createElement(Menu$1, null, groups.map(function (group) {
15019
+ return group.map(function (_ref2) {
15020
+ var type = _ref2.type,
15021
+ props = _objectWithoutProperties$1(_ref2, _excluded$3);
15022
+ var Component = MENU_ELEMENTS[type];
15023
+ if (type === MENU_ELEMENT_TYPES.BUTTON) {
15024
+ var Icon = props.icon;
15025
+ return /*#__PURE__*/React__default.createElement(MenuItem.Button, _extends$1({
15026
+ "data-cy": "neeto-editor-fixed-menu-".concat(props.optionName, "-option"),
15027
+ isActive: editor.isActive(props.optionName),
15028
+ key: props.optionName,
15029
+ tabIndex: "-1",
15030
+ onClick: props.command
15031
+ }, _objectSpread$4(_objectSpread$4(_objectSpread$4({}, generateFocusProps(props.highlight)), props), {}, {
15032
+ editor: editor
15033
+ })), /*#__PURE__*/React__default.createElement(Icon, null), " ", props.label);
15034
+ }
15035
+ return /*#__PURE__*/React__default.createElement(Component, _extends$1({
15036
+ key: props.optionName
15037
+ }, _objectSpread$4(_objectSpread$4({}, props), {}, {
15038
+ editor: editor
15039
+ }, generateFocusProps(props.highlight)), {
15040
+ isSecondaryMenu: true
15041
+ }));
15042
+ });
14275
15043
  })));
14276
15044
  };
14277
15045
 
15046
+ var _excluded$2 = ["type"];
15047
+ function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
15048
+ function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
14278
15049
  var Fixed = function Fixed(_ref) {
14279
15050
  var editor = _ref.editor,
14280
15051
  options = _ref.options,
@@ -14287,8 +15058,6 @@ var Fixed = function Fixed(_ref) {
14287
15058
  unsplashApiKey = _ref.unsplashApiKey,
14288
15059
  _ref$addonCommands = _ref.addonCommands,
14289
15060
  addonCommands = _ref$addonCommands === void 0 ? [] : _ref$addonCommands,
14290
- _ref$isMenuCollapsibl = _ref.isMenuCollapsible,
14291
- isMenuCollapsible = _ref$isMenuCollapsibl === void 0 ? false : _ref$isMenuCollapsibl,
14292
15061
  _ref$isIndependant = _ref.isIndependant,
14293
15062
  isIndependant = _ref$isIndependant === void 0 ? true : _ref$isIndependant,
14294
15063
  className = _ref.className,
@@ -14305,17 +15074,22 @@ var Fixed = function Fixed(_ref) {
14305
15074
  setFocusedButtonIndex = _useState2[1];
14306
15075
  var _useState3 = useState(false),
14307
15076
  _useState4 = _slicedToArray(_useState3, 2),
14308
- isMenuExpanded = _useState4[0],
14309
- setIsMenuExpanded = _useState4[1];
15077
+ isEmbedModalOpen = _useState4[0],
15078
+ setIsEmbedModalOpen = _useState4[1];
14310
15079
  var _useState5 = useState(false),
14311
15080
  _useState6 = _slicedToArray(_useState5, 2),
14312
- isEmbedModalOpen = _useState6[0],
14313
- setIsEmbedModalOpen = _useState6[1];
14314
- var _useState7 = useState(false),
15081
+ isAddLinkActive = _useState6[0],
15082
+ setIsAddLinkActive = _useState6[1];
15083
+ var _useState7 = useState([]),
14315
15084
  _useState8 = _slicedToArray(_useState7, 2),
14316
- isAddLinkActive = _useState8[0],
14317
- setIsAddLinkActive = _useState8[1];
15085
+ menuItems = _useState8[0],
15086
+ setMenuItems = _useState8[1];
15087
+ var _useState9 = useState([]),
15088
+ _useState10 = _slicedToArray(_useState9, 2),
15089
+ moreMenuItems = _useState10[0],
15090
+ setMoreMenuItems = _useState10[1];
14318
15091
  var menuRef = useRef(null);
15092
+ var menuContainerRef = useRef(null);
14319
15093
  var _useTranslation = useTranslation(),
14320
15094
  t = _useTranslation.t;
14321
15095
  var handleArrowNavigation = function handleArrowNavigation(event) {
@@ -14348,36 +15122,43 @@ var Fixed = function Fixed(_ref) {
14348
15122
  });
14349
15123
  };
14350
15124
  }, [menuButtons]);
14351
- if (!editor) {
14352
- return null;
14353
- }
14354
- var _buildMenuOptions = buildMenuOptions$1({
15125
+ var menuGroups = useMemo(function () {
15126
+ return buildMenuOptions$1({
14355
15127
  tooltips: tooltips,
14356
15128
  editor: editor,
14357
15129
  options: options,
14358
15130
  setMediaUploader: setMediaUploader,
14359
15131
  attachmentProps: attachmentProps,
14360
15132
  setIsEmbedModalOpen: setIsEmbedModalOpen,
14361
- setIsAddLinkActive: setIsAddLinkActive
14362
- }),
14363
- fontStyleOptions = _buildMenuOptions.font,
14364
- blockStyleOptions = _buildMenuOptions.block,
14365
- listStyleOptions = _buildMenuOptions.list,
14366
- miscOptions = _buildMenuOptions.misc,
14367
- rightOptions = _buildMenuOptions.right;
14368
- var fontSizeOptions = options.filter(function (option) {
14369
- return option.match(/^h[1-6]$/);
14370
- });
14371
- var isFontSizeActive = isNotEmpty(fontSizeOptions);
14372
- var isEmojiActive = options.includes(EDITOR_OPTIONS.EMOJI);
14373
- var isTableActive = options.includes(EDITOR_OPTIONS.TABLE);
14374
- var isTextColorOptionActive = options.includes(EDITOR_OPTIONS.TEXT_COLOR);
15133
+ setIsAddLinkActive: setIsAddLinkActive,
15134
+ mentions: mentions,
15135
+ addonCommands: addonCommands,
15136
+ setIsEmojiPickerActive: setIsEmojiPickerActive,
15137
+ isEmojiPickerActive: isEmojiPickerActive
15138
+ });
15139
+ }, [editor, isEmojiPickerActive, mentions]);
15140
+ var handleResize = useCallback(function () {
15141
+ if (!menuRef.current) return;
15142
+ var _reGroupMenuItems = reGroupMenuItems(menuRef, menuGroups),
15143
+ visibleMenuGroups = _reGroupMenuItems.visibleMenuGroups,
15144
+ invisibleMenuGroups = _reGroupMenuItems.invisibleMenuGroups;
15145
+ setMenuItems(visibleMenuGroups);
15146
+ setMoreMenuItems(invisibleMenuGroups);
15147
+ }, [menuGroups]);
15148
+ useEffect(function () {
15149
+ handleResize();
15150
+ var menuContainer = menuContainerRef.current;
15151
+ var resizeObserver = new ResizeObserver(handleResize);
15152
+ if (menuContainer) {
15153
+ resizeObserver.observe(menuContainer);
15154
+ }
15155
+ return function () {
15156
+ if (menuContainer) resizeObserver.unobserve(menuContainer);
15157
+ };
15158
+ }, [menuContainerRef, handleResize, menuGroups]);
15159
+ if (!editor) return null;
14375
15160
  var isEmbedOptionActive = options.includes(EDITOR_OPTIONS.VIDEO_EMBED);
14376
- var isMediaUploaderActive = options.includes(EDITOR_OPTIONS.IMAGE_UPLOAD );
14377
- var addonCommandOptions = buildOptionsFromAddonCommands({
14378
- editor: editor,
14379
- commands: addonCommands
14380
- });
15161
+ var isMediaUploaderActive = options.includes(EDITOR_OPTIONS.IMAGE_UPLOAD) || options.includes(EDITOR_OPTIONS.VIDEO_UPLOAD);
14381
15162
  var handleVariableClick = function handleVariableClick(item) {
14382
15163
  var category = item.category,
14383
15164
  key = item.key;
@@ -14387,7 +15168,7 @@ var Fixed = function Fixed(_ref) {
14387
15168
  }).run();
14388
15169
  };
14389
15170
  return /*#__PURE__*/React__default.createElement("div", {
14390
- ref: menuRef,
15171
+ ref: menuContainerRef,
14391
15172
  className: classnames("neeto-editor-fixed-menu", _defineProperty({
14392
15173
  "neeto-editor-fixed-menu--independant": isIndependant
14393
15174
  }, className, className))
@@ -14395,39 +15176,41 @@ var Fixed = function Fixed(_ref) {
14395
15176
  className: "neeto-editor-fixed-menu__wrapper",
14396
15177
  "data-cy": "neeto-editor-fixed-menu-wrapper",
14397
15178
  ref: menuRef
14398
- }, isNotEmpty(rightOptions) && /*#__PURE__*/React__default.createElement("div", {
14399
- className: "neeto-editor-fixed-menu__right-options"
14400
- }, rightOptions.map(renderOptionButton)), isFontSizeActive && /*#__PURE__*/React__default.createElement(FontSizeOption, {
15179
+ }, menuItems.map(function (group) {
15180
+ return group.map(function (_ref2) {
15181
+ var type = _ref2.type,
15182
+ props = _objectWithoutProperties$1(_ref2, _excluded$2);
15183
+ var Component = MENU_ELEMENTS[type];
15184
+ if (!Component) return null;
15185
+ return /*#__PURE__*/React__default.createElement(Component, _extends$1({
15186
+ key: props.optionName
15187
+ }, _objectSpread$3(_objectSpread$3({}, props), {}, {
15188
+ editor: editor
15189
+ })));
15190
+ });
15191
+ }), isNotEmpty(moreMenuItems) && /*#__PURE__*/React__default.createElement(MoreMenu, {
14401
15192
  editor: editor,
14402
- tooltipContent: tooltips.fontSize || t("neetoEditor.menu.fontSize")
14403
- }), /*#__PURE__*/React__default.createElement("div", {
14404
- className: "neeto-editor-fixed-menu__wrapper__button-group"
14405
- }, fontStyleOptions.map(renderOptionButton)), isAddLinkActive && /*#__PURE__*/React__default.createElement(LinkAddPopOver, {
15193
+ groups: moreMenuItems
15194
+ }), children), !isEmpty(variables) && /*#__PURE__*/React__default.createElement("div", {
15195
+ className: "neeto-editor-fixed-menu__variables",
15196
+ "data-cy": "neeto-editor-fixed-menu-variables"
15197
+ }, /*#__PURE__*/React__default.createElement(DynamicVariables, {
15198
+ variables: variables,
15199
+ dropdownProps: {
15200
+ buttonSize: "small",
15201
+ buttonProps: {
15202
+ tooltipProps: {
15203
+ content: t("neetoEditor.menu.dynamicVariables"),
15204
+ position: "bottom"
15205
+ }
15206
+ }
15207
+ },
15208
+ onVariableClick: handleVariableClick
15209
+ })), isAddLinkActive && /*#__PURE__*/React__default.createElement(LinkAddPopOver, {
14406
15210
  editor: editor,
14407
15211
  isAddLinkActive: isAddLinkActive,
14408
15212
  openLinkInNewTab: openLinkInNewTab,
14409
15213
  setIsAddLinkActive: setIsAddLinkActive
14410
- }), (isMenuExpanded || not(isMenuCollapsible)) && /*#__PURE__*/React__default.createElement("div", {
14411
- className: classnames("neeto-editor-fixed-menu__wrapper--collapsible", {
14412
- "neeto-editor-fixed-menu__wrapper--collapsible--fade": isMenuCollapsible
14413
- })
14414
- }, /*#__PURE__*/React__default.createElement("div", {
14415
- className: "neeto-editor-fixed-menu__wrapper__button-group"
14416
- }, listStyleOptions.map(renderOptionButton)), /*#__PURE__*/React__default.createElement("div", {
14417
- className: "neeto-editor-fixed-menu__wrapper__button-group"
14418
- }, blockStyleOptions.map(renderOptionButton)), /*#__PURE__*/React__default.createElement("div", {
14419
- className: "neeto-editor-fixed-menu__wrapper__button-group"
14420
- }, isTableActive && /*#__PURE__*/React__default.createElement(TableOption, {
14421
- editor: editor,
14422
- tooltipContent: tooltips.table || t("neetoEditor.menu.table")
14423
- }), miscOptions.map(renderOptionButton), isTextColorOptionActive && /*#__PURE__*/React__default.createElement(TextColorOption, {
14424
- editor: editor,
14425
- tooltipContent: tooltips.textColor || t("neetoEditor.menu.textColor")
14426
- }), isEmojiActive && /*#__PURE__*/React__default.createElement(EmojiOption, {
14427
- editor: editor,
14428
- isActive: isEmojiPickerActive,
14429
- setActive: setIsEmojiPickerActive,
14430
- tooltipContent: tooltips.emoji || t("neetoEditor.menu.emoji")
14431
15214
  }), isMediaUploaderActive && /*#__PURE__*/React__default.createElement(MediaUploader, {
14432
15215
  editor: editor,
14433
15216
  mediaUploader: mediaUploader,
@@ -14442,38 +15225,7 @@ var Fixed = function Fixed(_ref) {
14442
15225
  editor: editor,
14443
15226
  isEmbedModalOpen: isEmbedModalOpen,
14444
15227
  setIsEmbedModalOpen: setIsEmbedModalOpen
14445
- }), /*#__PURE__*/React__default.createElement(Mentions, {
14446
- editor: editor,
14447
- mentions: mentions,
14448
- tooltipContent: tooltips.mention || t("neetoEditor.menu.mention")
14449
- }), addonCommandOptions.map(renderOptionButton)), children), isMenuCollapsible && /*#__PURE__*/React__default.createElement(Button$1, {
14450
- className: "neeto-editor-fixed-menu__item",
14451
- "data-cy": "neeto-editor-fixed-menu-arrow",
14452
- icon: isMenuExpanded ? Left : Right,
14453
- style: "text",
14454
- tooltipProps: {
14455
- content: isMenuExpanded ? t("neetoEditor.menu.collapse") : t("neetoEditor.menu.expand"),
14456
- position: "bottom"
14457
- },
14458
- onClick: function onClick() {
14459
- return setIsMenuExpanded(not);
14460
- }
14461
- })), !isEmpty(variables) && /*#__PURE__*/React__default.createElement("div", {
14462
- className: "neeto-editor-fixed-menu__variables",
14463
- "data-cy": "neeto-editor-fixed-menu-variables"
14464
- }, /*#__PURE__*/React__default.createElement(DynamicVariables, {
14465
- variables: variables,
14466
- dropdownProps: {
14467
- buttonSize: "small",
14468
- buttonProps: {
14469
- tooltipProps: {
14470
- content: t("neetoEditor.menu.dynamicVariables"),
14471
- position: "bottom"
14472
- }
14473
- }
14474
- },
14475
- onVariableClick: handleVariableClick
14476
- })));
15228
+ }));
14477
15229
  };
14478
15230
 
14479
15231
  var _excluded$1 = ["icon", "onClick", "disabled", "className", "tooltipProps"];
@@ -14949,5 +15701,5 @@ var Menu = function Menu(props) {
14949
15701
  }));
14950
15702
  };
14951
15703
 
14952
- export { highlightFocussedNode as A, resetFocussedNode as B, findParentNodeClosestToPos as C, DecorationSet as D, Extension as E, BubbleMenu as F, getMarkType as G, getMarkRange as H, InputRule as I, useEditor as J, EditorContent as K, MediaUploader as L, Menu as M, Node as N, EmbedOption as O, PasteRule as P, EditorView as Q, ReactNodeViewRenderer as R, Mark as a, markInputRule as b, markPasteRule as c, Decoration as d, callOrReturn as e, getExtensionField as f, getMarkAttributes as g, findChildren as h, isMacOS as i, NodeViewWrapper as j, keydownHandler as k, NodeViewContent as l, mergeAttributes as m, nodeInputRule as n, escapeForRegEx as o, ReactRenderer as p, EmojiPickerMenu as q, emojiPickerApi as r, combineTransactionSteps as s, textblockTypeInputRule as t, getChangedRanges as u, validateUrl as v, wrappingInputRule as w, getMarksBetween as x, findChildrenInRange as y, getAttributes as z };
14953
- //# sourceMappingURL=chunk-e82a361e.js.map
15704
+ export { getLinkPopoverPosition as A, BubbleMenu as B, getMarkType as C, DecorationSet as D, Extension as E, getMarkRange as F, useEditor as G, EditorContent as H, InputRule as I, MediaUploader as J, EmbedOption as K, EditorView as L, Menu as M, Node as N, PasteRule as P, ReactNodeViewRenderer as R, Mark as a, markInputRule as b, markPasteRule as c, Decoration as d, callOrReturn as e, getExtensionField as f, getMarkAttributes as g, findChildren as h, NodeViewWrapper as i, NodeViewContent as j, keydownHandler as k, escapeForRegEx as l, mergeAttributes as m, nodeInputRule as n, ReactRenderer as o, EmojiPickerMenu as p, emojiPickerApi as q, combineTransactionSteps as r, getChangedRanges as s, textblockTypeInputRule as t, findChildrenInRange as u, validateUrl as v, wrappingInputRule as w, getMarksBetween as x, getAttributes as y, findParentNodeClosestToPos as z };
15705
+ //# sourceMappingURL=chunk-0da548f5.js.map