@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.
@@ -18,6 +18,7 @@ var neetoIcons = require('@bigbinary/neeto-icons');
18
18
  var neetoui = require('@bigbinary/neetoui');
19
19
  var reactI18next = require('react-i18next');
20
20
  var utils$1 = require('@bigbinary/neeto-commons-frontend/utils');
21
+ var i18n = require('i18next');
21
22
  var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
22
23
  var _classCallCheck$1 = require('@babel/runtime/helpers/classCallCheck');
23
24
  var _createClass$1 = require('@babel/runtime/helpers/createClass');
@@ -29,11 +30,10 @@ var emojiMart = require('emoji-mart');
29
30
  var axios = require('axios');
30
31
  var reactUtils = require('@bigbinary/neeto-commons-frontend/react-utils');
31
32
  var reactColorful = require('react-colorful');
32
- var i18n = require('i18next');
33
+ var _objectWithoutProperties$1 = require('@babel/runtime/helpers/objectWithoutProperties');
33
34
  var DynamicVariables = require('@bigbinary/neeto-molecules/DynamicVariables');
34
35
  var useUppyUploader = require('./chunk-7f205514.cjs.js');
35
36
  var _commonjsHelpers = require('./chunk-1b36f0ca.cjs.js');
36
- var _objectWithoutProperties$1 = require('@babel/runtime/helpers/objectWithoutProperties');
37
37
  var Tippy = require('@tippyjs/react');
38
38
 
39
39
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -46,6 +46,7 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
46
46
  var tippy__default = /*#__PURE__*/_interopDefaultLegacy(tippy);
47
47
  var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
48
48
  var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
49
+ var i18n__default = /*#__PURE__*/_interopDefaultLegacy(i18n);
49
50
  var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator);
50
51
  var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck$1);
51
52
  var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass$1);
@@ -54,9 +55,8 @@ var _getPrototypeOf__default = /*#__PURE__*/_interopDefaultLegacy(_getPrototypeO
54
55
  var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits$1);
55
56
  var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime);
56
57
  var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
57
- var i18n__default = /*#__PURE__*/_interopDefaultLegacy(i18n);
58
- var DynamicVariables__default = /*#__PURE__*/_interopDefaultLegacy(DynamicVariables);
59
58
  var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties$1);
59
+ var DynamicVariables__default = /*#__PURE__*/_interopDefaultLegacy(DynamicVariables);
60
60
  var Tippy__default = /*#__PURE__*/_interopDefaultLegacy(Tippy);
61
61
 
62
62
  const domIndex = function (node) {
@@ -6670,6 +6670,11 @@ function sinkListItem$1(itemType) {
6670
6670
  };
6671
6671
  }
6672
6672
 
6673
+ /**
6674
+ * Takes a Transaction & Editor State and turns it into a chainable state object
6675
+ * @param config The transaction and state to create the chainable state from
6676
+ * @returns A chainable Editor state object
6677
+ */
6673
6678
  function createChainableState(config) {
6674
6679
  const { state, transaction } = config;
6675
6680
  let { selection } = transaction;
@@ -6836,6 +6841,13 @@ class EventEmitter {
6836
6841
  }
6837
6842
  }
6838
6843
 
6844
+ /**
6845
+ * Returns a field from an extension
6846
+ * @param extension The Tiptap extension
6847
+ * @param field The field, for example `renderHTML` or `priority`
6848
+ * @param context The context object that should be passed as `this` into the function
6849
+ * @returns The field value
6850
+ */
6839
6851
  function getExtensionField(extension, field, context) {
6840
6852
  if (extension.config[field] === undefined && extension.parent) {
6841
6853
  return getExtensionField(extension.parent, field, context);
@@ -7080,6 +7092,12 @@ function cleanUpSchemaItem(data) {
7080
7092
  return value !== null && value !== undefined;
7081
7093
  }));
7082
7094
  }
7095
+ /**
7096
+ * Creates a new Prosemirror schema based on the given extensions.
7097
+ * @param extensions An array of Tiptap extensions
7098
+ * @param editor The editor instance
7099
+ * @returns A Prosemirror schema
7100
+ */
7083
7101
  function getSchemaByResolvedExtensions(extensions, editor) {
7084
7102
  var _a;
7085
7103
  const allAttributes = getAttributesFromExtensions(extensions);
@@ -7181,6 +7199,12 @@ function getSchemaByResolvedExtensions(extensions, editor) {
7181
7199
  });
7182
7200
  }
7183
7201
 
7202
+ /**
7203
+ * Tries to get a node or mark type by its name.
7204
+ * @param name The name of the node or mark type
7205
+ * @param schema The Prosemiror schema to search in
7206
+ * @returns The node or mark type, or null if it doesn't exist
7207
+ */
7184
7208
  function getSchemaTypeByName(name, schema) {
7185
7209
  return schema.nodes[name] || schema.marks[name] || null;
7186
7210
  }
@@ -7197,6 +7221,12 @@ function isExtensionRulesEnabled(extension, enabled) {
7197
7221
  return enabled;
7198
7222
  }
7199
7223
 
7224
+ /**
7225
+ * Returns the text content of a resolved prosemirror position
7226
+ * @param $from The resolved position to get the text content from
7227
+ * @param maxMatch The maximum number of characters to match
7228
+ * @returns The text content
7229
+ */
7200
7230
  const getTextContentFromNodes = ($from, maxMatch = 500) => {
7201
7231
  let textBefore = '';
7202
7232
  const sliceEndPos = $from.parentOffset;
@@ -7404,6 +7434,10 @@ function isNumber(value) {
7404
7434
  return typeof value === 'number';
7405
7435
  }
7406
7436
 
7437
+ /**
7438
+ * Paste rules are used to react to pasted content.
7439
+ * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
7440
+ */
7407
7441
  class PasteRule {
7408
7442
  constructor(config) {
7409
7443
  this.find = config.find;
@@ -7602,57 +7636,14 @@ class ExtensionManager {
7602
7636
  this.editor = editor;
7603
7637
  this.extensions = ExtensionManager.resolve(extensions);
7604
7638
  this.schema = getSchemaByResolvedExtensions(this.extensions, editor);
7605
- this.extensions.forEach(extension => {
7606
- var _a;
7607
- // store extension storage in editor
7608
- this.editor.extensionStorage[extension.name] = extension.storage;
7609
- const context = {
7610
- name: extension.name,
7611
- options: extension.options,
7612
- storage: extension.storage,
7613
- editor: this.editor,
7614
- type: getSchemaTypeByName(extension.name, this.schema),
7615
- };
7616
- if (extension.type === 'mark') {
7617
- const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, 'keepOnSplit', context))) !== null && _a !== void 0 ? _a : true;
7618
- if (keepOnSplit) {
7619
- this.splittableMarks.push(extension.name);
7620
- }
7621
- }
7622
- const onBeforeCreate = getExtensionField(extension, 'onBeforeCreate', context);
7623
- if (onBeforeCreate) {
7624
- this.editor.on('beforeCreate', onBeforeCreate);
7625
- }
7626
- const onCreate = getExtensionField(extension, 'onCreate', context);
7627
- if (onCreate) {
7628
- this.editor.on('create', onCreate);
7629
- }
7630
- const onUpdate = getExtensionField(extension, 'onUpdate', context);
7631
- if (onUpdate) {
7632
- this.editor.on('update', onUpdate);
7633
- }
7634
- const onSelectionUpdate = getExtensionField(extension, 'onSelectionUpdate', context);
7635
- if (onSelectionUpdate) {
7636
- this.editor.on('selectionUpdate', onSelectionUpdate);
7637
- }
7638
- const onTransaction = getExtensionField(extension, 'onTransaction', context);
7639
- if (onTransaction) {
7640
- this.editor.on('transaction', onTransaction);
7641
- }
7642
- const onFocus = getExtensionField(extension, 'onFocus', context);
7643
- if (onFocus) {
7644
- this.editor.on('focus', onFocus);
7645
- }
7646
- const onBlur = getExtensionField(extension, 'onBlur', context);
7647
- if (onBlur) {
7648
- this.editor.on('blur', onBlur);
7649
- }
7650
- const onDestroy = getExtensionField(extension, 'onDestroy', context);
7651
- if (onDestroy) {
7652
- this.editor.on('destroy', onDestroy);
7653
- }
7654
- });
7639
+ this.setupExtensions();
7655
7640
  }
7641
+ /**
7642
+ * Returns a flattened and sorted extension list while
7643
+ * also checking for duplicated extensions and warns the user.
7644
+ * @param extensions An array of Tiptap extensions
7645
+ * @returns An flattened and sorted array of Tiptap extensions
7646
+ */
7656
7647
  static resolve(extensions) {
7657
7648
  const resolvedExtensions = ExtensionManager.sort(ExtensionManager.flatten(extensions));
7658
7649
  const duplicatedNames = findDuplicates(resolvedExtensions.map(extension => extension.name));
@@ -7663,6 +7654,11 @@ class ExtensionManager {
7663
7654
  }
7664
7655
  return resolvedExtensions;
7665
7656
  }
7657
+ /**
7658
+ * Create a flattened array of extensions by traversing the `addExtensions` field.
7659
+ * @param extensions An array of Tiptap extensions
7660
+ * @returns A flattened array of Tiptap extensions
7661
+ */
7666
7662
  static flatten(extensions) {
7667
7663
  return (extensions
7668
7664
  .map(extension => {
@@ -7680,6 +7676,11 @@ class ExtensionManager {
7680
7676
  // `Infinity` will break TypeScript so we set a number that is probably high enough
7681
7677
  .flat(10));
7682
7678
  }
7679
+ /**
7680
+ * Sort extensions by priority.
7681
+ * @param extensions An array of Tiptap extensions
7682
+ * @returns A sorted array of Tiptap extensions by priority
7683
+ */
7683
7684
  static sort(extensions) {
7684
7685
  const defaultPriority = 100;
7685
7686
  return extensions.sort((a, b) => {
@@ -7694,6 +7695,10 @@ class ExtensionManager {
7694
7695
  return 0;
7695
7696
  });
7696
7697
  }
7698
+ /**
7699
+ * Get all commands from the extensions.
7700
+ * @returns An object with all commands where the key is the command name and the value is the command function
7701
+ */
7697
7702
  get commands() {
7698
7703
  return this.extensions.reduce((commands, extension) => {
7699
7704
  const context = {
@@ -7713,6 +7718,10 @@ class ExtensionManager {
7713
7718
  };
7714
7719
  }, {});
7715
7720
  }
7721
+ /**
7722
+ * Get all registered Prosemirror plugins from the extensions.
7723
+ * @returns An array of Prosemirror plugins
7724
+ */
7716
7725
  get plugins() {
7717
7726
  const { editor } = this;
7718
7727
  // With ProseMirror, first plugins within an array are executed first.
@@ -7775,9 +7784,17 @@ class ExtensionManager {
7775
7784
  ...allPlugins,
7776
7785
  ];
7777
7786
  }
7787
+ /**
7788
+ * Get all attributes from the extensions.
7789
+ * @returns An array of attributes
7790
+ */
7778
7791
  get attributes() {
7779
7792
  return getAttributesFromExtensions(this.extensions);
7780
7793
  }
7794
+ /**
7795
+ * Get all node views from the extensions.
7796
+ * @returns An object with all node views where the key is the node name and the value is the node view function
7797
+ */
7781
7798
  get nodeViews() {
7782
7799
  const { editor } = this;
7783
7800
  const { nodeExtensions } = splitExtensions(this.extensions);
@@ -7810,6 +7827,62 @@ class ExtensionManager {
7810
7827
  return [extension.name, nodeview];
7811
7828
  }));
7812
7829
  }
7830
+ /**
7831
+ * Go through all extensions, create extension storages & setup marks
7832
+ * & bind editor event listener.
7833
+ */
7834
+ setupExtensions() {
7835
+ this.extensions.forEach(extension => {
7836
+ var _a;
7837
+ // store extension storage in editor
7838
+ this.editor.extensionStorage[extension.name] = extension.storage;
7839
+ const context = {
7840
+ name: extension.name,
7841
+ options: extension.options,
7842
+ storage: extension.storage,
7843
+ editor: this.editor,
7844
+ type: getSchemaTypeByName(extension.name, this.schema),
7845
+ };
7846
+ if (extension.type === 'mark') {
7847
+ const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, 'keepOnSplit', context))) !== null && _a !== void 0 ? _a : true;
7848
+ if (keepOnSplit) {
7849
+ this.splittableMarks.push(extension.name);
7850
+ }
7851
+ }
7852
+ const onBeforeCreate = getExtensionField(extension, 'onBeforeCreate', context);
7853
+ const onCreate = getExtensionField(extension, 'onCreate', context);
7854
+ const onUpdate = getExtensionField(extension, 'onUpdate', context);
7855
+ const onSelectionUpdate = getExtensionField(extension, 'onSelectionUpdate', context);
7856
+ const onTransaction = getExtensionField(extension, 'onTransaction', context);
7857
+ const onFocus = getExtensionField(extension, 'onFocus', context);
7858
+ const onBlur = getExtensionField(extension, 'onBlur', context);
7859
+ const onDestroy = getExtensionField(extension, 'onDestroy', context);
7860
+ if (onBeforeCreate) {
7861
+ this.editor.on('beforeCreate', onBeforeCreate);
7862
+ }
7863
+ if (onCreate) {
7864
+ this.editor.on('create', onCreate);
7865
+ }
7866
+ if (onUpdate) {
7867
+ this.editor.on('update', onUpdate);
7868
+ }
7869
+ if (onSelectionUpdate) {
7870
+ this.editor.on('selectionUpdate', onSelectionUpdate);
7871
+ }
7872
+ if (onTransaction) {
7873
+ this.editor.on('transaction', onTransaction);
7874
+ }
7875
+ if (onFocus) {
7876
+ this.editor.on('focus', onFocus);
7877
+ }
7878
+ if (onBlur) {
7879
+ this.editor.on('blur', onBlur);
7880
+ }
7881
+ if (onDestroy) {
7882
+ this.editor.on('destroy', onDestroy);
7883
+ }
7884
+ });
7885
+ }
7813
7886
  }
7814
7887
 
7815
7888
  // see: https://github.com/mesqueeb/is-what/blob/88d6e4ca92fb2baab6003c54e02eedf4e729e5ab/src/index.ts
@@ -7843,6 +7916,10 @@ function mergeDeep(target, source) {
7843
7916
  return output;
7844
7917
  }
7845
7918
 
7919
+ /**
7920
+ * The Extension class is the base class for all extensions.
7921
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
7922
+ */
7846
7923
  class Extension {
7847
7924
  constructor(config = {}) {
7848
7925
  this.type = 'extension';
@@ -7880,6 +7957,7 @@ class Extension {
7880
7957
  // return a new instance so we can use the same extension
7881
7958
  // with different calls of `configure`
7882
7959
  const extension = this.extend();
7960
+ extension.parent = this.parent;
7883
7961
  extension.options = mergeDeep(this.options, options);
7884
7962
  extension.storage = callOrReturn(getExtensionField(extension, 'addStorage', {
7885
7963
  name: extension.name,
@@ -7906,19 +7984,25 @@ class Extension {
7906
7984
  }
7907
7985
  }
7908
7986
 
7987
+ /**
7988
+ * Gets the text between two positions in a Prosemirror node
7989
+ * and serializes it using the given text serializers and block separator (see getText)
7990
+ * @param startNode The Prosemirror node to start from
7991
+ * @param range The range of the text to get
7992
+ * @param options Options for the text serializer & block separator
7993
+ * @returns The text between the two positions
7994
+ */
7909
7995
  function getTextBetween(startNode, range, options) {
7910
7996
  const { from, to } = range;
7911
7997
  const { blockSeparator = '\n\n', textSerializers = {} } = options || {};
7912
7998
  let text = '';
7913
- let separated = true;
7914
7999
  startNode.nodesBetween(from, to, (node, pos, parent, index) => {
7915
8000
  var _a;
8001
+ if (node.isBlock && pos > from) {
8002
+ text += blockSeparator;
8003
+ }
7916
8004
  const textSerializer = textSerializers === null || textSerializers === void 0 ? void 0 : textSerializers[node.type.name];
7917
8005
  if (textSerializer) {
7918
- if (node.isBlock && !separated) {
7919
- text += blockSeparator;
7920
- separated = true;
7921
- }
7922
8006
  if (parent) {
7923
8007
  text += textSerializer({
7924
8008
  node,
@@ -7933,16 +8017,16 @@ function getTextBetween(startNode, range, options) {
7933
8017
  }
7934
8018
  if (node.isText) {
7935
8019
  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
7936
- separated = false;
7937
- }
7938
- else if (node.isBlock && !separated) {
7939
- text += blockSeparator;
7940
- separated = true;
7941
8020
  }
7942
8021
  });
7943
8022
  return text;
7944
8023
  }
7945
8024
 
8025
+ /**
8026
+ * Find text serializers `toText` in a Prosemirror schema
8027
+ * @param schema The Prosemirror schema to search in
8028
+ * @returns A record of text serializers by node name
8029
+ */
7946
8030
  function getTextSerializersFromSchema(schema) {
7947
8031
  return Object.fromEntries(Object.entries(schema.nodes)
7948
8032
  .filter(([, node]) => node.spec.toText)
@@ -8325,15 +8409,26 @@ function elementFromString(value) {
8325
8409
  return removeWhitespaces(html);
8326
8410
  }
8327
8411
 
8412
+ /**
8413
+ * Takes a JSON or HTML content and creates a Prosemirror node or fragment from it.
8414
+ * @param content The JSON or HTML content to create the node from
8415
+ * @param schema The Prosemirror schema to use for the node
8416
+ * @param options Options for the parser
8417
+ * @returns The created Prosemirror node or fragment
8418
+ */
8328
8419
  function createNodeFromContent(content, schema, options) {
8329
8420
  options = {
8330
8421
  slice: true,
8331
8422
  parseOptions: {},
8332
8423
  ...options,
8333
8424
  };
8334
- if (typeof content === 'object' && content !== null) {
8425
+ const isJSONContent = typeof content === 'object' && content !== null;
8426
+ const isTextContent = typeof content === 'string';
8427
+ if (isJSONContent) {
8335
8428
  try {
8336
- if (Array.isArray(content) && content.length > 0) {
8429
+ const isArrayContent = Array.isArray(content) && content.length > 0;
8430
+ // if the JSON Content is an array of nodes, create a fragment for each node
8431
+ if (isArrayContent) {
8337
8432
  return utils.Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)));
8338
8433
  }
8339
8434
  return schema.nodeFromJSON(content);
@@ -8343,7 +8438,7 @@ function createNodeFromContent(content, schema, options) {
8343
8438
  return createNodeFromContent('', schema, options);
8344
8439
  }
8345
8440
  }
8346
- if (typeof content === 'string') {
8441
+ if (isTextContent) {
8347
8442
  const parser = utils.DOMParser.fromSchema(schema);
8348
8443
  return options.slice
8349
8444
  ? parser.parseSlice(elementFromString(content), options.parseOptions).content
@@ -8643,6 +8738,12 @@ const newlineInCode = () => ({ state, dispatch }) => {
8643
8738
  return newlineInCode$1(state, dispatch);
8644
8739
  };
8645
8740
 
8741
+ /**
8742
+ * Get the type of a schema item by its name.
8743
+ * @param name The name of the schema item
8744
+ * @param schema The Prosemiror schema to search in
8745
+ * @returns The type of the schema item (`node` or `mark`), or null if it doesn't exist
8746
+ */
8646
8747
  function getSchemaTypeNameByName(name, schema) {
8647
8748
  if (schema.nodes[name]) {
8648
8749
  return 'node';
@@ -8740,6 +8841,13 @@ const selectTextblockStart = () => ({ state, dispatch }) => {
8740
8841
  return selectTextblockStart$1(state, dispatch);
8741
8842
  };
8742
8843
 
8844
+ /**
8845
+ * Create a new Prosemirror document node from content.
8846
+ * @param content The JSON or HTML content to create the document from
8847
+ * @param schema The Prosemirror schema to use for the document
8848
+ * @param parseOptions Options for the parser
8849
+ * @returns The created Prosemirror document node
8850
+ */
8743
8851
  function createDocument(content, schema, parseOptions = {}) {
8744
8852
  return createNodeFromContent(content, schema, { slice: false, parseOptions });
8745
8853
  }
@@ -8777,6 +8885,9 @@ function getMarkAttributes(state, typeOrName) {
8777
8885
 
8778
8886
  /**
8779
8887
  * Returns a new `Transform` based on all steps of the passed transactions.
8888
+ * @param oldDoc The Prosemirror node to start from
8889
+ * @param transactions The transactions to combine
8890
+ * @returns A new `Transform` with all steps of the passed transactions
8780
8891
  */
8781
8892
  function combineTransactionSteps(oldDoc, transactions) {
8782
8893
  const transform = new utils.Transform(oldDoc);
@@ -8788,6 +8899,11 @@ function combineTransactionSteps(oldDoc, transactions) {
8788
8899
  return transform;
8789
8900
  }
8790
8901
 
8902
+ /**
8903
+ * Gets the default block type at a given match
8904
+ * @param match The content match to get the default block type from
8905
+ * @returns The default block type or null
8906
+ */
8791
8907
  function defaultBlockAt(match) {
8792
8908
  for (let i = 0; i < match.edgeCount; i += 1) {
8793
8909
  const { type } = match.edge(i);
@@ -8798,6 +8914,12 @@ function defaultBlockAt(match) {
8798
8914
  return null;
8799
8915
  }
8800
8916
 
8917
+ /**
8918
+ * Find children inside a Prosemirror node that match a predicate.
8919
+ * @param node The Prosemirror node to search in
8920
+ * @param predicate The predicate to match
8921
+ * @returns An array of nodes with their positions
8922
+ */
8801
8923
  function findChildren(node, predicate) {
8802
8924
  const nodesWithPos = [];
8803
8925
  node.descendants((child, pos) => {
@@ -8813,6 +8935,10 @@ function findChildren(node, predicate) {
8813
8935
 
8814
8936
  /**
8815
8937
  * Same as `findChildren` but searches only within a `range`.
8938
+ * @param node The Prosemirror node to search in
8939
+ * @param range The range to search in
8940
+ * @param predicate The predicate to match
8941
+ * @returns An array of nodes with their positions
8816
8942
  */
8817
8943
  function findChildrenInRange(node, range, predicate) {
8818
8944
  const nodesWithPos = [];
@@ -8836,6 +8962,15 @@ function findChildrenInRange(node, range, predicate) {
8836
8962
  return nodesWithPos;
8837
8963
  }
8838
8964
 
8965
+ /**
8966
+ * Finds the closest parent node to a resolved position that matches a predicate.
8967
+ * @param $pos The resolved position to search from
8968
+ * @param predicate The predicate to match
8969
+ * @returns The closest parent node to the resolved position that matches the predicate
8970
+ * @example ```js
8971
+ * findParentNodeClosestToPos($from, node => node.type.name === 'paragraph')
8972
+ * ```
8973
+ */
8839
8974
  function findParentNodeClosestToPos($pos, predicate) {
8840
8975
  for (let i = $pos.depth; i > 0; i -= 1) {
8841
8976
  const node = $pos.node(i);
@@ -8850,6 +8985,14 @@ function findParentNodeClosestToPos($pos, predicate) {
8850
8985
  }
8851
8986
  }
8852
8987
 
8988
+ /**
8989
+ * Finds the closest parent node to the current selection that matches a predicate.
8990
+ * @param predicate The predicate to match
8991
+ * @returns A command that finds the closest parent node to the current selection that matches the predicate
8992
+ * @example ```js
8993
+ * findParentNode(node => node.type.name === 'paragraph')
8994
+ * ```
8995
+ */
8853
8996
  function findParentNode(predicate) {
8854
8997
  return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
8855
8998
  }
@@ -8862,6 +9005,15 @@ function getHTMLFromFragment(fragment, schema) {
8862
9005
  return container.innerHTML;
8863
9006
  }
8864
9007
 
9008
+ /**
9009
+ * Gets the text of a Prosemirror node
9010
+ * @param node The Prosemirror node
9011
+ * @param options Options for the text serializer & block separator
9012
+ * @returns The text of the node
9013
+ * @example ```js
9014
+ * const text = getText(node, { blockSeparator: '\n' })
9015
+ * ```
9016
+ */
8865
9017
  function getText(node, options) {
8866
9018
  const range = {
8867
9019
  from: 0,
@@ -8884,6 +9036,12 @@ function getNodeAttributes(state, typeOrName) {
8884
9036
  return { ...node.attrs };
8885
9037
  }
8886
9038
 
9039
+ /**
9040
+ * Get node or mark attributes by type or name on the current editor state
9041
+ * @param state The current editor state
9042
+ * @param typeOrName The node or mark type or name
9043
+ * @returns The attributes of the node or mark or an empty object
9044
+ */
8887
9045
  function getAttributes(state, typeOrName) {
8888
9046
  const schemaType = getSchemaTypeNameByName(typeof typeOrName === 'string' ? typeOrName : typeOrName.name, state.schema);
8889
9047
  if (schemaType === 'node') {
@@ -9005,6 +9163,13 @@ function getMarksBetween(from, to, doc) {
9005
9163
  return marks;
9006
9164
  }
9007
9165
 
9166
+ /**
9167
+ * Return attributes of an extension that should be splitted by keepOnSplit flag
9168
+ * @param extensionAttributes Array of extension attributes
9169
+ * @param typeName The type of the extension
9170
+ * @param attributes The attributes of the extension
9171
+ * @returns The splitted attributes
9172
+ */
9008
9173
  function getSplittedAttributes(extensionAttributes, typeName, attributes) {
9009
9174
  return Object.fromEntries(Object
9010
9175
  .entries(attributes)
@@ -9828,7 +9993,12 @@ const Keymap = Extension.create({
9828
9993
  const isAtStart = (parentIsIsolating && $parentPos.parent.childCount === 1)
9829
9994
  ? parentPos === $anchor.pos
9830
9995
  : utils.Selection.atStart(doc).from === pos;
9831
- if (!empty || !isAtStart || !parent.type.isTextblock || parent.textContent.length) {
9996
+ if (!empty
9997
+ || !parent.type.isTextblock
9998
+ || parent.textContent.length
9999
+ || !isAtStart
10000
+ || (isAtStart && $anchor.parent.type.name === 'paragraph') // prevent clearNodes when no nodes to clear, otherwise history stack is appended
10001
+ ) {
9832
10002
  return false;
9833
10003
  }
9834
10004
  return commands.clearNodes();
@@ -10080,28 +10250,30 @@ class NodePos {
10080
10250
  }
10081
10251
  querySelectorAll(selector, attributes = {}, firstItemOnly = false) {
10082
10252
  let nodes = [];
10083
- // iterate through children recursively finding all nodes which match the selector with the node name
10084
10253
  if (!this.children || this.children.length === 0) {
10085
10254
  return nodes;
10086
10255
  }
10256
+ const attrKeys = Object.keys(attributes);
10257
+ /**
10258
+ * Finds all children recursively that match the selector and attributes
10259
+ * If firstItemOnly is true, it will return the first item found
10260
+ */
10087
10261
  this.children.forEach(childPos => {
10262
+ // If we already found a node and we only want the first item, we dont need to keep going
10263
+ if (firstItemOnly && nodes.length > 0) {
10264
+ return;
10265
+ }
10088
10266
  if (childPos.node.type.name === selector) {
10089
- if (Object.keys(attributes).length > 0) {
10090
- const nodeAttributes = childPos.node.attrs;
10091
- const attrKeys = Object.keys(attributes);
10092
- for (let index = 0; index < attrKeys.length; index += 1) {
10093
- const key = attrKeys[index];
10094
- if (nodeAttributes[key] !== attributes[key]) {
10095
- return;
10096
- }
10097
- }
10098
- }
10099
- nodes.push(childPos);
10100
- if (firstItemOnly) {
10101
- return;
10267
+ const doesAllAttributesMatch = attrKeys.every(key => attributes[key] === childPos.node.attrs[key]);
10268
+ if (doesAllAttributesMatch) {
10269
+ nodes.push(childPos);
10102
10270
  }
10103
10271
  }
10104
- nodes = nodes.concat(childPos.querySelectorAll(selector));
10272
+ // If we already found a node and we only want the first item, we can stop here and skip the recursion
10273
+ if (firstItemOnly && nodes.length > 0) {
10274
+ return;
10275
+ }
10276
+ nodes = nodes.concat(childPos.querySelectorAll(selector, attributes, firstItemOnly));
10105
10277
  });
10106
10278
  return nodes;
10107
10279
  }
@@ -10588,6 +10760,7 @@ class Editor$1 extends EventEmitter {
10588
10760
  /**
10589
10761
  * Build an input rule that adds a mark when the
10590
10762
  * matched text is typed into it.
10763
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
10591
10764
  */
10592
10765
  function markInputRule(config) {
10593
10766
  return new InputRule({
@@ -10631,6 +10804,7 @@ function markInputRule(config) {
10631
10804
  /**
10632
10805
  * Build an input rule that adds a node when the
10633
10806
  * matched text is typed into it.
10807
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
10634
10808
  */
10635
10809
  function nodeInputRule(config) {
10636
10810
  return new InputRule({
@@ -10669,6 +10843,7 @@ function nodeInputRule(config) {
10669
10843
  * matched text is typed into it. When using a regular expresion you’ll
10670
10844
  * probably want the regexp to start with `^`, so that the pattern can
10671
10845
  * only occur at the start of a textblock.
10846
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
10672
10847
  */
10673
10848
  function textblockTypeInputRule(config) {
10674
10849
  return new InputRule({
@@ -10699,6 +10874,7 @@ function textblockTypeInputRule(config) {
10699
10874
  * two nodes. You can pass a join predicate, which takes a regular
10700
10875
  * expression match and the node before the wrapped node, and can
10701
10876
  * return a boolean to indicate whether a join should happen.
10877
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
10702
10878
  */
10703
10879
  function wrappingInputRule(config) {
10704
10880
  return new InputRule({
@@ -10738,6 +10914,10 @@ function wrappingInputRule(config) {
10738
10914
  });
10739
10915
  }
10740
10916
 
10917
+ /**
10918
+ * The Mark class is used to create custom mark extensions.
10919
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
10920
+ */
10741
10921
  class Mark {
10742
10922
  constructor(config = {}) {
10743
10923
  this.type = 'mark';
@@ -10821,6 +11001,10 @@ class Mark {
10821
11001
  }
10822
11002
  }
10823
11003
 
11004
+ /**
11005
+ * The Node class is used to create custom node extensions.
11006
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
11007
+ */
10824
11008
  class Node {
10825
11009
  constructor(config = {}) {
10826
11010
  this.type = 'node';
@@ -10888,6 +11072,10 @@ function isAndroid() {
10888
11072
  return navigator.platform === 'Android' || /android/i.test(navigator.userAgent);
10889
11073
  }
10890
11074
 
11075
+ /**
11076
+ * Node views are used to customize the rendered DOM structure of a node.
11077
+ * @see https://tiptap.dev/guide/node-views
11078
+ */
10891
11079
  class NodeView {
10892
11080
  constructor(component, props, options) {
10893
11081
  this.isDragging = false;
@@ -11078,6 +11266,7 @@ class NodeView {
11078
11266
  /**
11079
11267
  * Build an paste rule that adds a mark when the
11080
11268
  * matched text is pasted into it.
11269
+ * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
11081
11270
  */
11082
11271
  function markPasteRule(config) {
11083
11272
  return new PasteRule({
@@ -11299,6 +11488,10 @@ const BubbleMenuPlugin = (options) => {
11299
11488
  });
11300
11489
  };
11301
11490
 
11491
+ /**
11492
+ * This extension allows you to create a bubble menu.
11493
+ * @see https://tiptap.dev/api/extensions/bubble-menu
11494
+ */
11302
11495
  Extension.create({
11303
11496
  name: 'bubbleMenu',
11304
11497
  addOptions() {
@@ -11327,41 +11520,20 @@ Extension.create({
11327
11520
  },
11328
11521
  });
11329
11522
 
11330
- const BubbleMenu = (props) => {
11331
- const [element, setElement] = React.useState(null);
11332
- React.useEffect(() => {
11333
- if (!element) {
11334
- return;
11335
- }
11336
- if (props.editor.isDestroyed) {
11337
- return;
11338
- }
11339
- const { pluginKey = 'bubbleMenu', editor, tippyOptions = {}, shouldShow = null, } = props;
11340
- const plugin = BubbleMenuPlugin({
11341
- pluginKey,
11342
- editor,
11343
- element,
11344
- tippyOptions,
11345
- shouldShow,
11523
+ const mergeRefs = (...refs) => {
11524
+ return (node) => {
11525
+ refs.forEach(ref => {
11526
+ if (typeof ref === 'function') {
11527
+ ref(node);
11528
+ }
11529
+ else if (ref) {
11530
+ ref.current = node;
11531
+ }
11346
11532
  });
11347
- editor.registerPlugin(plugin);
11348
- return () => editor.unregisterPlugin(pluginKey);
11349
- }, [
11350
- props.editor,
11351
- element,
11352
- ]);
11353
- return (React__default["default"].createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
11354
- };
11355
-
11356
- class Editor extends Editor$1 {
11357
- constructor() {
11358
- super(...arguments);
11359
- this.contentComponent = null;
11360
- }
11361
- }
11362
-
11533
+ };
11534
+ };
11363
11535
  const Portals = ({ renderers }) => {
11364
- return (React__default["default"].createElement(React__default["default"].Fragment, null, Array.from(renderers).map(([key, renderer]) => {
11536
+ return (React__default["default"].createElement(React__default["default"].Fragment, null, Object.entries(renderers).map(([key, renderer]) => {
11365
11537
  return ReactDOM__default["default"].createPortal(renderer.reactElement, renderer.element, key);
11366
11538
  })));
11367
11539
  };
@@ -11369,8 +11541,9 @@ class PureEditorContent extends React__default["default"].Component {
11369
11541
  constructor(props) {
11370
11542
  super(props);
11371
11543
  this.editorContentRef = React__default["default"].createRef();
11544
+ this.initialized = false;
11372
11545
  this.state = {
11373
- renderers: new Map(),
11546
+ renderers: {},
11374
11547
  };
11375
11548
  }
11376
11549
  componentDidMount() {
@@ -11392,13 +11565,46 @@ class PureEditorContent extends React__default["default"].Component {
11392
11565
  });
11393
11566
  editor.contentComponent = this;
11394
11567
  editor.createNodeViews();
11568
+ this.initialized = true;
11569
+ }
11570
+ }
11571
+ maybeFlushSync(fn) {
11572
+ // Avoid calling flushSync until the editor is initialized.
11573
+ // Initialization happens during the componentDidMount or componentDidUpdate
11574
+ // lifecycle methods, and React doesn't allow calling flushSync from inside
11575
+ // a lifecycle method.
11576
+ if (this.initialized) {
11577
+ ReactDOM.flushSync(fn);
11578
+ }
11579
+ else {
11580
+ fn();
11395
11581
  }
11396
11582
  }
11583
+ setRenderer(id, renderer) {
11584
+ this.maybeFlushSync(() => {
11585
+ this.setState(({ renderers }) => ({
11586
+ renderers: {
11587
+ ...renderers,
11588
+ [id]: renderer,
11589
+ },
11590
+ }));
11591
+ });
11592
+ }
11593
+ removeRenderer(id) {
11594
+ this.maybeFlushSync(() => {
11595
+ this.setState(({ renderers }) => {
11596
+ const nextRenderers = { ...renderers };
11597
+ delete nextRenderers[id];
11598
+ return { renderers: nextRenderers };
11599
+ });
11600
+ });
11601
+ }
11397
11602
  componentWillUnmount() {
11398
11603
  const { editor } = this.props;
11399
11604
  if (!editor) {
11400
11605
  return;
11401
11606
  }
11607
+ this.initialized = false;
11402
11608
  if (!editor.isDestroyed) {
11403
11609
  editor.view.setProps({
11404
11610
  nodeViews: {},
@@ -11415,49 +11621,213 @@ class PureEditorContent extends React__default["default"].Component {
11415
11621
  });
11416
11622
  }
11417
11623
  render() {
11418
- const { editor, ...rest } = this.props;
11624
+ const { editor, innerRef, ...rest } = this.props;
11419
11625
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
11420
- React__default["default"].createElement("div", { ref: this.editorContentRef, ...rest }),
11626
+ React__default["default"].createElement("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }),
11421
11627
  React__default["default"].createElement(Portals, { renderers: this.state.renderers })));
11422
11628
  }
11423
11629
  }
11424
- const EditorContent = React__default["default"].memo(PureEditorContent);
11425
-
11426
- const ReactNodeViewContext = React.createContext({
11427
- onDragStart: undefined,
11630
+ // EditorContent should be re-created whenever the Editor instance changes
11631
+ const EditorContentWithKey = React.forwardRef((props, ref) => {
11632
+ const key = React__default["default"].useMemo(() => {
11633
+ return Math.floor(Math.random() * 0xFFFFFFFF).toString();
11634
+ }, [props.editor]);
11635
+ // Can't use JSX here because it conflicts with the type definition of Vue's JSX, so use createElement
11636
+ return React__default["default"].createElement(PureEditorContent, {
11637
+ key,
11638
+ innerRef: ref,
11639
+ ...props,
11640
+ });
11428
11641
  });
11429
- const useReactNodeView = () => React.useContext(ReactNodeViewContext);
11430
-
11431
- const NodeViewContent = props => {
11432
- const Tag = props.as || 'div';
11433
- const { nodeViewContentRef } = useReactNodeView();
11434
- return (React__default["default"].createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
11435
- whiteSpace: 'pre-wrap',
11436
- ...props.style,
11437
- } }));
11438
- };
11642
+ const EditorContent = React__default["default"].memo(EditorContentWithKey);
11439
11643
 
11440
- const NodeViewWrapper = React__default["default"].forwardRef((props, ref) => {
11441
- const { onDragStart } = useReactNodeView();
11442
- const Tag = props.as || 'div';
11443
- return (React__default["default"].createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
11444
- whiteSpace: 'normal',
11445
- ...props.style,
11446
- } }));
11447
- });
11644
+ class Editor extends Editor$1 {
11645
+ constructor() {
11646
+ super(...arguments);
11647
+ this.contentComponent = null;
11648
+ }
11649
+ }
11448
11650
 
11651
+ /**
11652
+ * This hook allows you to create an editor instance.
11653
+ * @param options The editor options
11654
+ * @param deps The dependencies to watch for changes
11655
+ * @returns The editor instance
11656
+ * @example const editor = useEditor({ extensions: [...] })
11657
+ */
11658
+ const useEditor = (options = {}, deps = []) => {
11659
+ const editorRef = React.useRef(null);
11660
+ const [, forceUpdate] = React.useState({});
11661
+ const { onBeforeCreate, onBlur, onCreate, onDestroy, onFocus, onSelectionUpdate, onTransaction, onUpdate, } = options;
11662
+ const onBeforeCreateRef = React.useRef(onBeforeCreate);
11663
+ const onBlurRef = React.useRef(onBlur);
11664
+ const onCreateRef = React.useRef(onCreate);
11665
+ const onDestroyRef = React.useRef(onDestroy);
11666
+ const onFocusRef = React.useRef(onFocus);
11667
+ const onSelectionUpdateRef = React.useRef(onSelectionUpdate);
11668
+ const onTransactionRef = React.useRef(onTransaction);
11669
+ const onUpdateRef = React.useRef(onUpdate);
11670
+ // This effect will handle updating the editor instance
11671
+ // when the event handlers change.
11672
+ React.useEffect(() => {
11673
+ if (!editorRef.current) {
11674
+ return;
11675
+ }
11676
+ if (onBeforeCreate) {
11677
+ editorRef.current.off('beforeCreate', onBeforeCreateRef.current);
11678
+ editorRef.current.on('beforeCreate', onBeforeCreate);
11679
+ onBeforeCreateRef.current = onBeforeCreate;
11680
+ }
11681
+ if (onBlur) {
11682
+ editorRef.current.off('blur', onBlurRef.current);
11683
+ editorRef.current.on('blur', onBlur);
11684
+ onBlurRef.current = onBlur;
11685
+ }
11686
+ if (onCreate) {
11687
+ editorRef.current.off('create', onCreateRef.current);
11688
+ editorRef.current.on('create', onCreate);
11689
+ onCreateRef.current = onCreate;
11690
+ }
11691
+ if (onDestroy) {
11692
+ editorRef.current.off('destroy', onDestroyRef.current);
11693
+ editorRef.current.on('destroy', onDestroy);
11694
+ onDestroyRef.current = onDestroy;
11695
+ }
11696
+ if (onFocus) {
11697
+ editorRef.current.off('focus', onFocusRef.current);
11698
+ editorRef.current.on('focus', onFocus);
11699
+ onFocusRef.current = onFocus;
11700
+ }
11701
+ if (onSelectionUpdate) {
11702
+ editorRef.current.off('selectionUpdate', onSelectionUpdateRef.current);
11703
+ editorRef.current.on('selectionUpdate', onSelectionUpdate);
11704
+ onSelectionUpdateRef.current = onSelectionUpdate;
11705
+ }
11706
+ if (onTransaction) {
11707
+ editorRef.current.off('transaction', onTransactionRef.current);
11708
+ editorRef.current.on('transaction', onTransaction);
11709
+ onTransactionRef.current = onTransaction;
11710
+ }
11711
+ if (onUpdate) {
11712
+ editorRef.current.off('update', onUpdateRef.current);
11713
+ editorRef.current.on('update', onUpdate);
11714
+ onUpdateRef.current = onUpdate;
11715
+ }
11716
+ }, [onBeforeCreate, onBlur, onCreate, onDestroy, onFocus, onSelectionUpdate, onTransaction, onUpdate, editorRef.current]);
11717
+ React.useEffect(() => {
11718
+ let isMounted = true;
11719
+ const editor = new Editor(options);
11720
+ editorRef.current = editor;
11721
+ editorRef.current.on('transaction', () => {
11722
+ requestAnimationFrame(() => {
11723
+ requestAnimationFrame(() => {
11724
+ if (isMounted) {
11725
+ forceUpdate({});
11726
+ }
11727
+ });
11728
+ });
11729
+ });
11730
+ return () => {
11731
+ isMounted = false;
11732
+ editor.destroy();
11733
+ };
11734
+ }, deps);
11735
+ return editorRef.current;
11736
+ };
11737
+
11738
+ const EditorContext = React.createContext({
11739
+ editor: null,
11740
+ });
11741
+ EditorContext.Consumer;
11742
+ const useCurrentEditor = () => React.useContext(EditorContext);
11743
+
11744
+ const BubbleMenu = (props) => {
11745
+ const [element, setElement] = React.useState(null);
11746
+ const { editor: currentEditor } = useCurrentEditor();
11747
+ React.useEffect(() => {
11748
+ var _a;
11749
+ if (!element) {
11750
+ return;
11751
+ }
11752
+ if (((_a = props.editor) === null || _a === void 0 ? void 0 : _a.isDestroyed) || (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.isDestroyed)) {
11753
+ return;
11754
+ }
11755
+ const { pluginKey = 'bubbleMenu', editor, tippyOptions = {}, updateDelay, shouldShow = null, } = props;
11756
+ const menuEditor = editor || currentEditor;
11757
+ if (!menuEditor) {
11758
+ console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.');
11759
+ return;
11760
+ }
11761
+ const plugin = BubbleMenuPlugin({
11762
+ updateDelay,
11763
+ editor: menuEditor,
11764
+ element,
11765
+ pluginKey,
11766
+ shouldShow,
11767
+ tippyOptions,
11768
+ });
11769
+ menuEditor.registerPlugin(plugin);
11770
+ return () => menuEditor.unregisterPlugin(pluginKey);
11771
+ }, [props.editor, currentEditor, element]);
11772
+ return (React__default["default"].createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
11773
+ };
11774
+
11775
+ const ReactNodeViewContext = React.createContext({
11776
+ onDragStart: undefined,
11777
+ });
11778
+ const useReactNodeView = () => React.useContext(ReactNodeViewContext);
11779
+
11780
+ const NodeViewContent = props => {
11781
+ const Tag = props.as || 'div';
11782
+ const { nodeViewContentRef } = useReactNodeView();
11783
+ return (React__default["default"].createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
11784
+ whiteSpace: 'pre-wrap',
11785
+ ...props.style,
11786
+ } }));
11787
+ };
11788
+
11789
+ const NodeViewWrapper = React__default["default"].forwardRef((props, ref) => {
11790
+ const { onDragStart } = useReactNodeView();
11791
+ const Tag = props.as || 'div';
11792
+ return (React__default["default"].createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
11793
+ whiteSpace: 'normal',
11794
+ ...props.style,
11795
+ } }));
11796
+ });
11797
+
11798
+ /**
11799
+ * Check if a component is a class component.
11800
+ * @param Component
11801
+ * @returns {boolean}
11802
+ */
11449
11803
  function isClassComponent(Component) {
11450
11804
  return !!(typeof Component === 'function'
11451
11805
  && Component.prototype
11452
11806
  && Component.prototype.isReactComponent);
11453
11807
  }
11808
+ /**
11809
+ * Check if a component is a forward ref component.
11810
+ * @param Component
11811
+ * @returns {boolean}
11812
+ */
11454
11813
  function isForwardRefComponent(Component) {
11455
11814
  var _a;
11456
11815
  return !!(typeof Component === 'object'
11457
11816
  && ((_a = Component.$$typeof) === null || _a === void 0 ? void 0 : _a.toString()) === 'Symbol(react.forward_ref)');
11458
11817
  }
11818
+ /**
11819
+ * The ReactRenderer class. It's responsible for rendering React components inside the editor.
11820
+ * @example
11821
+ * new ReactRenderer(MyComponent, {
11822
+ * editor,
11823
+ * props: {
11824
+ * foo: 'bar',
11825
+ * },
11826
+ * as: 'span',
11827
+ * })
11828
+ */
11459
11829
  class ReactRenderer {
11460
- constructor(component, { editor, props = {}, as = 'div', className = '', }) {
11830
+ constructor(component, { editor, props = {}, as = 'div', className = '', attrs, }) {
11461
11831
  this.ref = null;
11462
11832
  this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString();
11463
11833
  this.component = component;
@@ -11468,9 +11838,15 @@ class ReactRenderer {
11468
11838
  if (className) {
11469
11839
  this.element.classList.add(...className.split(' '));
11470
11840
  }
11841
+ if (attrs) {
11842
+ Object.keys(attrs).forEach(key => {
11843
+ this.element.setAttribute(key, attrs[key]);
11844
+ });
11845
+ }
11471
11846
  this.render();
11472
11847
  }
11473
11848
  render() {
11849
+ var _a, _b;
11474
11850
  const Component = this.component;
11475
11851
  const props = this.props;
11476
11852
  if (isClassComponent(Component) || isForwardRefComponent(Component)) {
@@ -11479,16 +11855,7 @@ class ReactRenderer {
11479
11855
  };
11480
11856
  }
11481
11857
  this.reactElement = React__default["default"].createElement(Component, { ...props });
11482
- queueMicrotask(() => {
11483
- ReactDOM.flushSync(() => {
11484
- var _a;
11485
- if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) {
11486
- this.editor.contentComponent.setState({
11487
- renderers: this.editor.contentComponent.state.renderers.set(this.id, this),
11488
- });
11489
- }
11490
- });
11491
- });
11858
+ (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.setRenderer(this.id, this);
11492
11859
  }
11493
11860
  updateProps(props = {}) {
11494
11861
  this.props = {
@@ -11498,18 +11865,8 @@ class ReactRenderer {
11498
11865
  this.render();
11499
11866
  }
11500
11867
  destroy() {
11501
- queueMicrotask(() => {
11502
- ReactDOM.flushSync(() => {
11503
- var _a;
11504
- if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) {
11505
- const { renderers } = this.editor.contentComponent.state;
11506
- renderers.delete(this.id);
11507
- this.editor.contentComponent.setState({
11508
- renderers,
11509
- });
11510
- }
11511
- });
11512
- });
11868
+ var _a, _b;
11869
+ (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.removeRenderer(this.id);
11513
11870
  }
11514
11871
  }
11515
11872
 
@@ -11539,13 +11896,20 @@ class ReactNodeView extends NodeView {
11539
11896
  element.appendChild(this.contentDOMElement);
11540
11897
  }
11541
11898
  };
11542
- return (React__default["default"].createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } },
11543
- React__default["default"].createElement(Component, { ...componentProps })));
11899
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
11900
+ React__default["default"].createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } },
11901
+ React__default["default"].createElement(Component, { ...componentProps }))));
11544
11902
  };
11545
11903
  ReactNodeViewProvider.displayName = 'ReactNodeView';
11546
- this.contentDOMElement = this.node.isLeaf
11547
- ? null
11548
- : document.createElement(this.node.isInline ? 'span' : 'div');
11904
+ if (this.node.isLeaf) {
11905
+ this.contentDOMElement = null;
11906
+ }
11907
+ else if (this.options.contentDOMElementTag) {
11908
+ this.contentDOMElement = document.createElement(this.options.contentDOMElementTag);
11909
+ }
11910
+ else {
11911
+ this.contentDOMElement = document.createElement(this.node.isInline ? 'span' : 'div');
11912
+ }
11549
11913
  if (this.contentDOMElement) {
11550
11914
  // For some reason the whiteSpace prop is not inherited properly in Chrome and Safari
11551
11915
  // With this fix it seems to work fine
@@ -11557,11 +11921,14 @@ class ReactNodeView extends NodeView {
11557
11921
  as = this.options.as;
11558
11922
  }
11559
11923
  const { className = '' } = this.options;
11924
+ this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
11925
+ this.editor.on('selectionUpdate', this.handleSelectionUpdate);
11560
11926
  this.renderer = new ReactRenderer(ReactNodeViewProvider, {
11561
11927
  editor: this.editor,
11562
11928
  props,
11563
11929
  as,
11564
11930
  className: `node-${this.node.type.name} ${className}`.trim(),
11931
+ attrs: this.options.attrs,
11565
11932
  });
11566
11933
  }
11567
11934
  get dom() {
@@ -11578,6 +11945,21 @@ class ReactNodeView extends NodeView {
11578
11945
  }
11579
11946
  return this.contentDOMElement;
11580
11947
  }
11948
+ handleSelectionUpdate() {
11949
+ const { from, to } = this.editor.state.selection;
11950
+ if (from <= this.getPos() && to >= this.getPos() + this.node.nodeSize) {
11951
+ if (this.renderer.props.selected) {
11952
+ return;
11953
+ }
11954
+ this.selectNode();
11955
+ }
11956
+ else {
11957
+ if (!this.renderer.props.selected) {
11958
+ return;
11959
+ }
11960
+ this.deselectNode();
11961
+ }
11962
+ }
11581
11963
  update(node, decorations) {
11582
11964
  const updateProps = (props) => {
11583
11965
  this.renderer.updateProps(props);
@@ -11610,14 +11992,17 @@ class ReactNodeView extends NodeView {
11610
11992
  this.renderer.updateProps({
11611
11993
  selected: true,
11612
11994
  });
11995
+ this.renderer.element.classList.add('ProseMirror-selectednode');
11613
11996
  }
11614
11997
  deselectNode() {
11615
11998
  this.renderer.updateProps({
11616
11999
  selected: false,
11617
12000
  });
12001
+ this.renderer.element.classList.remove('ProseMirror-selectednode');
11618
12002
  }
11619
12003
  destroy() {
11620
12004
  this.renderer.destroy();
12005
+ this.editor.off('selectionUpdate', this.handleSelectionUpdate);
11621
12006
  this.contentDOMElement = null;
11622
12007
  }
11623
12008
  }
@@ -11633,34 +12018,6 @@ function ReactNodeViewRenderer(component, options) {
11633
12018
  };
11634
12019
  }
11635
12020
 
11636
- function useForceUpdate() {
11637
- const [, setValue] = React.useState(0);
11638
- return () => setValue(value => value + 1);
11639
- }
11640
- const useEditor = (options = {}, deps = []) => {
11641
- const [editor, setEditor] = React.useState(null);
11642
- const forceUpdate = useForceUpdate();
11643
- React.useEffect(() => {
11644
- let isMounted = true;
11645
- const instance = new Editor(options);
11646
- setEditor(instance);
11647
- instance.on('transaction', () => {
11648
- requestAnimationFrame(() => {
11649
- requestAnimationFrame(() => {
11650
- if (isMounted) {
11651
- forceUpdate();
11652
- }
11653
- });
11654
- });
11655
- });
11656
- return () => {
11657
- instance.destroy();
11658
- isMounted = false;
11659
- };
11660
- }, deps);
11661
- return editor;
11662
- };
11663
-
11664
12021
  var validateUrl = function validateUrl(url) {
11665
12022
  return url ? validateNeetoRecordUrl(url) || validateYouTubeUrl(url) || validateLoomUrl(url) || validateVimeoUrl(url) : false;
11666
12023
  };
@@ -11774,8 +12131,8 @@ var emojiPickerApi = {
11774
12131
  fetch: fetch
11775
12132
  };
11776
12133
 
11777
- 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; }
11778
- 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__default["default"](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; }
12134
+ 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; }
12135
+ 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__default["default"](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; }
11779
12136
  function _callSuper(t, o, e) { return o = _getPrototypeOf__default["default"](o), _possibleConstructorReturn__default["default"](t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf__default["default"](t).constructor) : o.apply(t, e)); }
11780
12137
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
11781
12138
  var EmojiPickerMenu = /*#__PURE__*/function (_React$Component) {
@@ -11827,7 +12184,7 @@ var EmojiPickerMenu = /*#__PURE__*/function (_React$Component) {
11827
12184
  return _createClass__default["default"](EmojiPickerMenu, [{
11828
12185
  key: "componentDidMount",
11829
12186
  value: function componentDidMount() {
11830
- new emojiMart.Picker(_objectSpread$5(_objectSpread$5({}, this.props), {}, {
12187
+ new emojiMart.Picker(_objectSpread$7(_objectSpread$7({}, this.props), {}, {
11831
12188
  onEmojiSelect: this.handleSelect,
11832
12189
  style: {
11833
12190
  maxWidth: "100%"
@@ -11873,59 +12230,829 @@ var generateFocusProps = function generateFocusProps() {
11873
12230
  return highlight ? focusProps : {};
11874
12231
  };
11875
12232
 
11876
- 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; }
11877
- 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__default["default"](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; }
11878
- var Progress = function Progress(_ref) {
11879
- var uppy = _ref.uppy,
11880
- pendingUploads = _ref.pendingUploads,
11881
- setPendingUploads = _ref.setPendingUploads;
11882
- var _useTranslation = reactI18next.useTranslation(),
11883
- t = _useTranslation.t;
11884
- var handleUploadProgress = function handleUploadProgress(file, progress) {
11885
- setPendingUploads(function (prevState) {
11886
- return prevState.map(function (uploadingFile) {
11887
- return _objectSpread$4(_objectSpread$4({}, uploadingFile), {}, {
11888
- progress: uploadingFile.filename !== file.name ? uploadingFile.progress : progress.progress
11889
- });
12233
+ var MenuButton = function MenuButton(_ref) {
12234
+ var icon = _ref.icon,
12235
+ command = _ref.command,
12236
+ optionName = _ref.optionName,
12237
+ highlight = _ref.highlight,
12238
+ disabled = _ref.disabled,
12239
+ label = _ref.label,
12240
+ editor = _ref.editor;
12241
+ return /*#__PURE__*/React__default["default"].createElement(neetoui.Button, _extends__default["default"]({
12242
+ disabled: disabled,
12243
+ icon: icon,
12244
+ className: "neeto-editor-fixed-menu__item",
12245
+ "data-cy": "neeto-editor-fixed-menu-".concat(optionName, "-option"),
12246
+ style: editor.isActive(optionName) ? "secondary" : "text",
12247
+ tabIndex: "-1",
12248
+ tooltipProps: {
12249
+ content: label,
12250
+ position: "bottom"
12251
+ },
12252
+ onClick: command
12253
+ }, generateFocusProps(highlight)));
12254
+ };
12255
+
12256
+ var MenuItem$3 = neetoui.Dropdown.MenuItem;
12257
+ var SecondaryMenuTarget = function SecondaryMenuTarget(_ref) {
12258
+ var Icon = _ref.icon,
12259
+ label = _ref.label;
12260
+ return /*#__PURE__*/React__default["default"].createElement(MenuItem$3.Button, null, /*#__PURE__*/React__default["default"].createElement(Icon, null), " ", label);
12261
+ };
12262
+
12263
+ var EmojiOption = function EmojiOption(_ref) {
12264
+ var editor = _ref.editor,
12265
+ isActive = _ref.isActive,
12266
+ setActive = _ref.setActive,
12267
+ tooltipContent = _ref.tooltipContent,
12268
+ _ref$isSecondaryMenu = _ref.isSecondaryMenu,
12269
+ isSecondaryMenu = _ref$isSecondaryMenu === void 0 ? false : _ref$isSecondaryMenu,
12270
+ label = _ref.label;
12271
+ return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
12272
+ buttonStyle: "text",
12273
+ closeOnSelect: false,
12274
+ dropdownProps: {
12275
+ classNames: "neeto-editor-fixed-menu__emoji-dropdown"
12276
+ },
12277
+ icon: neetoIcons.Smiley,
12278
+ isOpen: isActive,
12279
+ position: isSecondaryMenu ? "left-start" : "bottom-start",
12280
+ strategy: "fixed",
12281
+ buttonProps: {
12282
+ tabIndex: -1,
12283
+ tooltipProps: {
12284
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label,
12285
+ position: "bottom"
12286
+ },
12287
+ className: "neeto-editor-fixed-menu__item"
12288
+ },
12289
+ customTarget: isSecondaryMenu && /*#__PURE__*/React__default["default"].createElement(SecondaryMenuTarget, {
12290
+ label: label,
12291
+ icon: neetoIcons.Smiley
12292
+ }),
12293
+ onClose: function onClose() {
12294
+ return setActive(false);
12295
+ },
12296
+ onClick: function onClick(e) {
12297
+ setActive(function (active) {
12298
+ return !active;
11890
12299
  });
12300
+ isSecondaryMenu && e.stopPropagation();
12301
+ }
12302
+ }, /*#__PURE__*/React__default["default"].createElement(EmojiPickerMenu, {
12303
+ editor: editor,
12304
+ setActive: setActive
12305
+ }));
12306
+ };
12307
+
12308
+ var Menu$4 = neetoui.Dropdown.Menu,
12309
+ MenuItem$2 = neetoui.Dropdown.MenuItem;
12310
+ var FontSizeOption = function FontSizeOption(_ref) {
12311
+ var editor = _ref.editor,
12312
+ tooltipContent = _ref.tooltipContent,
12313
+ label = _ref.label;
12314
+ var dropdownRef = React.useRef(null);
12315
+ var isActive = function isActive(level) {
12316
+ return editor.isActive("heading", {
12317
+ level: level
11891
12318
  });
11892
12319
  };
11893
- var removeUploadingFile = function removeUploadingFile(id) {
11894
- uppy.removeFile(id);
11895
- setPendingUploads(function (prevState) {
11896
- return neetoCist.removeById(id, prevState);
11897
- });
12320
+ var activeOption = FONT_SIZE_OPTIONS.find(function (_ref2) {
12321
+ var value = _ref2.value;
12322
+ return isActive(value);
12323
+ }) || ramda.last(FONT_SIZE_OPTIONS);
12324
+ var handleClick = function handleClick(level) {
12325
+ return level ? editor.chain().focus().toggleHeading({
12326
+ level: level
12327
+ }).run() : editor.chain().focus().setNode("paragraph").run();
11898
12328
  };
11899
- React.useEffect(function () {
11900
- uppy.on("upload-progress", handleUploadProgress);
11901
- return function () {
11902
- uppy.off("upload-progress", handleUploadProgress);
11903
- };
11904
- }, [uppy]);
11905
- return /*#__PURE__*/React__default["default"].createElement("div", {
11906
- className: "ne-media-uploader__wrapper"
11907
- }, pendingUploads.map(function (_ref2) {
11908
- var id = _ref2.id,
11909
- filename = _ref2.filename,
11910
- progress = _ref2.progress;
11911
- return /*#__PURE__*/React__default["default"].createElement("div", {
11912
- className: "ne-media-uploader__media",
11913
- key: id
11914
- }, /*#__PURE__*/React__default["default"].createElement("div", {
11915
- className: "ne-media-uploader__media__info"
11916
- }, /*#__PURE__*/React__default["default"].createElement(neetoui.Typography, {
11917
- style: "body2"
11918
- }, filename), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
11919
- "data-cy": "neeto-editor-image-upload-cancel-button",
11920
- icon: neetoIcons.Close,
11921
- size: "small",
12329
+ return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
12330
+ autoWidth: true,
12331
+ "data-cy": "neeto-editor-fixed-menu-font-size-option",
12332
+ label: activeOption === null || activeOption === void 0 ? void 0 : activeOption.label,
12333
+ placement: "bottom-start",
12334
+ strategy: "fixed",
12335
+ buttonProps: {
12336
+ ref: dropdownRef,
12337
+ onKeyDown: function onKeyDown(event) {
12338
+ var _dropdownRef$current;
12339
+ return event.key === "ArrowDown" && ((_dropdownRef$current = dropdownRef.current) === null || _dropdownRef$current === void 0 ? void 0 : _dropdownRef$current.click());
12340
+ },
12341
+ tooltipProps: {
12342
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label,
12343
+ position: "bottom"
12344
+ },
11922
12345
  style: "text",
12346
+ size: "small",
12347
+ className: "neeto-editor-fixed-menu__item neeto-editor-font-size__wrapper"
12348
+ }
12349
+ }, /*#__PURE__*/React__default["default"].createElement(Menu$4, {
12350
+ onKeyDown: function onKeyDown(event) {
12351
+ var _editor$commands;
12352
+ return event.key === "Escape" && ((_editor$commands = editor.commands) === null || _editor$commands === void 0 ? void 0 : _editor$commands.focus());
12353
+ }
12354
+ }, FONT_SIZE_OPTIONS.map(function (_ref3) {
12355
+ var label = _ref3.label,
12356
+ value = _ref3.value,
12357
+ key = _ref3.key;
12358
+ return /*#__PURE__*/React__default["default"].createElement(MenuItem$2.Button, {
12359
+ "data-cy": "neeto-editor-fixed-menu-font-size-option-".concat(key),
12360
+ key: value,
11923
12361
  onClick: function onClick() {
11924
- return removeUploadingFile(id);
12362
+ return handleClick(value);
11925
12363
  }
11926
- })), progress !== 100 ? /*#__PURE__*/React__default["default"].createElement("div", {
11927
- className: "ne-media-uploader__media__progress"
11928
- }, /*#__PURE__*/React__default["default"].createElement("div", {
12364
+ }, /*#__PURE__*/React__default["default"].createElement(neetoui.Typography, {
12365
+ style: key
12366
+ }, label));
12367
+ })));
12368
+ };
12369
+
12370
+ var Menu$3 = neetoui.Dropdown.Menu;
12371
+ var TableOption$1 = function TableOption(_ref) {
12372
+ var editor = _ref.editor,
12373
+ tooltipContent = _ref.tooltipContent,
12374
+ _ref$isSecondaryMenu = _ref.isSecondaryMenu,
12375
+ isSecondaryMenu = _ref$isSecondaryMenu === void 0 ? false : _ref$isSecondaryMenu,
12376
+ label = _ref.label;
12377
+ var _useTranslation = reactI18next.useTranslation(),
12378
+ t = _useTranslation.t;
12379
+ var _useState = React.useState(false),
12380
+ _useState2 = _slicedToArray__default["default"](_useState, 2),
12381
+ isOpen = _useState2[0],
12382
+ setIsOpen = _useState2[1];
12383
+ var _useState3 = React.useState(3),
12384
+ _useState4 = _slicedToArray__default["default"](_useState3, 2),
12385
+ rows = _useState4[0],
12386
+ setRows = _useState4[1];
12387
+ var _useState5 = React.useState(3),
12388
+ _useState6 = _slicedToArray__default["default"](_useState5, 2),
12389
+ columns = _useState6[0],
12390
+ setColumns = _useState6[1];
12391
+ var handleClose = function handleClose() {
12392
+ setRows(3);
12393
+ setColumns(3);
12394
+ setIsOpen(false);
12395
+ };
12396
+ var handleSubmit = function handleSubmit() {
12397
+ editor.chain().focus().insertTable({
12398
+ rows: rows,
12399
+ cols: columns,
12400
+ withHeaderRow: true
12401
+ }).run();
12402
+ handleClose();
12403
+ };
12404
+ var handleDropdownClick = function handleDropdownClick(e) {
12405
+ isSecondaryMenu && e.stopPropagation();
12406
+ setIsOpen(ramda.not);
12407
+ };
12408
+ return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
12409
+ isOpen: isOpen,
12410
+ buttonStyle: isOpen ? "secondary" : "text",
12411
+ closeOnSelect: false,
12412
+ "data-cy": "neeto-editor-fixed-menu-link-option",
12413
+ icon: neetoIcons.Column,
12414
+ position: isSecondaryMenu ? "left-start" : "bottom",
12415
+ buttonProps: {
12416
+ tabIndex: -1,
12417
+ tooltipProps: {
12418
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label,
12419
+ position: "bottom"
12420
+ },
12421
+ className: "neeto-editor-fixed-menu__item"
12422
+ },
12423
+ customTarget: isSecondaryMenu && /*#__PURE__*/React__default["default"].createElement(SecondaryMenuTarget, {
12424
+ label: label,
12425
+ icon: neetoIcons.Column
12426
+ }),
12427
+ onClick: handleDropdownClick,
12428
+ onClose: handleClose
12429
+ }, /*#__PURE__*/React__default["default"].createElement(Menu$3, {
12430
+ className: "neeto-editor-table__item"
12431
+ }, /*#__PURE__*/React__default["default"].createElement(neetoui.Input, {
12432
+ autoFocus: true,
12433
+ "data-cy": "neeto-editor-fixed-menu-table-option-input",
12434
+ min: "1",
12435
+ placeholder: t("neetoEditor.placeholders.rows"),
12436
+ size: "small",
12437
+ type: "number",
12438
+ value: rows,
12439
+ onChange: utils$1.withEventTargetValue(setRows)
12440
+ }), /*#__PURE__*/React__default["default"].createElement(neetoui.Input, {
12441
+ "data-cy": "neeto-editor-fixed-menu-table-option-input",
12442
+ min: "1",
12443
+ placeholder: t("neetoEditor.placeholders.rows"),
12444
+ size: "small",
12445
+ type: "number",
12446
+ value: columns,
12447
+ onChange: utils$1.withEventTargetValue(setColumns)
12448
+ }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
12449
+ "data-cy": "neeto-editor-fixed-menu-table-option-create-button",
12450
+ label: t("neetoEditor.common.create"),
12451
+ size: "small",
12452
+ onClick: handleSubmit
12453
+ })));
12454
+ };
12455
+
12456
+ var TextColorOption = function TextColorOption(_ref) {
12457
+ var editor = _ref.editor,
12458
+ tooltipContent = _ref.tooltipContent,
12459
+ _ref$isSecondaryMenu = _ref.isSecondaryMenu,
12460
+ isSecondaryMenu = _ref$isSecondaryMenu === void 0 ? false : _ref$isSecondaryMenu,
12461
+ label = _ref.label;
12462
+ var _useState = React.useState(false),
12463
+ _useState2 = _slicedToArray__default["default"](_useState, 2),
12464
+ isOpen = _useState2[0],
12465
+ setIsOpen = _useState2[1];
12466
+ var _useState3 = React.useState(null),
12467
+ _useState4 = _slicedToArray__default["default"](_useState3, 2),
12468
+ color = _useState4[0],
12469
+ setColor = _useState4[1];
12470
+ var dropdownWrapperRef = React.useRef(null);
12471
+ var _useTranslation = reactI18next.useTranslation(),
12472
+ t = _useTranslation.t;
12473
+ var handleSave = function handleSave() {
12474
+ editor.chain().focus().setColor(color).run();
12475
+ setIsOpen(false);
12476
+ };
12477
+ var handleUnset = function handleUnset() {
12478
+ editor.chain().focus().unsetColor().run();
12479
+ setColor(null);
12480
+ setIsOpen(false);
12481
+ };
12482
+ reactUtils.useOnClickOutside(dropdownWrapperRef, function (event) {
12483
+ if (!isOpen) return;
12484
+ event.preventDefault();
12485
+ editor.commands.focus();
12486
+ setIsOpen(false);
12487
+ });
12488
+ React.useEffect(function () {
12489
+ setColor(editor.getAttributes("textStyle").color);
12490
+ }, [isOpen, editor.getAttributes("textStyle").color]);
12491
+ var openColorPicker = function openColorPicker(e) {
12492
+ isSecondaryMenu && e.stopPropagation();
12493
+ setColor(editor.getAttributes("textStyle").color);
12494
+ setIsOpen(ramda.not);
12495
+ };
12496
+ return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
12497
+ isOpen: isOpen,
12498
+ buttonStyle: isOpen || color ? "secondary" : "text",
12499
+ icon: neetoIcons.Customize,
12500
+ position: isSecondaryMenu ? "left-start" : "bottom-start",
12501
+ buttonProps: {
12502
+ tabIndex: -1,
12503
+ tooltipProps: {
12504
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label
12505
+ },
12506
+ className: "neeto-editor-fixed-menu__item neeto-editor-text-color-option"
12507
+ },
12508
+ customTarget: isSecondaryMenu && /*#__PURE__*/React__default["default"].createElement(SecondaryMenuTarget, {
12509
+ label: label,
12510
+ icon: neetoIcons.Customize
12511
+ }),
12512
+ onClick: openColorPicker
12513
+ }, /*#__PURE__*/React__default["default"].createElement("div", {
12514
+ ref: dropdownWrapperRef,
12515
+ style: {
12516
+ "min-width": "236px"
12517
+ },
12518
+ onClick: function onClick(e) {
12519
+ e.stopPropagation();
12520
+ }
12521
+ }, /*#__PURE__*/React__default["default"].createElement(reactColorful.HexColorPicker, {
12522
+ color: color || "#000000",
12523
+ onChange: setColor
12524
+ }), /*#__PURE__*/React__default["default"].createElement("div", {
12525
+ className: "neeto-editor-text-color-option__options-group"
12526
+ }, /*#__PURE__*/React__default["default"].createElement(neetoui.Input, {
12527
+ autoFocus: true,
12528
+ className: "neeto-editor-text-color-option__options-group__input",
12529
+ placeholder: t("neetoEditor.placeholders.pickColor"),
12530
+ size: "small",
12531
+ value: color,
12532
+ onChange: utils$1.withEventTargetValue(setColor),
12533
+ onClick: function onClick(event) {
12534
+ return event.stopPropagation();
12535
+ }
12536
+ }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
12537
+ icon: neetoIcons.Check,
12538
+ size: "small",
12539
+ onClick: handleSave
12540
+ }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
12541
+ icon: neetoIcons.Close,
12542
+ size: "small",
12543
+ style: "text",
12544
+ onClick: function onClick() {
12545
+ editor.commands.focus();
12546
+ setIsOpen(false);
12547
+ }
12548
+ }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
12549
+ icon: neetoIcons.Refresh,
12550
+ size: "small",
12551
+ style: "text",
12552
+ tooltipProps: {
12553
+ content: t("neetoEditor.common.resetToDefault"),
12554
+ position: "top"
12555
+ },
12556
+ onClick: handleUnset
12557
+ }))));
12558
+ };
12559
+
12560
+ var Menu$2 = neetoui.Dropdown.Menu,
12561
+ MenuItem$1 = neetoui.Dropdown.MenuItem;
12562
+ var Mentions = function Mentions(_ref) {
12563
+ var editor = _ref.editor,
12564
+ mentions = _ref.mentions,
12565
+ tooltipContent = _ref.tooltipContent,
12566
+ _ref$isSecondaryMenu = _ref.isSecondaryMenu,
12567
+ isSecondaryMenu = _ref$isSecondaryMenu === void 0 ? false : _ref$isSecondaryMenu,
12568
+ label = _ref.label;
12569
+ if (ramda.isEmpty(mentions)) return null;
12570
+ return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
12571
+ buttonStyle: "text",
12572
+ "data-cy": "neeto-editor-mention-option",
12573
+ icon: neetoIcons.Email,
12574
+ position: isSecondaryMenu ? "left-start" : "bottom-start",
12575
+ strategy: "fixed",
12576
+ buttonProps: {
12577
+ tooltipProps: {
12578
+ content: tooltipContent !== null && tooltipContent !== void 0 ? tooltipContent : label,
12579
+ position: "bottom"
12580
+ },
12581
+ className: "neeto-editor-fixed-menu__item"
12582
+ },
12583
+ customTarget: isSecondaryMenu && /*#__PURE__*/React__default["default"].createElement(SecondaryMenuTarget, {
12584
+ label: label,
12585
+ icon: neetoIcons.Email
12586
+ }),
12587
+ onClick: function onClick(e) {
12588
+ return isSecondaryMenu && e.stopPropagation();
12589
+ }
12590
+ }, /*#__PURE__*/React__default["default"].createElement(Menu$2, null, mentions.map(function (_ref2) {
12591
+ var key = _ref2.key,
12592
+ name = _ref2.name,
12593
+ imageUrl = _ref2.imageUrl;
12594
+ return /*#__PURE__*/React__default["default"].createElement(MenuItem$1.Button, {
12595
+ "data-cy": "neeto-editor-mention-option-".concat(key),
12596
+ key: key,
12597
+ onClick: function onClick() {
12598
+ return editor.commands.setMention({
12599
+ id: key,
12600
+ label: name
12601
+ });
12602
+ }
12603
+ }, /*#__PURE__*/React__default["default"].createElement(neetoui.Avatar, {
12604
+ size: "small",
12605
+ user: {
12606
+ name: name,
12607
+ imageUrl: imageUrl
12608
+ }
12609
+ }), /*#__PURE__*/React__default["default"].createElement(neetoui.Typography, {
12610
+ style: "body2"
12611
+ }, name));
12612
+ })));
12613
+ };
12614
+
12615
+ var FONT_SIZE_OPTIONS = [{
12616
+ label: i18n.t("neetoEditor.menu.heading1"),
12617
+ value: 1,
12618
+ key: "h1"
12619
+ }, {
12620
+ label: i18n.t("neetoEditor.menu.heading2"),
12621
+ value: 2,
12622
+ key: "h2"
12623
+ }, {
12624
+ label: i18n.t("neetoEditor.menu.heading3"),
12625
+ value: 3,
12626
+ key: "h3"
12627
+ }, {
12628
+ label: i18n.t("neetoEditor.menu.heading4"),
12629
+ value: 4,
12630
+ key: "h4"
12631
+ }, {
12632
+ label: i18n.t("neetoEditor.menu.heading5"),
12633
+ value: 5,
12634
+ key: "h5"
12635
+ }, {
12636
+ label: i18n.t("neetoEditor.menu.normalText"),
12637
+ value: 0,
12638
+ key: "body2"
12639
+ }];
12640
+ var MENU_ELEMENT_TYPES = {
12641
+ BUTTON: "button",
12642
+ FONT_SIZE: "fontSize",
12643
+ TABLE: "table",
12644
+ TEXT_COLOR: "textColor",
12645
+ EMOJI: "emoji",
12646
+ MENTIONS: "mentions"
12647
+ };
12648
+ var MENU_ELEMENTS = _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"]({}, 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);
12649
+ var MENU_ELEMENT_WIDTHS = _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"]({}, 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);
12650
+
12651
+ 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; }
12652
+ 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__default["default"](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; }
12653
+ var createMenuOptions$2 = function createMenuOptions(_ref) {
12654
+ 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;
12655
+ var tooltips = _ref.tooltips,
12656
+ editor = _ref.editor,
12657
+ setMediaUploader = _ref.setMediaUploader,
12658
+ attachmentProps = _ref.attachmentProps,
12659
+ setIsEmbedModalOpen = _ref.setIsEmbedModalOpen,
12660
+ setIsAddLinkActive = _ref.setIsAddLinkActive,
12661
+ options = _ref.options,
12662
+ mentions = _ref.mentions,
12663
+ addonCommandOptions = _ref.addonCommandOptions,
12664
+ setIsEmojiPickerActive = _ref.setIsEmojiPickerActive,
12665
+ isEmojiPickerActive = _ref.isEmojiPickerActive;
12666
+ var fontSizeOptions = options.filter(function (option) {
12667
+ return option.match(/^h[1-6]$/);
12668
+ });
12669
+ return [
12670
+ // history
12671
+ [{
12672
+ icon: neetoIcons.Undo,
12673
+ command: function command() {
12674
+ return editor.chain().focus().undo().run();
12675
+ },
12676
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.UNDO),
12677
+ disabled: !editor.can().undo(),
12678
+ optionName: constants.EDITOR_OPTIONS.UNDO,
12679
+ label: (_tooltips$undo = tooltips.undo) !== null && _tooltips$undo !== void 0 ? _tooltips$undo : i18n.t("neetoEditor.menu.undo"),
12680
+ type: MENU_ELEMENT_TYPES.BUTTON
12681
+ }, {
12682
+ icon: neetoIcons.Redo,
12683
+ command: function command() {
12684
+ return editor.chain().focus().redo().run();
12685
+ },
12686
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.REDO),
12687
+ disabled: !editor.can().redo(),
12688
+ optionName: constants.EDITOR_OPTIONS.REDO,
12689
+ label: (_tooltips$redo = tooltips.redo) !== null && _tooltips$redo !== void 0 ? _tooltips$redo : i18n.t("neetoEditor.menu.redo"),
12690
+ type: MENU_ELEMENT_TYPES.BUTTON
12691
+ }],
12692
+ // font
12693
+ [{
12694
+ type: MENU_ELEMENT_TYPES.FONT_SIZE,
12695
+ options: fontSizeOptions,
12696
+ label: (_tooltips$fontSize = tooltips.fontSize) !== null && _tooltips$fontSize !== void 0 ? _tooltips$fontSize : i18n.t("neetoEditor.menu.fontSize"),
12697
+ isEnabled: neetoCist.isNotEmpty(fontSizeOptions),
12698
+ optionName: "fontSizeOptions"
12699
+ }, {
12700
+ type: MENU_ELEMENT_TYPES.BUTTON,
12701
+ icon: neetoIcons.TextBold,
12702
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.BOLD),
12703
+ command: function command() {
12704
+ return editor.chain().focus().toggleBold().run();
12705
+ },
12706
+ optionName: constants.EDITOR_OPTIONS.BOLD,
12707
+ label: (_tooltips$bold = tooltips.bold) !== null && _tooltips$bold !== void 0 ? _tooltips$bold : i18n.t("neetoEditor.menu.bold")
12708
+ }, {
12709
+ type: MENU_ELEMENT_TYPES.BUTTON,
12710
+ icon: neetoIcons.TextItalic,
12711
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.ITALIC),
12712
+ command: function command() {
12713
+ return editor.chain().focus().toggleItalic().run();
12714
+ },
12715
+ optionName: constants.EDITOR_OPTIONS.ITALIC,
12716
+ label: (_tooltips$italic = tooltips.italic) !== null && _tooltips$italic !== void 0 ? _tooltips$italic : i18n.t("neetoEditor.menu.italic")
12717
+ }, {
12718
+ type: MENU_ELEMENT_TYPES.BUTTON,
12719
+ icon: neetoIcons.Underline,
12720
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.UNDERLINE),
12721
+ command: function command() {
12722
+ return editor.chain().focus().toggleUnderline().run();
12723
+ },
12724
+ optionName: constants.EDITOR_OPTIONS.UNDERLINE,
12725
+ label: (_tooltips$underline = tooltips.underline) !== null && _tooltips$underline !== void 0 ? _tooltips$underline : i18n.t("neetoEditor.menu.underline")
12726
+ }, {
12727
+ type: MENU_ELEMENT_TYPES.BUTTON,
12728
+ icon: neetoIcons.Link,
12729
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.LINK),
12730
+ command: function command() {
12731
+ return setIsAddLinkActive(ramda.not);
12732
+ },
12733
+ optionName: constants.EDITOR_OPTIONS.LINK,
12734
+ label: (_tooltips$link = tooltips.link) !== null && _tooltips$link !== void 0 ? _tooltips$link : i18n.t("neetoEditor.menu.link")
12735
+ }, {
12736
+ type: MENU_ELEMENT_TYPES.BUTTON,
12737
+ icon: neetoIcons.TextCross,
12738
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.STRIKETHROUGH),
12739
+ command: function command() {
12740
+ return editor.chain().focus().toggleStrike().run();
12741
+ },
12742
+ optionName: constants.EDITOR_OPTIONS.STRIKETHROUGH,
12743
+ label: (_tooltips$strike = tooltips.strike) !== null && _tooltips$strike !== void 0 ? _tooltips$strike : i18n.t("neetoEditor.menu.strike")
12744
+ }, {
12745
+ type: MENU_ELEMENT_TYPES.BUTTON,
12746
+ icon: neetoIcons.Highlight,
12747
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.HIGHLIGHT),
12748
+ command: function command() {
12749
+ return editor.chain().focus().toggleHighlight().run();
12750
+ },
12751
+ optionName: constants.EDITOR_OPTIONS.HIGHLIGHT,
12752
+ label: (_tooltips$highlight = tooltips.highlight) !== null && _tooltips$highlight !== void 0 ? _tooltips$highlight : i18n.t("neetoEditor.menu.highlight")
12753
+ }],
12754
+ // list
12755
+ [{
12756
+ type: MENU_ELEMENT_TYPES.BUTTON,
12757
+ icon: neetoIcons.ListDot,
12758
+ command: function command() {
12759
+ return editor.chain().focus().toggleBulletList().run();
12760
+ },
12761
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.LIST_BULLETS),
12762
+ optionName: "bulletList",
12763
+ highlight: true,
12764
+ label: (_tooltips$bulletList = tooltips.bulletList) !== null && _tooltips$bulletList !== void 0 ? _tooltips$bulletList : i18n.t("neetoEditor.menu.bulletedList")
12765
+ }, {
12766
+ type: MENU_ELEMENT_TYPES.BUTTON,
12767
+ icon: neetoIcons.ListNumber,
12768
+ command: function command() {
12769
+ return editor.chain().focus().toggleOrderedList().run();
12770
+ },
12771
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.LIST_ORDERED),
12772
+ optionName: "orderedList",
12773
+ highlight: true,
12774
+ label: (_tooltips$orderedList = tooltips.orderedList) !== null && _tooltips$orderedList !== void 0 ? _tooltips$orderedList : i18n.t("neetoEditor.menu.orderedList")
12775
+ }],
12776
+ // block
12777
+ [{
12778
+ type: MENU_ELEMENT_TYPES.BUTTON,
12779
+ icon: neetoIcons.Quote,
12780
+ command: function command() {
12781
+ return editor.chain().focus().toggleBlockquote().run();
12782
+ },
12783
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.BLOCKQUOTE),
12784
+ optionName: "blockquote",
12785
+ highlight: true,
12786
+ label: (_tooltips$blockQuote = tooltips.blockQuote) !== null && _tooltips$blockQuote !== void 0 ? _tooltips$blockQuote : i18n.t("neetoEditor.menu.blockQuote")
12787
+ }, {
12788
+ type: MENU_ELEMENT_TYPES.BUTTON,
12789
+ icon: neetoIcons.Code,
12790
+ command: function command() {
12791
+ return editor.chain().focus().toggleCode().run();
12792
+ },
12793
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.CODE),
12794
+ optionName: constants.EDITOR_OPTIONS.CODE,
12795
+ label: (_tooltips$code = tooltips.code) !== null && _tooltips$code !== void 0 ? _tooltips$code : i18n.t("neetoEditor.menu.code")
12796
+ }, {
12797
+ type: MENU_ELEMENT_TYPES.BUTTON,
12798
+ icon: neetoIcons.CodeBlock,
12799
+ command: function command() {
12800
+ return editor.chain().focus().toggleCodeBlock().run();
12801
+ },
12802
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.CODE_BLOCK),
12803
+ optionName: "codeBlock",
12804
+ label: (_tooltips$codeBlock = tooltips.codeBlock) !== null && _tooltips$codeBlock !== void 0 ? _tooltips$codeBlock : i18n.t("neetoEditor.menu.codeBlock")
12805
+ }],
12806
+ // misc
12807
+ [{
12808
+ type: MENU_ELEMENT_TYPES.TABLE,
12809
+ label: (_tooltips$table = tooltips.table) !== null && _tooltips$table !== void 0 ? _tooltips$table : i18n.t("neetoEditor.menu.table"),
12810
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.TABLE),
12811
+ optionName: constants.EDITOR_OPTIONS.TABLE
12812
+ }, {
12813
+ type: MENU_ELEMENT_TYPES.BUTTON,
12814
+ icon: neetoIcons.Attachment,
12815
+ command: function command() {
12816
+ return attachmentProps === null || attachmentProps === void 0 ? void 0 : attachmentProps.handleUploadAttachments();
12817
+ },
12818
+ disabled: attachmentProps === null || attachmentProps === void 0 ? void 0 : attachmentProps.isDisabled,
12819
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.ATTACHMENTS),
12820
+ optionName: constants.EDITOR_OPTIONS.ATTACHMENTS,
12821
+ label: (_tooltips$attachments = tooltips.attachments) !== null && _tooltips$attachments !== void 0 ? _tooltips$attachments : i18n.t("neetoEditor.menu.attachments")
12822
+ }, {
12823
+ type: MENU_ELEMENT_TYPES.BUTTON,
12824
+ icon: neetoIcons.ImageUpload,
12825
+ command: function command() {
12826
+ return setMediaUploader(ramda.assoc("image", true));
12827
+ },
12828
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.IMAGE_UPLOAD),
12829
+ optionName: constants.EDITOR_OPTIONS.IMAGE_UPLOAD,
12830
+ label: (_tooltips$imageUpload = tooltips.imageUpload) !== null && _tooltips$imageUpload !== void 0 ? _tooltips$imageUpload : i18n.t("neetoEditor.menu.imageUpload")
12831
+ }, {
12832
+ type: MENU_ELEMENT_TYPES.BUTTON,
12833
+ icon: neetoIcons.Video,
12834
+ command: function command() {
12835
+ return setMediaUploader(ramda.assoc("video", true));
12836
+ },
12837
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.VIDEO_UPLOAD),
12838
+ optionName: constants.EDITOR_OPTIONS.VIDEO_UPLOAD,
12839
+ label: (_tooltips$videoUpload = tooltips.videoUpload) !== null && _tooltips$videoUpload !== void 0 ? _tooltips$videoUpload : i18n.t("neetoEditor.menu.videoUpload")
12840
+ }, {
12841
+ type: MENU_ELEMENT_TYPES.BUTTON,
12842
+ icon: neetoIcons.MediaVideo,
12843
+ command: function command() {
12844
+ return setIsEmbedModalOpen(true);
12845
+ },
12846
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.VIDEO_EMBED),
12847
+ optionName: constants.EDITOR_OPTIONS.VIDEO_EMBED,
12848
+ label: (_tooltips$videoEmbed = tooltips.videoEmbed) !== null && _tooltips$videoEmbed !== void 0 ? _tooltips$videoEmbed : i18n.t("neetoEditor.menu.videoEmbed")
12849
+ }],
12850
+ // extras
12851
+ [{
12852
+ type: MENU_ELEMENT_TYPES.TEXT_COLOR,
12853
+ label: (_tooltips$textColor = tooltips.textColor) !== null && _tooltips$textColor !== void 0 ? _tooltips$textColor : i18n.t("neetoEditor.menu.textColor"),
12854
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.TEXT_COLOR),
12855
+ optionName: constants.EDITOR_OPTIONS.TEXT_COLOR
12856
+ }, {
12857
+ type: MENU_ELEMENT_TYPES.EMOJI,
12858
+ label: (_tooltips$emoji = tooltips.emoji) !== null && _tooltips$emoji !== void 0 ? _tooltips$emoji : i18n.t("neetoEditor.menu.emoji"),
12859
+ isEnabled: options.includes(constants.EDITOR_OPTIONS.EMOJI),
12860
+ optionName: constants.EDITOR_OPTIONS.EMOJI,
12861
+ setActive: setIsEmojiPickerActive,
12862
+ isActive: isEmojiPickerActive
12863
+ }, {
12864
+ type: MENU_ELEMENT_TYPES.MENTIONS,
12865
+ label: (_tooltips$mention = tooltips.mention) !== null && _tooltips$mention !== void 0 ? _tooltips$mention : i18n.t("neetoEditor.menu.mention"),
12866
+ isEnabled: neetoCist.isNotEmpty(mentions),
12867
+ optionName: "mentions",
12868
+ mentions: mentions
12869
+ }], //addons
12870
+ _toConsumableArray__default["default"](addonCommandOptions)];
12871
+ };
12872
+ var buildMenuOptions$1 = function buildMenuOptions(_ref2) {
12873
+ var tooltips = _ref2.tooltips,
12874
+ editor = _ref2.editor,
12875
+ options = _ref2.options,
12876
+ setMediaUploader = _ref2.setMediaUploader,
12877
+ attachmentProps = _ref2.attachmentProps,
12878
+ setIsEmbedModalOpen = _ref2.setIsEmbedModalOpen,
12879
+ setIsAddLinkActive = _ref2.setIsAddLinkActive,
12880
+ mentions = _ref2.mentions,
12881
+ addonCommands = _ref2.addonCommands,
12882
+ setIsEmojiPickerActive = _ref2.setIsEmojiPickerActive,
12883
+ isEmojiPickerActive = _ref2.isEmojiPickerActive;
12884
+ if (!editor) return [];
12885
+ var addonCommandOptions = buildOptionsFromAddonCommands({
12886
+ editor: editor,
12887
+ commands: addonCommands
12888
+ });
12889
+ var menuOptions = createMenuOptions$2({
12890
+ tooltips: tooltips,
12891
+ editor: editor,
12892
+ setMediaUploader: setMediaUploader,
12893
+ attachmentProps: attachmentProps,
12894
+ setIsEmbedModalOpen: setIsEmbedModalOpen,
12895
+ setIsAddLinkActive: setIsAddLinkActive,
12896
+ options: options,
12897
+ mentions: mentions,
12898
+ addonCommandOptions: addonCommandOptions,
12899
+ setIsEmojiPickerActive: setIsEmojiPickerActive,
12900
+ isEmojiPickerActive: isEmojiPickerActive
12901
+ });
12902
+ return menuOptions.map(function (option) {
12903
+ return option.filter(ramda.prop("isEnabled"));
12904
+ });
12905
+ };
12906
+ var buildOptionsFromAddonCommands = function buildOptionsFromAddonCommands(_ref3) {
12907
+ var editor = _ref3.editor,
12908
+ commands = _ref3.commands;
12909
+ var to = editor.state.selection.to;
12910
+ return commands.map(function (option) {
12911
+ var _option$active;
12912
+ return _objectSpread$6(_objectSpread$6({}, option), {}, {
12913
+ type: MENU_ELEMENT_TYPES.BUTTON,
12914
+ active: (_option$active = option.active) === null || _option$active === void 0 ? void 0 : _option$active.call(option, {
12915
+ editor: editor
12916
+ }),
12917
+ command: function command() {
12918
+ var _option$command;
12919
+ return (_option$command = option.command) === null || _option$command === void 0 ? void 0 : _option$command.call(option, {
12920
+ editor: editor,
12921
+ range: {
12922
+ from: to,
12923
+ to: to
12924
+ }
12925
+ });
12926
+ }
12927
+ });
12928
+ });
12929
+ };
12930
+ var getCursorPos = function getCursorPos(editor, to) {
12931
+ return editor === null || editor === void 0 ? void 0 : editor.view.coordsAtPos(to);
12932
+ };
12933
+ var reGroupMenuItems = function reGroupMenuItems(menuRef, menuGroups) {
12934
+ var toolbarWidth = menuRef.current.offsetWidth;
12935
+ var totalWidth = 0;
12936
+ var visibleMenuGroups = [];
12937
+ var invisibleMenuGroups = [];
12938
+ menuGroups.forEach(function (group, groupIndex) {
12939
+ group.forEach(function (item, itemIndex) {
12940
+ var width = MENU_ELEMENT_WIDTHS[item.type];
12941
+ if (totalWidth + width < toolbarWidth) {
12942
+ var _visibleMenuGroups$gr;
12943
+ totalWidth += width;
12944
+ visibleMenuGroups[groupIndex] = (_visibleMenuGroups$gr = visibleMenuGroups[groupIndex]) !== null && _visibleMenuGroups$gr !== void 0 ? _visibleMenuGroups$gr : [];
12945
+ visibleMenuGroups[groupIndex][itemIndex] = item;
12946
+ } else {
12947
+ var _invisibleMenuGroups$;
12948
+ var visibleMenuGroupsLength = visibleMenuGroups.length;
12949
+ var index = groupIndex - visibleMenuGroupsLength + 1;
12950
+ invisibleMenuGroups[index] = (_invisibleMenuGroups$ = invisibleMenuGroups[index]) !== null && _invisibleMenuGroups$ !== void 0 ? _invisibleMenuGroups$ : [];
12951
+ invisibleMenuGroups[index][itemIndex] = item;
12952
+ }
12953
+ });
12954
+ });
12955
+ return {
12956
+ visibleMenuGroups: visibleMenuGroups,
12957
+ invisibleMenuGroups: invisibleMenuGroups
12958
+ };
12959
+ };
12960
+ var getLinkPopoverPosition = function getLinkPopoverPosition(editor, popoverRef) {
12961
+ var _editor$view$state$se = editor.view.state.selection,
12962
+ selectionEnd = _editor$view$state$se.$to.pos,
12963
+ selectionStart = _editor$view$state$se.$from.pos;
12964
+ var selectionLength = selectionEnd - selectionStart;
12965
+ var offset = 0;
12966
+ if (selectionLength > 1) offset = Math.round(selectionLength / 2);
12967
+ if (selectionLength === 1) offset = 1;
12968
+
12969
+ // Calculate the arrow position
12970
+ var arrowCoords = editor.view.coordsAtPos(selectionStart + offset);
12971
+ var arrowPosition = {
12972
+ top: "".concat(arrowCoords.top + 21, "px"),
12973
+ left: "".concat(arrowCoords.left - 8.5, "px")
12974
+ };
12975
+
12976
+ // Calculate the popover position
12977
+ var popoverCoords = editor.view.coordsAtPos(selectionStart);
12978
+ var adjustedLeft = popoverCoords === null || popoverCoords === void 0 ? void 0 : popoverCoords.left,
12979
+ adjustedTop = popoverCoords === null || popoverCoords === void 0 ? void 0 : popoverCoords.top;
12980
+ if (popoverRef !== null && popoverRef !== void 0 && popoverRef.current) {
12981
+ var _popoverRef$current;
12982
+ var popoverRect = (_popoverRef$current = popoverRef.current) === null || _popoverRef$current === void 0 ? void 0 : _popoverRef$current.getBoundingClientRect();
12983
+ var screenWidth = window.innerWidth;
12984
+ var screenHeight = window.innerHeight;
12985
+ var maxLeft = screenWidth - popoverRect.width;
12986
+ var maxTop = screenHeight - popoverRect.height - 50;
12987
+ adjustedLeft = popoverCoords !== null && popoverCoords !== void 0 && popoverCoords.left ? Math.min(popoverCoords.left - 50, maxLeft) : 0;
12988
+ adjustedTop = popoverCoords !== null && popoverCoords !== void 0 && popoverCoords.top ? Math.min(popoverCoords.top - 22, maxTop) : 0;
12989
+ } else {
12990
+ adjustedLeft = popoverCoords.left - 50;
12991
+ adjustedTop = popoverCoords.top - 22;
12992
+ }
12993
+ var popoverPosition = {
12994
+ top: "".concat(adjustedTop, "px"),
12995
+ left: "".concat(adjustedLeft, "px")
12996
+ };
12997
+ return {
12998
+ arrowPosition: arrowPosition,
12999
+ popoverPosition: popoverPosition
13000
+ };
13001
+ };
13002
+
13003
+ 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; }
13004
+ 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__default["default"](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; }
13005
+ var Progress = function Progress(_ref) {
13006
+ var uppy = _ref.uppy,
13007
+ pendingUploads = _ref.pendingUploads,
13008
+ setPendingUploads = _ref.setPendingUploads;
13009
+ var _useTranslation = reactI18next.useTranslation(),
13010
+ t = _useTranslation.t;
13011
+ var handleUploadProgress = function handleUploadProgress(file, progress) {
13012
+ setPendingUploads(function (prevState) {
13013
+ return prevState.map(function (uploadingFile) {
13014
+ return _objectSpread$5(_objectSpread$5({}, uploadingFile), {}, {
13015
+ progress: uploadingFile.filename !== file.name ? uploadingFile.progress : progress.progress
13016
+ });
13017
+ });
13018
+ });
13019
+ };
13020
+ var removeUploadingFile = function removeUploadingFile(id) {
13021
+ uppy.removeFile(id);
13022
+ setPendingUploads(function (prevState) {
13023
+ return neetoCist.removeById(id, prevState);
13024
+ });
13025
+ };
13026
+ React.useEffect(function () {
13027
+ uppy.on("upload-progress", handleUploadProgress);
13028
+ return function () {
13029
+ uppy.off("upload-progress", handleUploadProgress);
13030
+ };
13031
+ }, [uppy]);
13032
+ return /*#__PURE__*/React__default["default"].createElement("div", {
13033
+ className: "ne-media-uploader__wrapper"
13034
+ }, pendingUploads.map(function (_ref2) {
13035
+ var id = _ref2.id,
13036
+ filename = _ref2.filename,
13037
+ progress = _ref2.progress;
13038
+ return /*#__PURE__*/React__default["default"].createElement("div", {
13039
+ className: "ne-media-uploader__media",
13040
+ key: id
13041
+ }, /*#__PURE__*/React__default["default"].createElement("div", {
13042
+ className: "ne-media-uploader__media__info"
13043
+ }, /*#__PURE__*/React__default["default"].createElement(neetoui.Typography, {
13044
+ style: "body2"
13045
+ }, filename), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
13046
+ "data-cy": "neeto-editor-image-upload-cancel-button",
13047
+ icon: neetoIcons.Close,
13048
+ size: "small",
13049
+ style: "text",
13050
+ onClick: function onClick() {
13051
+ return removeUploadingFile(id);
13052
+ }
13053
+ })), progress !== 100 ? /*#__PURE__*/React__default["default"].createElement("div", {
13054
+ className: "ne-media-uploader__media__progress"
13055
+ }, /*#__PURE__*/React__default["default"].createElement("div", {
11929
13056
  className: "ne-media-uploader__media__progress-bar",
11930
13057
  style: {
11931
13058
  width: "".concat(progress, "%")
@@ -13173,7 +14300,7 @@ var MediaUploader = function MediaUploader(_ref) {
13173
14300
  }))));
13174
14301
  };
13175
14302
 
13176
- 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}";
14303
+ 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}";
13177
14304
  injectCss.n(css,{});
13178
14305
 
13179
14306
  var LinkOption = function LinkOption(_ref) {
@@ -13192,361 +14319,109 @@ var LinkOption = function LinkOption(_ref) {
13192
14319
  var handleKeyDown = function handleKeyDown(event) {
13193
14320
  if (event.key === "Escape") {
13194
14321
  handleClose();
13195
- } else if (event.key === "Enter") {
13196
- handleSubmit();
13197
- }
13198
- };
13199
- var handleSubmit = function handleSubmit() {
13200
- if (constants.URL_REGEXP.test(link)) {
13201
- editor.chain().focus().setLink({
13202
- href: link
13203
- }).run();
13204
- handleClose();
13205
- } else if (neetoCist.isNotPresent(link)) {
13206
- editor.chain().focus().unsetLink().run();
13207
- handleClose();
13208
- } else {
13209
- setLink("");
13210
- handleAnimateInvalidLink();
13211
- }
13212
- };
13213
- var handleReset = function handleReset() {
13214
- if (link) {
13215
- setLink("");
13216
- editor.chain().focus().unsetLink().run();
13217
- } else {
13218
- handleClose();
13219
- }
13220
- };
13221
- return /*#__PURE__*/React__default["default"].createElement("div", {
13222
- className: "neeto-editor-bubble-menu__link",
13223
- onKeyDown: handleKeyDown
13224
- }, /*#__PURE__*/React__default["default"].createElement("input", {
13225
- autoFocus: true,
13226
- className: "neeto-editor-bubble-menu-link__input",
13227
- "data-cy": "neeto-editor-link-input",
13228
- name: "url",
13229
- placeholder: t("neetoEditor.placeholders.linkInput"),
13230
- value: link,
13231
- onChange: function onChange(_ref2) {
13232
- var value = _ref2.target.value;
13233
- return setLink(value);
13234
- }
13235
- }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
13236
- "data-cy": "neeto-editor-link-cancel-button",
13237
- icon: neetoIcons.Close,
13238
- size: "small",
13239
- style: "secondary",
13240
- onClick: handleReset
13241
- }));
13242
- };
13243
-
13244
- var TableOption$1 = function TableOption(_ref) {
13245
- var editor = _ref.editor,
13246
- handleClose = _ref.handleClose;
13247
- var _useTranslation = reactI18next.useTranslation(),
13248
- t = _useTranslation.t;
13249
- var _useState = React.useState(3),
13250
- _useState2 = _slicedToArray__default["default"](_useState, 2),
13251
- rows = _useState2[0],
13252
- setRows = _useState2[1];
13253
- var _useState3 = React.useState(3),
13254
- _useState4 = _slicedToArray__default["default"](_useState3, 2),
13255
- columns = _useState4[0],
13256
- setColumns = _useState4[1];
13257
- var handleSubmit = function handleSubmit() {
13258
- editor.chain().focus().insertTable({
13259
- rows: rows,
13260
- cols: columns,
13261
- withHeaderRow: true
13262
- }).run(), setRows(3);
13263
- setColumns(3);
13264
- handleClose();
13265
- };
13266
- return /*#__PURE__*/React__default["default"].createElement("div", {
13267
- className: "neeto-editor-bubble-menu__table"
13268
- }, /*#__PURE__*/React__default["default"].createElement("input", {
13269
- autoFocus: true,
13270
- "data-cy": "neeto-editor-fixed-menu-table-option-input",
13271
- min: "1",
13272
- placeholder: t("neetoEditor.placeholders.rows"),
13273
- type: "number",
13274
- value: rows,
13275
- onChange: utils$1.withEventTargetValue(setRows)
13276
- }), /*#__PURE__*/React__default["default"].createElement("input", {
13277
- "data-cy": "neeto-editor-bubble-menu-table-option-input",
13278
- min: "1",
13279
- placeholder: t("neetoEditor.placeholders.columns"),
13280
- type: "number",
13281
- value: columns,
13282
- onChange: utils$1.withEventTargetValue(setColumns)
13283
- }), /*#__PURE__*/React__default["default"].createElement("div", {
13284
- className: "neeto-editor-bubble-menu__table__buttons"
13285
- }, /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
13286
- "data-cy": "neeto-editor-bubble-menu-table-option-create-button",
13287
- icon: neetoIcons.Check,
13288
- style: "secondary",
13289
- onClick: handleSubmit
13290
- }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
13291
- "data-cy": "neeto-editor-bubble-menu-table-option-create-button",
13292
- icon: neetoIcons.Close,
13293
- style: "secondary",
13294
- onClick: handleClose
13295
- })));
13296
- };
13297
-
13298
- var getTextMenuDropdownOptions = function getTextMenuDropdownOptions(_ref2) {
13299
- var editor = _ref2.editor;
13300
- return [{
13301
- optionName: "Heading 1",
13302
- active: editor.isActive("heading", {
13303
- level: 1
13304
- }),
13305
- command: function command() {
13306
- return editor.chain().focus().setNode("heading", {
13307
- level: 1
13308
- }).run();
13309
- }
13310
- }, {
13311
- optionName: "Heading 2",
13312
- active: editor.isActive("heading", {
13313
- level: 2
13314
- }),
13315
- command: function command() {
13316
- return editor.chain().focus().setNode("heading", {
13317
- level: 2
13318
- }).run();
13319
- }
13320
- }, {
13321
- optionName: "Heading 3",
13322
- active: editor.isActive("heading", {
13323
- level: 3
13324
- }),
13325
- command: function command() {
13326
- return editor.chain().focus().setNode("heading", {
13327
- level: 3
13328
- }).run();
13329
- }
13330
- }, {
13331
- optionName: "Ordered List",
13332
- active: editor.isActive("orderedList"),
13333
- command: function command() {
13334
- return editor.chain().focus().toggleOrderedList().run();
13335
- }
13336
- }, {
13337
- optionName: "Bulleted List",
13338
- active: editor.isActive("bulletList"),
13339
- command: function command() {
13340
- return editor.chain().focus().toggleBulletList().run();
13341
- }
13342
- }, {
13343
- optionName: "Text",
13344
- active: editor.isActive("paragraph"),
13345
- command: function command() {
13346
- return editor.chain().focus().setNode("paragraph").run();
13347
- }
13348
- }];
13349
- };
13350
- var getNodeType = function getNodeType(options) {
13351
- var _options$find;
13352
- return ((_options$find = options.find(ramda.prop("active"))) === null || _options$find === void 0 ? void 0 : _options$find.optionName) || "Text";
13353
- };
13354
- var renderOptionButton$1 = function renderOptionButton(_ref3) {
13355
- var tooltip = _ref3.tooltip,
13356
- Icon = _ref3.Icon,
13357
- command = _ref3.command,
13358
- active = _ref3.active,
13359
- optionName = _ref3.optionName,
13360
- highlight = _ref3.highlight;
13361
- return /*#__PURE__*/React__default["default"].createElement(neetoui.Button, _extends__default["default"]({
13362
- "data-cy": "neeto-editor-bubble-menu-".concat(optionName, "-option"),
13363
- icon: Icon,
13364
- key: optionName,
13365
- size: "small",
13366
- style: active ? "secondary" : "text",
13367
- tooltipProps: {
13368
- content: tooltip,
13369
- position: "bottom",
13370
- theme: "dark",
13371
- delay: [500]
13372
- },
13373
- onClick: command
13374
- }, generateFocusProps(highlight)));
13375
- };
13376
-
13377
- var Mentions = function Mentions(_ref) {
13378
- var editor = _ref.editor,
13379
- mentions = _ref.mentions,
13380
- tooltipContent = _ref.tooltipContent;
13381
- var Menu = neetoui.Dropdown.Menu,
13382
- MenuItem = neetoui.Dropdown.MenuItem;
13383
- if (ramda.isEmpty(mentions)) return null;
13384
- return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
13385
- buttonStyle: "text",
13386
- "data-cy": "neeto-editor-mention-option",
13387
- icon: neetoIcons.Email,
13388
- strategy: "fixed",
13389
- buttonProps: {
13390
- tooltipProps: {
13391
- content: tooltipContent,
13392
- position: "bottom"
13393
- },
13394
- className: "neeto-editor-fixed-menu__item"
13395
- }
13396
- }, /*#__PURE__*/React__default["default"].createElement(Menu, null, mentions.map(function (_ref2) {
13397
- var key = _ref2.key,
13398
- name = _ref2.name,
13399
- imageUrl = _ref2.imageUrl;
13400
- return /*#__PURE__*/React__default["default"].createElement(MenuItem.Button, {
13401
- "data-cy": "neeto-editor-mention-option-".concat(key),
13402
- key: key,
13403
- onClick: function onClick() {
13404
- return editor.commands.setMention({
13405
- id: key,
13406
- label: name
13407
- });
13408
- }
13409
- }, /*#__PURE__*/React__default["default"].createElement(neetoui.Avatar, {
13410
- size: "small",
13411
- user: {
13412
- name: name,
13413
- imageUrl: imageUrl
13414
- }
13415
- }), /*#__PURE__*/React__default["default"].createElement(neetoui.Typography, {
13416
- style: "body2"
13417
- }, name));
13418
- })));
13419
- };
13420
-
13421
- var EmojiOption = function EmojiOption(_ref) {
13422
- var editor = _ref.editor,
13423
- isActive = _ref.isActive,
13424
- setActive = _ref.setActive,
13425
- tooltipContent = _ref.tooltipContent;
13426
- return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
13427
- buttonStyle: "text",
13428
- closeOnSelect: false,
13429
- dropdownProps: {
13430
- classNames: "neeto-editor-fixed-menu__emoji-dropdown"
13431
- },
13432
- icon: neetoIcons.Smiley,
13433
- isOpen: isActive,
13434
- position: "bottom-start",
13435
- strategy: "fixed",
13436
- buttonProps: {
13437
- tabIndex: -1,
13438
- tooltipProps: {
13439
- content: tooltipContent,
13440
- position: "bottom"
13441
- },
13442
- className: "neeto-editor-fixed-menu__item"
13443
- },
13444
- onClick: function onClick() {
13445
- return setActive(function (active) {
13446
- return !active;
13447
- });
13448
- },
13449
- onClose: function onClose() {
13450
- return setActive(false);
14322
+ } else if (event.key === "Enter") {
14323
+ handleSubmit();
13451
14324
  }
13452
- }, /*#__PURE__*/React__default["default"].createElement(EmojiPickerMenu, {
13453
- editor: editor,
13454
- setActive: setActive
14325
+ };
14326
+ var handleSubmit = function handleSubmit() {
14327
+ if (constants.URL_REGEXP.test(link)) {
14328
+ editor.chain().focus().setLink({
14329
+ href: link
14330
+ }).run();
14331
+ handleClose();
14332
+ } else if (neetoCist.isNotPresent(link)) {
14333
+ editor.chain().focus().unsetLink().run();
14334
+ handleClose();
14335
+ } else {
14336
+ setLink("");
14337
+ handleAnimateInvalidLink();
14338
+ }
14339
+ };
14340
+ var handleReset = function handleReset() {
14341
+ if (link) {
14342
+ setLink("");
14343
+ editor.chain().focus().unsetLink().run();
14344
+ } else {
14345
+ handleClose();
14346
+ }
14347
+ };
14348
+ return /*#__PURE__*/React__default["default"].createElement("div", {
14349
+ className: "neeto-editor-bubble-menu__link",
14350
+ onKeyDown: handleKeyDown
14351
+ }, /*#__PURE__*/React__default["default"].createElement("input", {
14352
+ autoFocus: true,
14353
+ className: "neeto-editor-bubble-menu-link__input",
14354
+ "data-cy": "neeto-editor-link-input",
14355
+ name: "url",
14356
+ placeholder: t("neetoEditor.placeholders.linkInput"),
14357
+ value: link,
14358
+ onChange: function onChange(_ref2) {
14359
+ var value = _ref2.target.value;
14360
+ return setLink(value);
14361
+ }
14362
+ }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
14363
+ "data-cy": "neeto-editor-link-cancel-button",
14364
+ icon: neetoIcons.Close,
14365
+ size: "small",
14366
+ style: "secondary",
14367
+ onClick: handleReset
13455
14368
  }));
13456
14369
  };
13457
14370
 
13458
- var TextColorOption = function TextColorOption(_ref) {
14371
+ var TableOption = function TableOption(_ref) {
13459
14372
  var editor = _ref.editor,
13460
- tooltipContent = _ref.tooltipContent;
13461
- var _useState = React.useState(false),
13462
- _useState2 = _slicedToArray__default["default"](_useState, 2),
13463
- isOpen = _useState2[0],
13464
- setIsOpen = _useState2[1];
13465
- var _useState3 = React.useState(null),
13466
- _useState4 = _slicedToArray__default["default"](_useState3, 2),
13467
- color = _useState4[0],
13468
- setColor = _useState4[1];
13469
- var dropdownWrapperRef = React.useRef(null);
14373
+ handleClose = _ref.handleClose;
13470
14374
  var _useTranslation = reactI18next.useTranslation(),
13471
14375
  t = _useTranslation.t;
13472
- var handleSave = function handleSave() {
13473
- editor.chain().focus().setColor(color).run();
13474
- setIsOpen(false);
13475
- };
13476
- var handleUnset = function handleUnset() {
13477
- editor.chain().focus().unsetColor().run();
13478
- setColor(null);
13479
- setIsOpen(false);
14376
+ var _useState = React.useState(3),
14377
+ _useState2 = _slicedToArray__default["default"](_useState, 2),
14378
+ rows = _useState2[0],
14379
+ setRows = _useState2[1];
14380
+ var _useState3 = React.useState(3),
14381
+ _useState4 = _slicedToArray__default["default"](_useState3, 2),
14382
+ columns = _useState4[0],
14383
+ setColumns = _useState4[1];
14384
+ var handleSubmit = function handleSubmit() {
14385
+ editor.chain().focus().insertTable({
14386
+ rows: rows,
14387
+ cols: columns,
14388
+ withHeaderRow: true
14389
+ }).run(), setRows(3);
14390
+ setColumns(3);
14391
+ handleClose();
13480
14392
  };
13481
- reactUtils.useOnClickOutside(dropdownWrapperRef, function (event) {
13482
- if (isOpen) {
13483
- event.preventDefault();
13484
- editor.commands.focus();
13485
- setIsOpen(false);
13486
- }
13487
- });
13488
- React.useEffect(function () {
13489
- setColor(editor.getAttributes("textStyle").color);
13490
- }, [isOpen, editor.getAttributes("textStyle").color]);
13491
14393
  return /*#__PURE__*/React__default["default"].createElement("div", {
13492
- ref: dropdownWrapperRef
13493
- }, /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
13494
- buttonStyle: isOpen || color ? "secondary" : "text",
13495
- icon: neetoIcons.Customize,
13496
- isOpen: isOpen,
13497
- buttonProps: {
13498
- tabIndex: -1,
13499
- tooltipProps: {
13500
- content: tooltipContent,
13501
- position: "bottom"
13502
- },
13503
- className: "neeto-editor-fixed-menu__item neeto-editor-text-color-option"
13504
- },
13505
- onClick: function onClick() {
13506
- setColor(editor.getAttributes("textStyle").color);
13507
- setIsOpen(ramda.not);
13508
- }
13509
- }, /*#__PURE__*/React__default["default"].createElement(reactColorful.HexColorPicker, {
13510
- color: color || "#000000",
13511
- onChange: setColor
13512
- }), /*#__PURE__*/React__default["default"].createElement("div", {
13513
- className: "neeto-editor-text-color-option__options-group"
13514
- }, /*#__PURE__*/React__default["default"].createElement(neetoui.Input, {
14394
+ className: "neeto-editor-bubble-menu__table"
14395
+ }, /*#__PURE__*/React__default["default"].createElement("input", {
13515
14396
  autoFocus: true,
13516
- className: "neeto-editor-text-color-option__options-group__input",
13517
- placeholder: t("neetoEditor.placeholders.pickColor"),
13518
- size: "small",
13519
- value: color,
13520
- onChange: utils$1.withEventTargetValue(setColor),
13521
- onClick: function onClick(event) {
13522
- return event.stopPropagation();
13523
- }
13524
- }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
14397
+ "data-cy": "neeto-editor-fixed-menu-table-option-input",
14398
+ min: "1",
14399
+ placeholder: t("neetoEditor.placeholders.rows"),
14400
+ type: "number",
14401
+ value: rows,
14402
+ onChange: utils$1.withEventTargetValue(setRows)
14403
+ }), /*#__PURE__*/React__default["default"].createElement("input", {
14404
+ "data-cy": "neeto-editor-bubble-menu-table-option-input",
14405
+ min: "1",
14406
+ placeholder: t("neetoEditor.placeholders.columns"),
14407
+ type: "number",
14408
+ value: columns,
14409
+ onChange: utils$1.withEventTargetValue(setColumns)
14410
+ }), /*#__PURE__*/React__default["default"].createElement("div", {
14411
+ className: "neeto-editor-bubble-menu__table__buttons"
14412
+ }, /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
14413
+ "data-cy": "neeto-editor-bubble-menu-table-option-create-button",
13525
14414
  icon: neetoIcons.Check,
13526
- size: "small",
13527
- onClick: handleSave
14415
+ style: "secondary",
14416
+ onClick: handleSubmit
13528
14417
  }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
14418
+ "data-cy": "neeto-editor-bubble-menu-table-option-create-button",
13529
14419
  icon: neetoIcons.Close,
13530
- size: "small",
13531
- style: "text",
13532
- onClick: function onClick() {
13533
- editor.commands.focus();
13534
- setIsOpen(false);
13535
- }
13536
- }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
13537
- icon: neetoIcons.Refresh,
13538
- size: "small",
13539
- style: "text",
13540
- tooltipProps: {
13541
- content: t("neetoEditor.common.resetToDefault"),
13542
- position: "top"
13543
- },
13544
- onClick: handleUnset
13545
- }))));
14420
+ style: "secondary",
14421
+ onClick: handleClose
14422
+ })));
13546
14423
  };
13547
14424
 
13548
- 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; }
13549
- 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__default["default"](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; }
13550
14425
  var createMenuOptions$1 = function createMenuOptions(_ref) {
13551
14426
  var tooltips = _ref.tooltips,
13552
14427
  editor = _ref.editor,
@@ -13698,7 +14573,7 @@ var createMenuOptions$1 = function createMenuOptions(_ref) {
13698
14573
  }]
13699
14574
  };
13700
14575
  };
13701
- var buildMenuOptions$1 = function buildMenuOptions(_ref2) {
14576
+ var buildBubbleMenuOptions = function buildBubbleMenuOptions(_ref2) {
13702
14577
  var tooltips = _ref2.tooltips,
13703
14578
  editor = _ref2.editor,
13704
14579
  options = _ref2.options,
@@ -13720,54 +14595,83 @@ var buildMenuOptions$1 = function buildMenuOptions(_ref2) {
13720
14595
  })];
13721
14596
  }));
13722
14597
  };
13723
- var renderOptionButton = function renderOptionButton(_ref3) {
13724
- var Icon = _ref3.Icon,
13725
- command = _ref3.command,
13726
- active = _ref3.active,
13727
- optionName = _ref3.optionName,
13728
- highlight = _ref3.highlight,
13729
- disabled = _ref3.disabled,
13730
- tooltip = _ref3.tooltip;
14598
+ var getTextMenuDropdownOptions = function getTextMenuDropdownOptions(_ref3) {
14599
+ var editor = _ref3.editor;
14600
+ return [{
14601
+ optionName: "Heading 1",
14602
+ active: editor.isActive("heading", {
14603
+ level: 1
14604
+ }),
14605
+ command: function command() {
14606
+ return editor.chain().focus().setNode("heading", {
14607
+ level: 1
14608
+ }).run();
14609
+ }
14610
+ }, {
14611
+ optionName: "Heading 2",
14612
+ active: editor.isActive("heading", {
14613
+ level: 2
14614
+ }),
14615
+ command: function command() {
14616
+ return editor.chain().focus().setNode("heading", {
14617
+ level: 2
14618
+ }).run();
14619
+ }
14620
+ }, {
14621
+ optionName: "Heading 3",
14622
+ active: editor.isActive("heading", {
14623
+ level: 3
14624
+ }),
14625
+ command: function command() {
14626
+ return editor.chain().focus().setNode("heading", {
14627
+ level: 3
14628
+ }).run();
14629
+ }
14630
+ }, {
14631
+ optionName: "Ordered List",
14632
+ active: editor.isActive("orderedList"),
14633
+ command: function command() {
14634
+ return editor.chain().focus().toggleOrderedList().run();
14635
+ }
14636
+ }, {
14637
+ optionName: "Bulleted List",
14638
+ active: editor.isActive("bulletList"),
14639
+ command: function command() {
14640
+ return editor.chain().focus().toggleBulletList().run();
14641
+ }
14642
+ }, {
14643
+ optionName: "Text",
14644
+ active: editor.isActive("paragraph"),
14645
+ command: function command() {
14646
+ return editor.chain().focus().setNode("paragraph").run();
14647
+ }
14648
+ }];
14649
+ };
14650
+ var getNodeType = function getNodeType(options) {
14651
+ var _options$find;
14652
+ return ((_options$find = options.find(ramda.prop("active"))) === null || _options$find === void 0 ? void 0 : _options$find.optionName) || "Text";
14653
+ };
14654
+ var renderOptionButton = function renderOptionButton(_ref4) {
14655
+ var tooltip = _ref4.tooltip,
14656
+ Icon = _ref4.Icon,
14657
+ command = _ref4.command,
14658
+ active = _ref4.active,
14659
+ optionName = _ref4.optionName,
14660
+ highlight = _ref4.highlight;
13731
14661
  return /*#__PURE__*/React__default["default"].createElement(neetoui.Button, _extends__default["default"]({
13732
- disabled: disabled,
13733
- className: "neeto-editor-fixed-menu__item",
13734
- "data-cy": "neeto-editor-fixed-menu-".concat(optionName, "-option"),
14662
+ "data-cy": "neeto-editor-bubble-menu-".concat(optionName, "-option"),
13735
14663
  icon: Icon,
13736
14664
  key: optionName,
13737
- style: active ? "secondary" : "text",
13738
- tabIndex: "-1",
13739
- tooltipProps: {
13740
- content: tooltip,
13741
- position: "bottom"
13742
- },
13743
- onClick: command
13744
- }, generateFocusProps(highlight)));
13745
- };
13746
- var buildOptionsFromAddonCommands = function buildOptionsFromAddonCommands(_ref4) {
13747
- var editor = _ref4.editor,
13748
- commands = _ref4.commands;
13749
- var to = editor.state.selection.to;
13750
- return commands.map(function (option) {
13751
- var _option$active;
13752
- return _objectSpread$3(_objectSpread$3({}, option), {}, {
13753
- active: (_option$active = option.active) === null || _option$active === void 0 ? void 0 : _option$active.call(option, {
13754
- editor: editor
13755
- }),
13756
- command: function command() {
13757
- var _option$command;
13758
- return (_option$command = option.command) === null || _option$command === void 0 ? void 0 : _option$command.call(option, {
13759
- editor: editor,
13760
- range: {
13761
- from: to,
13762
- to: to
13763
- }
13764
- });
13765
- }
13766
- });
13767
- });
13768
- };
13769
- var getCursorPos = function getCursorPos(editor, to) {
13770
- return editor === null || editor === void 0 ? void 0 : editor.view.coordsAtPos(to);
14665
+ size: "small",
14666
+ style: active ? "secondary" : "text",
14667
+ tooltipProps: {
14668
+ content: tooltip,
14669
+ position: "bottom",
14670
+ theme: "dark",
14671
+ delay: [500]
14672
+ },
14673
+ onClick: command
14674
+ }, generateFocusProps(highlight)));
13771
14675
  };
13772
14676
 
13773
14677
  var Options = function Options(_ref) {
@@ -13798,7 +14702,7 @@ var Options = function Options(_ref) {
13798
14702
  var isTextColorOptionActive = options.includes(constants.EDITOR_OPTIONS.TEXT_COLOR);
13799
14703
  var isLinkActive = options.includes(constants.EDITOR_OPTIONS.LINK);
13800
14704
  var isTableActive = options.includes(constants.EDITOR_OPTIONS.TABLE);
13801
- var _buildMenuOptions = buildMenuOptions$1({
14705
+ var _buildBubbleMenuOptio = buildBubbleMenuOptions({
13802
14706
  editor: editor,
13803
14707
  options: options,
13804
14708
  setMediaUploader: setMediaUploader,
@@ -13807,9 +14711,9 @@ var Options = function Options(_ref) {
13807
14711
  setIsEmbedModalOpen: setIsEmbedModalOpen,
13808
14712
  setIsAddLinkActive: setIsLinkOptionActive
13809
14713
  }),
13810
- fontStyleOptions = _buildMenuOptions.font,
13811
- blockStyleOptions = _buildMenuOptions.block,
13812
- listStyleOptions = _buildMenuOptions.list;
14714
+ fontStyleOptions = _buildBubbleMenuOptio.font,
14715
+ blockStyleOptions = _buildBubbleMenuOptio.block,
14716
+ listStyleOptions = _buildBubbleMenuOptio.list;
13813
14717
  var handleAnimateInvalidLink = function handleAnimateInvalidLink() {
13814
14718
  setIsInvalidLink(true);
13815
14719
  setTimeout(function () {
@@ -13826,7 +14730,7 @@ var Options = function Options(_ref) {
13826
14730
  });
13827
14731
  }
13828
14732
  if (isTableOptionActive) {
13829
- return /*#__PURE__*/React__default["default"].createElement(TableOption$1, {
14733
+ return /*#__PURE__*/React__default["default"].createElement(TableOption, {
13830
14734
  editor: editor,
13831
14735
  handleClose: function handleClose() {
13832
14736
  return setIsTableOptionActive(false);
@@ -13845,7 +14749,7 @@ var Options = function Options(_ref) {
13845
14749
  key: optionName,
13846
14750
  onClick: command
13847
14751
  }, optionName);
13848
- }))), fontStyleOptions.map(renderOptionButton$1), blockStyleOptions.map(renderOptionButton$1), isTextColorOptionActive && /*#__PURE__*/React__default["default"].createElement(TextColorOption, {
14752
+ }))), fontStyleOptions.map(renderOptionButton), blockStyleOptions.map(renderOptionButton), isTextColorOptionActive && /*#__PURE__*/React__default["default"].createElement(TextColorOption, {
13849
14753
  editor: editor,
13850
14754
  tooltipContent: tooltips.textColor || t("neetoEditor.menu.textColor")
13851
14755
  }), isEmojiActive && /*#__PURE__*/React__default["default"].createElement(EmojiOption, {
@@ -13853,7 +14757,7 @@ var Options = function Options(_ref) {
13853
14757
  isActive: isEmojiPickerActive,
13854
14758
  setActive: setIsEmojiPickerActive,
13855
14759
  tooltipContent: tooltips.emoji || t("neetoEditor.menu.emoji")
13856
- }), listStyleOptions.map(renderOptionButton$1), isLinkActive && renderOptionButton$1({
14760
+ }), listStyleOptions.map(renderOptionButton), isLinkActive && renderOptionButton({
13857
14761
  Icon: neetoIcons.Link,
13858
14762
  command: function command() {
13859
14763
  return setIsLinkOptionActive(true);
@@ -13862,7 +14766,7 @@ var Options = function Options(_ref) {
13862
14766
  optionName: "link",
13863
14767
  highlight: false,
13864
14768
  tooltip: tooltips.link || t("neetoEditor.menu.link")
13865
- }), isTableActive && renderOptionButton$1({
14769
+ }), isTableActive && renderOptionButton({
13866
14770
  Icon: neetoIcons.Column,
13867
14771
  command: function command() {
13868
14772
  return setIsTableOptionActive(true);
@@ -13945,93 +14849,6 @@ var Bubble = function Bubble(_ref) {
13945
14849
  }, children)));
13946
14850
  };
13947
14851
 
13948
- var FONT_SIZE_OPTIONS = [{
13949
- label: i18n.t("neetoEditor.menu.heading1"),
13950
- value: 1,
13951
- key: "h1"
13952
- }, {
13953
- label: i18n.t("neetoEditor.menu.heading2"),
13954
- value: 2,
13955
- key: "h2"
13956
- }, {
13957
- label: i18n.t("neetoEditor.menu.heading3"),
13958
- value: 3,
13959
- key: "h3"
13960
- }, {
13961
- label: i18n.t("neetoEditor.menu.heading4"),
13962
- value: 4,
13963
- key: "h4"
13964
- }, {
13965
- label: i18n.t("neetoEditor.menu.heading5"),
13966
- value: 5,
13967
- key: "h5"
13968
- }, {
13969
- label: i18n.t("neetoEditor.menu.normalText"),
13970
- value: 0,
13971
- key: "body2"
13972
- }];
13973
-
13974
- var Menu$2 = neetoui.Dropdown.Menu,
13975
- MenuItem = neetoui.Dropdown.MenuItem;
13976
- var FontSizeOption = function FontSizeOption(_ref) {
13977
- var editor = _ref.editor,
13978
- tooltipContent = _ref.tooltipContent;
13979
- var dropdownRef = React.useRef(null);
13980
- var isActive = function isActive(level) {
13981
- return editor.isActive("heading", {
13982
- level: level
13983
- });
13984
- };
13985
- var activeOption = FONT_SIZE_OPTIONS.find(function (_ref2) {
13986
- var value = _ref2.value;
13987
- return isActive(value);
13988
- }) || ramda.last(FONT_SIZE_OPTIONS);
13989
- var handleClick = function handleClick(level) {
13990
- return level ? editor.chain().focus().toggleHeading({
13991
- level: level
13992
- }).run() : editor.chain().focus().setNode("paragraph").run();
13993
- };
13994
- return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
13995
- autoWidth: true,
13996
- "data-cy": "neeto-editor-fixed-menu-font-size-option",
13997
- label: activeOption === null || activeOption === void 0 ? void 0 : activeOption.label,
13998
- placement: "bottom-start",
13999
- strategy: "fixed",
14000
- buttonProps: {
14001
- ref: dropdownRef,
14002
- onKeyDown: function onKeyDown(event) {
14003
- var _dropdownRef$current;
14004
- return event.key === "ArrowDown" && ((_dropdownRef$current = dropdownRef.current) === null || _dropdownRef$current === void 0 ? void 0 : _dropdownRef$current.click());
14005
- },
14006
- tooltipProps: {
14007
- content: tooltipContent,
14008
- position: "bottom"
14009
- },
14010
- style: "text",
14011
- size: "small",
14012
- className: "neeto-editor-fixed-menu__item neeto-editor-font-size__wrapper"
14013
- }
14014
- }, /*#__PURE__*/React__default["default"].createElement(Menu$2, {
14015
- onKeyDown: function onKeyDown(event) {
14016
- var _editor$commands;
14017
- return event.key === "Escape" && ((_editor$commands = editor.commands) === null || _editor$commands === void 0 ? void 0 : _editor$commands.focus());
14018
- }
14019
- }, FONT_SIZE_OPTIONS.map(function (_ref3) {
14020
- var label = _ref3.label,
14021
- value = _ref3.value,
14022
- key = _ref3.key;
14023
- return /*#__PURE__*/React__default["default"].createElement(MenuItem.Button, {
14024
- "data-cy": "neeto-editor-fixed-menu-font-size-option-".concat(key),
14025
- key: value,
14026
- onClick: function onClick() {
14027
- return handleClick(value);
14028
- }
14029
- }, /*#__PURE__*/React__default["default"].createElement(neetoui.Typography, {
14030
- style: key
14031
- }, label));
14032
- })));
14033
- };
14034
-
14035
14852
  var LinkAddPopOver = function LinkAddPopOver(_ref) {
14036
14853
  var isAddLinkActive = _ref.isAddLinkActive,
14037
14854
  setIsAddLinkActive = _ref.setIsAddLinkActive,
@@ -14068,7 +14885,7 @@ var LinkAddPopOver = function LinkAddPopOver(_ref) {
14068
14885
  _useState12 = _slicedToArray__default["default"](_useState11, 2),
14069
14886
  arrowPosition = _useState12[0],
14070
14887
  setArrowPosition = _useState12[1];
14071
- var popOverRef = React.useRef(null);
14888
+ var popoverRef = React.useRef(null);
14072
14889
  var _useTranslation = reactI18next.useTranslation(),
14073
14890
  t = _useTranslation.t;
14074
14891
  var isLinkTextPresent = !neetoCist.isNotPresent(linkText);
@@ -14117,26 +14934,13 @@ var LinkAddPopOver = function LinkAddPopOver(_ref) {
14117
14934
  }
14118
14935
  };
14119
14936
  var updatePopoverPosition = function updatePopoverPosition() {
14120
- var _popOverRef$current;
14121
- if (!popOverRef.current) return;
14122
- var newPos = editor.view.coordsAtPos(editor.view.state.selection.$to.pos);
14123
- setArrowPosition({
14124
- top: "".concat(newPos.top + 20, "px"),
14125
- left: "".concat(newPos.left - 10, "px")
14126
- });
14127
- var popoverRect = (_popOverRef$current = popOverRef.current) === null || _popOverRef$current === void 0 ? void 0 : _popOverRef$current.getBoundingClientRect();
14128
- var screenWidth = window.innerWidth;
14129
- var screenHeight = window.innerHeight;
14130
- var maxLeft = screenWidth - popoverRect.width;
14131
- var maxTop = screenHeight - popoverRect.height - 50;
14132
- var adjustedLeft = newPos !== null && newPos !== void 0 && newPos.left ? Math.min(newPos.left - 50, maxLeft) : 0;
14133
- var adjustedTop = newPos !== null && newPos !== void 0 && newPos.top ? Math.min(newPos.top - 22, maxTop) : 0;
14134
- setPopoverPosition({
14135
- top: "".concat(adjustedTop, "px"),
14136
- left: "".concat(adjustedLeft, "px")
14137
- });
14937
+ var _getLinkPopoverPositi = getLinkPopoverPosition(editor, popoverRef),
14938
+ arrowPosition = _getLinkPopoverPositi.arrowPosition,
14939
+ popoverPosition = _getLinkPopoverPositi.popoverPosition;
14940
+ setPopoverPosition(popoverPosition);
14941
+ setArrowPosition(arrowPosition);
14138
14942
  };
14139
- reactUtils.useOnClickOutside(popOverRef, removePopover);
14943
+ reactUtils.useOnClickOutside(popoverRef, removePopover);
14140
14944
  React.useEffect(function () {
14141
14945
  if (editor && isAddLinkActive) {
14142
14946
  updatePopoverPosition();
@@ -14149,15 +14953,15 @@ var LinkAddPopOver = function LinkAddPopOver(_ref) {
14149
14953
  };
14150
14954
  }, []);
14151
14955
  return isAddLinkActive ? /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("div", {
14152
- className: "ne-link-arrow",
14956
+ className: "ne-link-arrow fade-in",
14153
14957
  style: {
14154
14958
  top: arrowPosition.top,
14155
14959
  left: arrowPosition.left
14156
14960
  }
14157
14961
  }), /*#__PURE__*/React__default["default"].createElement("div", {
14158
- className: "ne-link-popover",
14962
+ className: "ne-link-popover fade-in",
14159
14963
  id: "ne-link-add-popover",
14160
- ref: popOverRef,
14964
+ ref: popoverRef,
14161
14965
  style: popoverStyle
14162
14966
  }, /*#__PURE__*/React__default["default"].createElement(neetoui.Input, {
14163
14967
  required: true,
@@ -14221,85 +15025,52 @@ var LinkAddPopOver = function LinkAddPopOver(_ref) {
14221
15025
  })))), document.body) : null;
14222
15026
  };
14223
15027
 
14224
- var Menu$1 = neetoui.Dropdown.Menu;
14225
- var TableOption = function TableOption(_ref) {
14226
- var editor = _ref.editor,
14227
- tooltipContent = _ref.tooltipContent;
14228
- var _useTranslation = reactI18next.useTranslation(),
14229
- t = _useTranslation.t;
14230
- var _useState = React.useState(false),
14231
- _useState2 = _slicedToArray__default["default"](_useState, 2),
14232
- isOpen = _useState2[0],
14233
- setIsOpen = _useState2[1];
14234
- var _useState3 = React.useState(3),
14235
- _useState4 = _slicedToArray__default["default"](_useState3, 2),
14236
- rows = _useState4[0],
14237
- setRows = _useState4[1];
14238
- var _useState5 = React.useState(3),
14239
- _useState6 = _slicedToArray__default["default"](_useState5, 2),
14240
- columns = _useState6[0],
14241
- setColumns = _useState6[1];
14242
- var handleClose = function handleClose() {
14243
- setRows(3);
14244
- setColumns(3);
14245
- setIsOpen(false);
14246
- };
14247
- var handleSubmit = function handleSubmit() {
14248
- editor.chain().focus().insertTable({
14249
- rows: rows,
14250
- cols: columns,
14251
- withHeaderRow: true
14252
- }).run();
14253
- handleClose();
14254
- };
15028
+ var _excluded$3 = ["type"];
15029
+ 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; }
15030
+ 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__default["default"](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; }
15031
+ var Menu$1 = neetoui.Dropdown.Menu,
15032
+ MenuItem = neetoui.Dropdown.MenuItem;
15033
+ var MoreMenu = function MoreMenu(_ref) {
15034
+ var groups = _ref.groups,
15035
+ editor = _ref.editor;
14255
15036
  return /*#__PURE__*/React__default["default"].createElement(neetoui.Dropdown, {
14256
- isOpen: isOpen,
14257
- buttonStyle: isOpen ? "secondary" : "text",
14258
- closeOnSelect: false,
14259
- "data-cy": "neeto-editor-fixed-menu-link-option",
14260
- icon: neetoIcons.Column,
14261
- position: "bottom",
14262
15037
  buttonProps: {
14263
- tabIndex: -1,
14264
- tooltipProps: {
14265
- content: tooltipContent,
14266
- position: "bottom"
14267
- },
14268
- className: "neeto-editor-fixed-menu__item"
14269
- },
14270
- onClick: function onClick() {
14271
- return setIsOpen(function (isOpen) {
14272
- return !isOpen;
14273
- });
15038
+ className: "flex-shrink-0"
14274
15039
  },
14275
- onClose: handleClose
14276
- }, /*#__PURE__*/React__default["default"].createElement(Menu$1, {
14277
- className: "neeto-editor-table__item"
14278
- }, /*#__PURE__*/React__default["default"].createElement(neetoui.Input, {
14279
- autoFocus: true,
14280
- "data-cy": "neeto-editor-fixed-menu-table-option-input",
14281
- min: "1",
14282
- placeholder: t("neetoEditor.placeholders.rows"),
14283
- size: "small",
14284
- type: "number",
14285
- value: rows,
14286
- onChange: utils$1.withEventTargetValue(setRows)
14287
- }), /*#__PURE__*/React__default["default"].createElement(neetoui.Input, {
14288
- "data-cy": "neeto-editor-fixed-menu-table-option-input",
14289
- min: "1",
14290
- placeholder: t("neetoEditor.placeholders.rows"),
14291
- size: "small",
14292
- type: "number",
14293
- value: columns,
14294
- onChange: utils$1.withEventTargetValue(setColumns)
14295
- }), /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
14296
- "data-cy": "neeto-editor-fixed-menu-table-option-create-button",
14297
- label: t("neetoEditor.common.create"),
14298
- size: "small",
14299
- onClick: handleSubmit
15040
+ buttonStyle: "text",
15041
+ icon: neetoIcons.MenuHorizontal,
15042
+ strategy: "fixed"
15043
+ }, /*#__PURE__*/React__default["default"].createElement(Menu$1, null, groups.map(function (group) {
15044
+ return group.map(function (_ref2) {
15045
+ var type = _ref2.type,
15046
+ props = _objectWithoutProperties__default["default"](_ref2, _excluded$3);
15047
+ var Component = MENU_ELEMENTS[type];
15048
+ if (type === MENU_ELEMENT_TYPES.BUTTON) {
15049
+ var Icon = props.icon;
15050
+ return /*#__PURE__*/React__default["default"].createElement(MenuItem.Button, _extends__default["default"]({
15051
+ "data-cy": "neeto-editor-fixed-menu-".concat(props.optionName, "-option"),
15052
+ isActive: editor.isActive(props.optionName),
15053
+ key: props.optionName,
15054
+ tabIndex: "-1",
15055
+ onClick: props.command
15056
+ }, _objectSpread$4(_objectSpread$4(_objectSpread$4({}, generateFocusProps(props.highlight)), props), {}, {
15057
+ editor: editor
15058
+ })), /*#__PURE__*/React__default["default"].createElement(Icon, null), " ", props.label);
15059
+ }
15060
+ return /*#__PURE__*/React__default["default"].createElement(Component, _extends__default["default"]({
15061
+ key: props.optionName
15062
+ }, _objectSpread$4(_objectSpread$4({}, props), {}, {
15063
+ editor: editor
15064
+ }, generateFocusProps(props.highlight)), {
15065
+ isSecondaryMenu: true
15066
+ }));
15067
+ });
14300
15068
  })));
14301
15069
  };
14302
15070
 
15071
+ var _excluded$2 = ["type"];
15072
+ 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; }
15073
+ 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__default["default"](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; }
14303
15074
  var Fixed = function Fixed(_ref) {
14304
15075
  var editor = _ref.editor,
14305
15076
  options = _ref.options,
@@ -14312,8 +15083,6 @@ var Fixed = function Fixed(_ref) {
14312
15083
  unsplashApiKey = _ref.unsplashApiKey,
14313
15084
  _ref$addonCommands = _ref.addonCommands,
14314
15085
  addonCommands = _ref$addonCommands === void 0 ? [] : _ref$addonCommands,
14315
- _ref$isMenuCollapsibl = _ref.isMenuCollapsible,
14316
- isMenuCollapsible = _ref$isMenuCollapsibl === void 0 ? false : _ref$isMenuCollapsibl,
14317
15086
  _ref$isIndependant = _ref.isIndependant,
14318
15087
  isIndependant = _ref$isIndependant === void 0 ? true : _ref$isIndependant,
14319
15088
  className = _ref.className,
@@ -14330,17 +15099,22 @@ var Fixed = function Fixed(_ref) {
14330
15099
  setFocusedButtonIndex = _useState2[1];
14331
15100
  var _useState3 = React.useState(false),
14332
15101
  _useState4 = _slicedToArray__default["default"](_useState3, 2),
14333
- isMenuExpanded = _useState4[0],
14334
- setIsMenuExpanded = _useState4[1];
15102
+ isEmbedModalOpen = _useState4[0],
15103
+ setIsEmbedModalOpen = _useState4[1];
14335
15104
  var _useState5 = React.useState(false),
14336
15105
  _useState6 = _slicedToArray__default["default"](_useState5, 2),
14337
- isEmbedModalOpen = _useState6[0],
14338
- setIsEmbedModalOpen = _useState6[1];
14339
- var _useState7 = React.useState(false),
15106
+ isAddLinkActive = _useState6[0],
15107
+ setIsAddLinkActive = _useState6[1];
15108
+ var _useState7 = React.useState([]),
14340
15109
  _useState8 = _slicedToArray__default["default"](_useState7, 2),
14341
- isAddLinkActive = _useState8[0],
14342
- setIsAddLinkActive = _useState8[1];
15110
+ menuItems = _useState8[0],
15111
+ setMenuItems = _useState8[1];
15112
+ var _useState9 = React.useState([]),
15113
+ _useState10 = _slicedToArray__default["default"](_useState9, 2),
15114
+ moreMenuItems = _useState10[0],
15115
+ setMoreMenuItems = _useState10[1];
14343
15116
  var menuRef = React.useRef(null);
15117
+ var menuContainerRef = React.useRef(null);
14344
15118
  var _useTranslation = reactI18next.useTranslation(),
14345
15119
  t = _useTranslation.t;
14346
15120
  var handleArrowNavigation = function handleArrowNavigation(event) {
@@ -14373,36 +15147,43 @@ var Fixed = function Fixed(_ref) {
14373
15147
  });
14374
15148
  };
14375
15149
  }, [menuButtons]);
14376
- if (!editor) {
14377
- return null;
14378
- }
14379
- var _buildMenuOptions = buildMenuOptions$1({
15150
+ var menuGroups = React.useMemo(function () {
15151
+ return buildMenuOptions$1({
14380
15152
  tooltips: tooltips,
14381
15153
  editor: editor,
14382
15154
  options: options,
14383
15155
  setMediaUploader: setMediaUploader,
14384
15156
  attachmentProps: attachmentProps,
14385
15157
  setIsEmbedModalOpen: setIsEmbedModalOpen,
14386
- setIsAddLinkActive: setIsAddLinkActive
14387
- }),
14388
- fontStyleOptions = _buildMenuOptions.font,
14389
- blockStyleOptions = _buildMenuOptions.block,
14390
- listStyleOptions = _buildMenuOptions.list,
14391
- miscOptions = _buildMenuOptions.misc,
14392
- rightOptions = _buildMenuOptions.right;
14393
- var fontSizeOptions = options.filter(function (option) {
14394
- return option.match(/^h[1-6]$/);
14395
- });
14396
- var isFontSizeActive = neetoCist.isNotEmpty(fontSizeOptions);
14397
- var isEmojiActive = options.includes(constants.EDITOR_OPTIONS.EMOJI);
14398
- var isTableActive = options.includes(constants.EDITOR_OPTIONS.TABLE);
14399
- var isTextColorOptionActive = options.includes(constants.EDITOR_OPTIONS.TEXT_COLOR);
15158
+ setIsAddLinkActive: setIsAddLinkActive,
15159
+ mentions: mentions,
15160
+ addonCommands: addonCommands,
15161
+ setIsEmojiPickerActive: setIsEmojiPickerActive,
15162
+ isEmojiPickerActive: isEmojiPickerActive
15163
+ });
15164
+ }, [editor, isEmojiPickerActive, mentions]);
15165
+ var handleResize = React.useCallback(function () {
15166
+ if (!menuRef.current) return;
15167
+ var _reGroupMenuItems = reGroupMenuItems(menuRef, menuGroups),
15168
+ visibleMenuGroups = _reGroupMenuItems.visibleMenuGroups,
15169
+ invisibleMenuGroups = _reGroupMenuItems.invisibleMenuGroups;
15170
+ setMenuItems(visibleMenuGroups);
15171
+ setMoreMenuItems(invisibleMenuGroups);
15172
+ }, [menuGroups]);
15173
+ React.useEffect(function () {
15174
+ handleResize();
15175
+ var menuContainer = menuContainerRef.current;
15176
+ var resizeObserver = new ResizeObserver(handleResize);
15177
+ if (menuContainer) {
15178
+ resizeObserver.observe(menuContainer);
15179
+ }
15180
+ return function () {
15181
+ if (menuContainer) resizeObserver.unobserve(menuContainer);
15182
+ };
15183
+ }, [menuContainerRef, handleResize, menuGroups]);
15184
+ if (!editor) return null;
14400
15185
  var isEmbedOptionActive = options.includes(constants.EDITOR_OPTIONS.VIDEO_EMBED);
14401
- var isMediaUploaderActive = options.includes(constants.EDITOR_OPTIONS.IMAGE_UPLOAD );
14402
- var addonCommandOptions = buildOptionsFromAddonCommands({
14403
- editor: editor,
14404
- commands: addonCommands
14405
- });
15186
+ var isMediaUploaderActive = options.includes(constants.EDITOR_OPTIONS.IMAGE_UPLOAD) || options.includes(constants.EDITOR_OPTIONS.VIDEO_UPLOAD);
14406
15187
  var handleVariableClick = function handleVariableClick(item) {
14407
15188
  var category = item.category,
14408
15189
  key = item.key;
@@ -14412,7 +15193,7 @@ var Fixed = function Fixed(_ref) {
14412
15193
  }).run();
14413
15194
  };
14414
15195
  return /*#__PURE__*/React__default["default"].createElement("div", {
14415
- ref: menuRef,
15196
+ ref: menuContainerRef,
14416
15197
  className: classnames__default["default"]("neeto-editor-fixed-menu", _defineProperty__default["default"]({
14417
15198
  "neeto-editor-fixed-menu--independant": isIndependant
14418
15199
  }, className, className))
@@ -14420,39 +15201,41 @@ var Fixed = function Fixed(_ref) {
14420
15201
  className: "neeto-editor-fixed-menu__wrapper",
14421
15202
  "data-cy": "neeto-editor-fixed-menu-wrapper",
14422
15203
  ref: menuRef
14423
- }, neetoCist.isNotEmpty(rightOptions) && /*#__PURE__*/React__default["default"].createElement("div", {
14424
- className: "neeto-editor-fixed-menu__right-options"
14425
- }, rightOptions.map(renderOptionButton)), isFontSizeActive && /*#__PURE__*/React__default["default"].createElement(FontSizeOption, {
15204
+ }, menuItems.map(function (group) {
15205
+ return group.map(function (_ref2) {
15206
+ var type = _ref2.type,
15207
+ props = _objectWithoutProperties__default["default"](_ref2, _excluded$2);
15208
+ var Component = MENU_ELEMENTS[type];
15209
+ if (!Component) return null;
15210
+ return /*#__PURE__*/React__default["default"].createElement(Component, _extends__default["default"]({
15211
+ key: props.optionName
15212
+ }, _objectSpread$3(_objectSpread$3({}, props), {}, {
15213
+ editor: editor
15214
+ })));
15215
+ });
15216
+ }), neetoCist.isNotEmpty(moreMenuItems) && /*#__PURE__*/React__default["default"].createElement(MoreMenu, {
14426
15217
  editor: editor,
14427
- tooltipContent: tooltips.fontSize || t("neetoEditor.menu.fontSize")
14428
- }), /*#__PURE__*/React__default["default"].createElement("div", {
14429
- className: "neeto-editor-fixed-menu__wrapper__button-group"
14430
- }, fontStyleOptions.map(renderOptionButton)), isAddLinkActive && /*#__PURE__*/React__default["default"].createElement(LinkAddPopOver, {
15218
+ groups: moreMenuItems
15219
+ }), children), !ramda.isEmpty(variables) && /*#__PURE__*/React__default["default"].createElement("div", {
15220
+ className: "neeto-editor-fixed-menu__variables",
15221
+ "data-cy": "neeto-editor-fixed-menu-variables"
15222
+ }, /*#__PURE__*/React__default["default"].createElement(DynamicVariables__default["default"], {
15223
+ variables: variables,
15224
+ dropdownProps: {
15225
+ buttonSize: "small",
15226
+ buttonProps: {
15227
+ tooltipProps: {
15228
+ content: t("neetoEditor.menu.dynamicVariables"),
15229
+ position: "bottom"
15230
+ }
15231
+ }
15232
+ },
15233
+ onVariableClick: handleVariableClick
15234
+ })), isAddLinkActive && /*#__PURE__*/React__default["default"].createElement(LinkAddPopOver, {
14431
15235
  editor: editor,
14432
15236
  isAddLinkActive: isAddLinkActive,
14433
15237
  openLinkInNewTab: openLinkInNewTab,
14434
15238
  setIsAddLinkActive: setIsAddLinkActive
14435
- }), (isMenuExpanded || ramda.not(isMenuCollapsible)) && /*#__PURE__*/React__default["default"].createElement("div", {
14436
- className: classnames__default["default"]("neeto-editor-fixed-menu__wrapper--collapsible", {
14437
- "neeto-editor-fixed-menu__wrapper--collapsible--fade": isMenuCollapsible
14438
- })
14439
- }, /*#__PURE__*/React__default["default"].createElement("div", {
14440
- className: "neeto-editor-fixed-menu__wrapper__button-group"
14441
- }, listStyleOptions.map(renderOptionButton)), /*#__PURE__*/React__default["default"].createElement("div", {
14442
- className: "neeto-editor-fixed-menu__wrapper__button-group"
14443
- }, blockStyleOptions.map(renderOptionButton)), /*#__PURE__*/React__default["default"].createElement("div", {
14444
- className: "neeto-editor-fixed-menu__wrapper__button-group"
14445
- }, isTableActive && /*#__PURE__*/React__default["default"].createElement(TableOption, {
14446
- editor: editor,
14447
- tooltipContent: tooltips.table || t("neetoEditor.menu.table")
14448
- }), miscOptions.map(renderOptionButton), isTextColorOptionActive && /*#__PURE__*/React__default["default"].createElement(TextColorOption, {
14449
- editor: editor,
14450
- tooltipContent: tooltips.textColor || t("neetoEditor.menu.textColor")
14451
- }), isEmojiActive && /*#__PURE__*/React__default["default"].createElement(EmojiOption, {
14452
- editor: editor,
14453
- isActive: isEmojiPickerActive,
14454
- setActive: setIsEmojiPickerActive,
14455
- tooltipContent: tooltips.emoji || t("neetoEditor.menu.emoji")
14456
15239
  }), isMediaUploaderActive && /*#__PURE__*/React__default["default"].createElement(MediaUploader, {
14457
15240
  editor: editor,
14458
15241
  mediaUploader: mediaUploader,
@@ -14467,38 +15250,7 @@ var Fixed = function Fixed(_ref) {
14467
15250
  editor: editor,
14468
15251
  isEmbedModalOpen: isEmbedModalOpen,
14469
15252
  setIsEmbedModalOpen: setIsEmbedModalOpen
14470
- }), /*#__PURE__*/React__default["default"].createElement(Mentions, {
14471
- editor: editor,
14472
- mentions: mentions,
14473
- tooltipContent: tooltips.mention || t("neetoEditor.menu.mention")
14474
- }), addonCommandOptions.map(renderOptionButton)), children), isMenuCollapsible && /*#__PURE__*/React__default["default"].createElement(neetoui.Button, {
14475
- className: "neeto-editor-fixed-menu__item",
14476
- "data-cy": "neeto-editor-fixed-menu-arrow",
14477
- icon: isMenuExpanded ? neetoIcons.Left : neetoIcons.Right,
14478
- style: "text",
14479
- tooltipProps: {
14480
- content: isMenuExpanded ? t("neetoEditor.menu.collapse") : t("neetoEditor.menu.expand"),
14481
- position: "bottom"
14482
- },
14483
- onClick: function onClick() {
14484
- return setIsMenuExpanded(ramda.not);
14485
- }
14486
- })), !ramda.isEmpty(variables) && /*#__PURE__*/React__default["default"].createElement("div", {
14487
- className: "neeto-editor-fixed-menu__variables",
14488
- "data-cy": "neeto-editor-fixed-menu-variables"
14489
- }, /*#__PURE__*/React__default["default"].createElement(DynamicVariables__default["default"], {
14490
- variables: variables,
14491
- dropdownProps: {
14492
- buttonSize: "small",
14493
- buttonProps: {
14494
- tooltipProps: {
14495
- content: t("neetoEditor.menu.dynamicVariables"),
14496
- position: "bottom"
14497
- }
14498
- }
14499
- },
14500
- onVariableClick: handleVariableClick
14501
- })));
15253
+ }));
14502
15254
  };
14503
15255
 
14504
15256
  var _excluded$1 = ["icon", "onClick", "disabled", "className", "tooltipProps"];
@@ -15002,20 +15754,18 @@ exports.findParentNodeClosestToPos = findParentNodeClosestToPos;
15002
15754
  exports.getAttributes = getAttributes;
15003
15755
  exports.getChangedRanges = getChangedRanges;
15004
15756
  exports.getExtensionField = getExtensionField;
15757
+ exports.getLinkPopoverPosition = getLinkPopoverPosition;
15005
15758
  exports.getMarkAttributes = getMarkAttributes;
15006
15759
  exports.getMarkRange = getMarkRange;
15007
15760
  exports.getMarkType = getMarkType;
15008
15761
  exports.getMarksBetween = getMarksBetween;
15009
- exports.highlightFocussedNode = highlightFocussedNode;
15010
- exports.isMacOS = isMacOS;
15011
15762
  exports.keydownHandler = keydownHandler;
15012
15763
  exports.markInputRule = markInputRule;
15013
15764
  exports.markPasteRule = markPasteRule;
15014
15765
  exports.mergeAttributes = mergeAttributes;
15015
15766
  exports.nodeInputRule = nodeInputRule;
15016
- exports.resetFocussedNode = resetFocussedNode;
15017
15767
  exports.textblockTypeInputRule = textblockTypeInputRule;
15018
15768
  exports.useEditor = useEditor;
15019
15769
  exports.validateUrl = validateUrl;
15020
15770
  exports.wrappingInputRule = wrappingInputRule;
15021
- //# sourceMappingURL=chunk-e1b45d60.cjs.js.map
15771
+ //# sourceMappingURL=chunk-b40b9bbf.cjs.js.map