@ni/spright-components 5.5.3 → 5.5.5

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.
@@ -5264,7 +5264,7 @@
5264
5264
  * Returns all displayed elements inside of a root node that match a provided selector
5265
5265
  */
5266
5266
  function getDisplayedNodes(rootNode, selector) {
5267
- if (!rootNode || false || !isHTMLElement(rootNode)) {
5267
+ if (!rootNode || !selector || !isHTMLElement(rootNode)) {
5268
5268
  return;
5269
5269
  }
5270
5270
  const nodes = Array.from(rootNode.querySelectorAll(selector));
@@ -11497,7 +11497,7 @@
11497
11497
  */
11498
11498
  getValidValue(value) {
11499
11499
  var _a, _b;
11500
- let validValue = parseFloat(parseFloat(value).toPrecision(12));
11500
+ let validValue = parseFloat(parseFloat(value).toPrecision(15));
11501
11501
  if (isNaN(validValue)) {
11502
11502
  validValue = "";
11503
11503
  }
@@ -26828,7 +26828,7 @@ so this becomes the fallback color for the slot */ ''}
26828
26828
  ?required="${x => x.required}"
26829
26829
  size="${x => x.size}"
26830
26830
  type="text"
26831
- inputmode="numeric"
26831
+ inputmode="text"
26832
26832
  min="${x => x.min}"
26833
26833
  max="${x => x.max}"
26834
26834
  step="${x => x.step}"
@@ -26890,11 +26890,53 @@ so this becomes the fallback color for the slot */ ''}
26890
26890
  this.appearance = NumberFieldAppearance.underline;
26891
26891
  this.fullBleed = false;
26892
26892
  this.appearanceReadOnly = false;
26893
+ this.decimalSeparator = '.';
26894
+ this.inputFilterRegExp = this.buildFilterRegExp(this.decimalSeparator);
26895
+ this.langSubscriber = {
26896
+ handleChange: () => this.updateDecimalSeparatorAndInputFilter()
26897
+ };
26893
26898
  }
26894
26899
  connectedCallback() {
26895
26900
  super.connectedCallback();
26896
26901
  // This is a workaround for FAST issue: https://github.com/microsoft/fast/issues/6148
26897
26902
  this.control.setAttribute('role', 'spinbutton');
26903
+ this.updateDecimalSeparatorAndInputFilter();
26904
+ lang.subscribe(this.langSubscriber, this);
26905
+ }
26906
+ disconnectedCallback() {
26907
+ super.disconnectedCallback();
26908
+ lang.unsubscribe(this.langSubscriber, this);
26909
+ }
26910
+ sanitizeInput(inputText) {
26911
+ return inputText.replace(this.inputFilterRegExp, '');
26912
+ }
26913
+ // this.value <-- this.control.value
26914
+ syncValueFromInnerControl() {
26915
+ this.value = this.decimalSeparator !== '.'
26916
+ ? this.control.value.replace(this.decimalSeparator, '.')
26917
+ : this.control.value;
26918
+ }
26919
+ // this.value --> this.control.value
26920
+ syncValueToInnerControl() {
26921
+ this.control.value = this.decimalSeparator !== '.'
26922
+ ? this.value.replace('.', this.decimalSeparator)
26923
+ : this.value;
26924
+ }
26925
+ updateDecimalSeparatorAndInputFilter() {
26926
+ const previousSeparator = this.decimalSeparator;
26927
+ this.decimalSeparator = this.getSeparatorForLanguange(lang.getValueFor(this));
26928
+ if (this.decimalSeparator !== previousSeparator) {
26929
+ this.inputFilterRegExp = this.buildFilterRegExp(this.decimalSeparator);
26930
+ this.control.value = this.control.value.replace(previousSeparator, this.decimalSeparator);
26931
+ }
26932
+ }
26933
+ getSeparatorForLanguange(language) {
26934
+ return Intl.NumberFormat(language)
26935
+ .formatToParts(1.1)
26936
+ .find(x => x.type === 'decimal').value;
26937
+ }
26938
+ buildFilterRegExp(decimalSeparator) {
26939
+ return new RegExp(`[^0-9\\-+e${decimalSeparator}]`, 'g');
26898
26940
  }
26899
26941
  }
26900
26942
  __decorate([
@@ -27565,7 +27607,7 @@ so this becomes the fallback color for the slot */ ''}
27565
27607
  position in this fragment. The result object will be reused
27566
27608
  (overwritten) the next time the function is called. @internal
27567
27609
  */
27568
- findIndex(pos, round = -1) {
27610
+ findIndex(pos) {
27569
27611
  if (pos == 0)
27570
27612
  return retIndex(0, pos);
27571
27613
  if (pos == this.size)
@@ -27575,7 +27617,7 @@ so this becomes the fallback color for the slot */ ''}
27575
27617
  for (let i = 0, curPos = 0;; i++) {
27576
27618
  let cur = this.child(i), end = curPos + cur.nodeSize;
27577
27619
  if (end >= pos) {
27578
- if (end == pos || round > 0)
27620
+ if (end == pos)
27579
27621
  return retIndex(i + 1, end);
27580
27622
  return retIndex(i, curPos);
27581
27623
  }
@@ -28536,7 +28578,7 @@ so this becomes the fallback color for the slot */ ''}
28536
28578
  `blockSeparator` is given, it will be inserted to separate text
28537
28579
  from different block nodes. If `leafText` is given, it'll be
28538
28580
  inserted for every non-text leaf node encountered, otherwise
28539
- [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used.
28581
+ [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
28540
28582
  */
28541
28583
  textBetween(from, to, blockSeparator, leafText) {
28542
28584
  return this.content.textBetween(from, to, blockSeparator, leafText);
@@ -29746,8 +29788,8 @@ so this becomes the fallback color for the slot */ ''}
29746
29788
  let type = this.marks[prop], excl = type.spec.excludes;
29747
29789
  type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" "));
29748
29790
  }
29749
- this.nodeFromJSON = this.nodeFromJSON.bind(this);
29750
- this.markFromJSON = this.markFromJSON.bind(this);
29791
+ this.nodeFromJSON = json => Node$2.fromJSON(this, json);
29792
+ this.markFromJSON = json => Mark$1.fromJSON(this, json);
29751
29793
  this.topNodeType = this.nodes[this.spec.topNode || "doc"];
29752
29794
  this.cached.wrappings = Object.create(null);
29753
29795
  }
@@ -29783,20 +29825,6 @@ so this becomes the fallback color for the slot */ ''}
29783
29825
  return type.create(attrs);
29784
29826
  }
29785
29827
  /**
29786
- Deserialize a node from its JSON representation. This method is
29787
- bound.
29788
- */
29789
- nodeFromJSON(json) {
29790
- return Node$2.fromJSON(this, json);
29791
- }
29792
- /**
29793
- Deserialize a mark from its JSON representation. This method is
29794
- bound.
29795
- */
29796
- markFromJSON(json) {
29797
- return Mark$1.fromJSON(this, json);
29798
- }
29799
- /**
29800
29828
  @internal
29801
29829
  */
29802
29830
  nodeType(name) {
@@ -29978,7 +30006,7 @@ so this becomes the fallback color for the slot */ ''}
29978
30006
  /**
29979
30007
  Construct a DOM parser using the parsing rules listed in a
29980
30008
  schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by
29981
- [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority).
30009
+ [priority](https://prosemirror.net/docs/ref/#model.GenericParseRule.priority).
29982
30010
  */
29983
30011
  static fromSchema(schema) {
29984
30012
  return schema.cached.domParser ||
@@ -30002,7 +30030,7 @@ so this becomes the fallback color for the slot */ ''}
30002
30030
  if (preserveWhitespace != null)
30003
30031
  return (preserveWhitespace ? OPT_PRESERVE_WS : 0) |
30004
30032
  (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0);
30005
- return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & -5;
30033
+ return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & ~OPT_OPEN_LEFT;
30006
30034
  }
30007
30035
  class NodeContext {
30008
30036
  constructor(type, attrs, marks, solid, match, options) {
@@ -30729,6 +30757,8 @@ so this becomes the fallback color for the slot */ ''}
30729
30757
  let space = name.indexOf(" ");
30730
30758
  if (space > 0)
30731
30759
  dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
30760
+ else if (name == "style" && dom.style)
30761
+ dom.style.cssText = attrs[name];
30732
30762
  else
30733
30763
  dom.setAttribute(name, attrs[name]);
30734
30764
  }
@@ -33438,7 +33468,7 @@ so this becomes the fallback color for the slot */ ''}
33438
33468
  throw new RangeError("Selection passed to setSelection must point at the current document");
33439
33469
  this.curSelection = selection;
33440
33470
  this.curSelectionFor = this.steps.length;
33441
- this.updated = (this.updated | UPDATED_SEL) & -3;
33471
+ this.updated = (this.updated | UPDATED_SEL) & ~UPDATED_MARKS;
33442
33472
  this.storedMarks = null;
33443
33473
  return this;
33444
33474
  }
@@ -33489,7 +33519,7 @@ so this becomes the fallback color for the slot */ ''}
33489
33519
  */
33490
33520
  addStep(step, doc) {
33491
33521
  super.addStep(step, doc);
33492
- this.updated = this.updated & -3;
33522
+ this.updated = this.updated & ~UPDATED_MARKS;
33493
33523
  this.storedMarks = null;
33494
33524
  }
33495
33525
  /**
@@ -41835,7 +41865,7 @@ so this becomes the fallback color for the slot */ ''}
41835
41865
  dropEvent = event;
41836
41866
  if (!isDroppedFromProseMirror) {
41837
41867
  const dragFromOtherEditor = tiptapDragFromOtherEditor;
41838
- if (dragFromOtherEditor) {
41868
+ if (dragFromOtherEditor === null || dragFromOtherEditor === void 0 ? void 0 : dragFromOtherEditor.isEditable) {
41839
41869
  // setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0
41840
41870
  setTimeout(() => {
41841
41871
  const selection = dragFromOtherEditor.state.selection;
@@ -42386,7 +42416,7 @@ so this becomes the fallback color for the slot */ ''}
42386
42416
  tr.deleteRange(originRange.from, originRange.to);
42387
42417
  const newPos = tr.mapping.map(targetPos);
42388
42418
  tr.insert(newPos, contentSlice.content);
42389
- tr.setSelection(new TextSelection(tr.doc.resolve(newPos - 1)));
42419
+ tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
42390
42420
  return true;
42391
42421
  };
42392
42422
 
@@ -42818,25 +42848,42 @@ so this becomes the fallback color for the slot */ ''}
42818
42848
  ...options,
42819
42849
  };
42820
42850
  let content;
42821
- try {
42822
- content = createNodeFromContent(value, editor.schema, {
42823
- parseOptions: {
42824
- preserveWhitespace: 'full',
42825
- ...options.parseOptions,
42826
- },
42827
- errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck,
42828
- });
42829
- }
42830
- catch (e) {
42851
+ const emitContentError = (error) => {
42831
42852
  editor.emit('contentError', {
42832
42853
  editor,
42833
- error: e,
42854
+ error,
42834
42855
  disableCollaboration: () => {
42835
42856
  if (editor.storage.collaboration) {
42836
42857
  editor.storage.collaboration.isDisabled = true;
42837
42858
  }
42838
42859
  },
42839
42860
  });
42861
+ };
42862
+ const parseOptions = {
42863
+ preserveWhitespace: 'full',
42864
+ ...options.parseOptions,
42865
+ };
42866
+ // If `emitContentError` is enabled, we want to check the content for errors
42867
+ // but ignore them (do not remove the invalid content from the document)
42868
+ if (!options.errorOnInvalidContent && !editor.options.enableContentCheck && editor.options.emitContentError) {
42869
+ try {
42870
+ createNodeFromContent(value, editor.schema, {
42871
+ parseOptions,
42872
+ errorOnInvalidContent: true,
42873
+ });
42874
+ }
42875
+ catch (e) {
42876
+ emitContentError(e);
42877
+ }
42878
+ }
42879
+ try {
42880
+ content = createNodeFromContent(value, editor.schema, {
42881
+ parseOptions,
42882
+ errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck,
42883
+ });
42884
+ }
42885
+ catch (e) {
42886
+ emitContentError(e);
42840
42887
  return false;
42841
42888
  }
42842
42889
  let { from, to } = typeof position === 'number' ? { from: position, to: position } : { from: position.from, to: position.to };
@@ -44663,6 +44710,10 @@ so this becomes the fallback color for the slot */ ''}
44663
44710
  const isBlock = node.isBlock && !node.isTextblock;
44664
44711
  const isNonTextAtom = node.isAtom && !node.isText;
44665
44712
  const targetPos = this.pos + offset + (isNonTextAtom ? 0 : 1);
44713
+ // Check if targetPos is within valid document range
44714
+ if (targetPos < 0 || targetPos > this.resolvedPos.doc.nodeSize - 2) {
44715
+ return;
44716
+ }
44666
44717
  const $pos = this.resolvedPos.doc.resolve(targetPos);
44667
44718
  if (!isBlock && $pos.depth <= this.depth) {
44668
44719
  return;
@@ -44862,6 +44913,7 @@ img.ProseMirror-separator {
44862
44913
  enablePasteRules: true,
44863
44914
  enableCoreExtensions: true,
44864
44915
  enableContentCheck: false,
44916
+ emitContentError: false,
44865
44917
  onBeforeCreate: () => null,
44866
44918
  onCreate: () => null,
44867
44919
  onUpdate: () => null,
@@ -58881,6 +58933,13 @@ img.ProseMirror-separator {
58881
58933
  return filtered;
58882
58934
  }
58883
58935
 
58936
+ // From DOMPurify
58937
+ // https://github.com/cure53/DOMPurify/blob/main/src/regexp.ts
58938
+ const UNICODE_WHITESPACE_PATTERN = '[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]';
58939
+ const UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN);
58940
+ const UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`);
58941
+ const UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, 'g');
58942
+
58884
58943
  /**
58885
58944
  * Check if the provided tokens form a valid link structure, which can either be a single link token
58886
58945
  * or a link token surrounded by parentheses or square brackets.
@@ -58937,14 +58996,16 @@ img.ProseMirror-separator {
58937
58996
  textBlock = nodesInChangedRanges[0];
58938
58997
  textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, textBlock.pos + textBlock.node.nodeSize, undefined, ' ');
58939
58998
  }
58940
- else if (nodesInChangedRanges.length
58941
- // We want to make sure to include the block seperator argument to treat hard breaks like spaces.
58942
- && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')) {
58999
+ else if (nodesInChangedRanges.length) {
59000
+ const endText = newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ');
59001
+ if (!UNICODE_WHITESPACE_REGEX_END.test(endText)) {
59002
+ return;
59003
+ }
58943
59004
  textBlock = nodesInChangedRanges[0];
58944
59005
  textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, undefined, ' ');
58945
59006
  }
58946
59007
  if (textBlock && textBeforeWhitespace) {
58947
- const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '');
59008
+ const wordsBeforeWhitespace = textBeforeWhitespace.split(UNICODE_WHITESPACE_REGEX).filter(Boolean);
58948
59009
  if (wordsBeforeWhitespace.length <= 0) {
58949
59010
  return false;
58950
59011
  }
@@ -59056,10 +59117,6 @@ img.ProseMirror-separator {
59056
59117
  },
59057
59118
  });
59058
59119
  }
59059
- // From DOMPurify
59060
- // https://github.com/cure53/DOMPurify/blob/main/src/regexp.js
59061
- // eslint-disable-next-line no-control-regex
59062
- const ATTR_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
59063
59120
  function isAllowedUri(uri, protocols) {
59064
59121
  const allowedProtocols = [
59065
59122
  'http',
@@ -59082,9 +59139,7 @@ img.ProseMirror-separator {
59082
59139
  });
59083
59140
  }
59084
59141
  return (!uri
59085
- || uri
59086
- .replace(ATTR_WHITESPACE, '')
59087
- .match(new RegExp(
59142
+ || uri.replace(UNICODE_WHITESPACE_REGEX_GLOBAL, '').match(new RegExp(
59088
59143
  // eslint-disable-next-line no-useless-escape
59089
59144
  `^(?:(?:${allowedProtocols.join('|')}):|[^a-z]|[a-z0-9+.\-]+(?:[^a-z+.\-:]|$))`, 'i')));
59090
59145
  }
@@ -59379,7 +59434,7 @@ img.ProseMirror-separator {
59379
59434
  * This utility allows you to create suggestions.
59380
59435
  * @see https://tiptap.dev/api/utilities/suggestion
59381
59436
  */
59382
- function Suggestion({ pluginKey = SuggestionPluginKey, editor, char = '@', allowSpaces = false, allowToIncludeChar = false, allowedPrefixes = [' '], startOfLine = false, decorationTag = 'span', decorationClass = 'suggestion', command = () => null, items = () => [], render = () => ({}), allow = () => true, findSuggestionMatch: findSuggestionMatch$1 = findSuggestionMatch, }) {
59437
+ function Suggestion({ pluginKey = SuggestionPluginKey, editor, char = '@', allowSpaces = false, allowToIncludeChar = false, allowedPrefixes = [' '], startOfLine = false, decorationTag = 'span', decorationClass = 'suggestion', decorationContent = '', decorationEmptyClass = 'is-empty', command = () => null, items = () => [], render = () => ({}), allow = () => true, findSuggestionMatch: findSuggestionMatch$1 = findSuggestionMatch, }) {
59383
59438
  let props;
59384
59439
  const renderer = render === null || render === void 0 ? void 0 : render();
59385
59440
  const plugin = new Plugin({
@@ -59489,7 +59544,9 @@ img.ProseMirror-separator {
59489
59544
  // * a composition is active (see: https://github.com/ueberdosis/tiptap/issues/1449)
59490
59545
  if (isEditable && (empty || editor.view.composing)) {
59491
59546
  // Reset active state if we just left the previous suggestion range
59492
- if ((from < prev.range.from || from > prev.range.to) && !composing && !prev.composing) {
59547
+ if ((from < prev.range.from || from > prev.range.to)
59548
+ && !composing
59549
+ && !prev.composing) {
59493
59550
  next.active = false;
59494
59551
  }
59495
59552
  // Try to match against where our cursor currently is
@@ -59503,11 +59560,17 @@ img.ProseMirror-separator {
59503
59560
  });
59504
59561
  const decorationId = `id_${Math.floor(Math.random() * 0xffffffff)}`;
59505
59562
  // If we found a match, update the current state to show it
59506
- if (match && allow({
59507
- editor, state, range: match.range, isActive: prev.active,
59508
- })) {
59563
+ if (match
59564
+ && allow({
59565
+ editor,
59566
+ state,
59567
+ range: match.range,
59568
+ isActive: prev.active,
59569
+ })) {
59509
59570
  next.active = true;
59510
- next.decorationId = prev.decorationId ? prev.decorationId : decorationId;
59571
+ next.decorationId = prev.decorationId
59572
+ ? prev.decorationId
59573
+ : decorationId;
59511
59574
  next.range = match.range;
59512
59575
  next.query = match.query;
59513
59576
  next.text = match.text;
@@ -59541,15 +59604,21 @@ img.ProseMirror-separator {
59541
59604
  },
59542
59605
  // Setup decorator on the currently active suggestion.
59543
59606
  decorations(state) {
59544
- const { active, range, decorationId } = plugin.getState(state);
59607
+ const { active, range, decorationId, query, } = plugin.getState(state);
59545
59608
  if (!active) {
59546
59609
  return null;
59547
59610
  }
59611
+ const isEmpty = !(query === null || query === void 0 ? void 0 : query.length);
59612
+ const classNames = [decorationClass];
59613
+ if (isEmpty) {
59614
+ classNames.push(decorationEmptyClass);
59615
+ }
59548
59616
  return DecorationSet.create(state.doc, [
59549
59617
  Decoration.inline(range.from, range.to, {
59550
59618
  nodeName: decorationTag,
59551
- class: decorationClass,
59619
+ class: classNames.join(' '),
59552
59620
  'data-decoration-id': decorationId,
59621
+ 'data-decoration-content': decorationContent,
59553
59622
  }),
59554
59623
  ]);
59555
59624
  },
@@ -59559,10 +59628,91 @@ img.ProseMirror-separator {
59559
59628
  }
59560
59629
 
59561
59630
  /**
59562
- * The plugin key for the mention plugin.
59563
- * @default 'mention'
59631
+ * Returns the suggestion options for a trigger of the Mention extension. These
59632
+ * options are used to create a `Suggestion` ProseMirror plugin. Each plugin lets
59633
+ * you define a different trigger that opens the Mention menu. For example,
59634
+ * you can define a `@` trigger to mention users and a `#` trigger to mention
59635
+ * tags.
59636
+ *
59637
+ * @param param0 The configured options for the suggestion
59638
+ * @returns
59639
+ */
59640
+ function getSuggestionOptions({ editor: tiptapEditor, overrideSuggestionOptions, extensionName, char = '@', }) {
59641
+ const pluginKey = new PluginKey();
59642
+ return {
59643
+ editor: tiptapEditor,
59644
+ char,
59645
+ pluginKey,
59646
+ command: ({ editor, range, props }) => {
59647
+ var _a, _b, _c;
59648
+ // increase range.to by one when the next node is of type "text"
59649
+ // and starts with a space character
59650
+ const nodeAfter = editor.view.state.selection.$to.nodeAfter;
59651
+ const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
59652
+ if (overrideSpace) {
59653
+ range.to += 1;
59654
+ }
59655
+ editor
59656
+ .chain()
59657
+ .focus()
59658
+ .insertContentAt(range, [
59659
+ {
59660
+ type: extensionName,
59661
+ attrs: { ...props, mentionSuggestionChar: char },
59662
+ },
59663
+ {
59664
+ type: 'text',
59665
+ text: ' ',
59666
+ },
59667
+ ])
59668
+ .run();
59669
+ // get reference to `window` object from editor element, to support cross-frame JS usage
59670
+ (_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
59671
+ },
59672
+ allow: ({ state, range }) => {
59673
+ const $from = state.doc.resolve(range.from);
59674
+ const type = state.schema.nodes[extensionName];
59675
+ const allow = !!$from.parent.type.contentMatch.matchType(type);
59676
+ return allow;
59677
+ },
59678
+ ...overrideSuggestionOptions,
59679
+ };
59680
+ }
59681
+
59682
+ /**
59683
+ * Returns the suggestions for the mention extension.
59684
+ *
59685
+ * @param options The extension options
59686
+ * @returns the suggestions
59687
+ */
59688
+ function getSuggestions(options) {
59689
+ return (options.options.suggestions.length ? options.options.suggestions : [options.options.suggestion]).map(suggestion => getSuggestionOptions({
59690
+ // @ts-ignore `editor` can be `undefined` when converting the document to HTML with the HTML utility
59691
+ editor: options.editor,
59692
+ overrideSuggestionOptions: suggestion,
59693
+ extensionName: options.name,
59694
+ char: suggestion.char,
59695
+ }));
59696
+ }
59697
+ /**
59698
+ * Returns the suggestion options of the mention that has a given character trigger. If not
59699
+ * found, it returns the first suggestion.
59700
+ *
59701
+ * @param options The extension options
59702
+ * @param char The character that triggers the mention
59703
+ * @returns The suggestion options
59564
59704
  */
59565
- const MentionPluginKey = new PluginKey('mention');
59705
+ function getSuggestionFromChar(options, char) {
59706
+ const suggestions = getSuggestions(options);
59707
+ const suggestion = suggestions.find(s => s.char === char);
59708
+ if (suggestion) {
59709
+ return suggestion;
59710
+ }
59711
+ if (suggestions.length) {
59712
+ return suggestions[0];
59713
+ }
59714
+ return null;
59715
+ }
59566
59716
  /**
59567
59717
  * This extension allows you to insert mentions into the editor.
59568
59718
  * @see https://www.tiptap.dev/api/extensions/mention
@@ -59573,55 +59723,21 @@ img.ProseMirror-separator {
59573
59723
  addOptions() {
59574
59724
  return {
59575
59725
  HTMLAttributes: {},
59576
- renderText({ options, node }) {
59577
- var _a;
59578
- return `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`;
59726
+ renderText({ node, suggestion }) {
59727
+ var _a, _b;
59728
+ return `${(_a = suggestion === null || suggestion === void 0 ? void 0 : suggestion.char) !== null && _a !== void 0 ? _a : '@'}${(_b = node.attrs.label) !== null && _b !== void 0 ? _b : node.attrs.id}`;
59579
59729
  },
59580
59730
  deleteTriggerWithBackspace: false,
59581
- renderHTML({ options, node }) {
59582
- var _a;
59731
+ renderHTML({ options, node, suggestion }) {
59732
+ var _a, _b;
59583
59733
  return [
59584
59734
  'span',
59585
59735
  mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),
59586
- `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`,
59736
+ `${(_a = suggestion === null || suggestion === void 0 ? void 0 : suggestion.char) !== null && _a !== void 0 ? _a : '@'}${(_b = node.attrs.label) !== null && _b !== void 0 ? _b : node.attrs.id}`,
59587
59737
  ];
59588
59738
  },
59589
- suggestion: {
59590
- char: '@',
59591
- pluginKey: MentionPluginKey,
59592
- command: ({ editor, range, props }) => {
59593
- var _a, _b, _c;
59594
- // increase range.to by one when the next node is of type "text"
59595
- // and starts with a space character
59596
- const nodeAfter = editor.view.state.selection.$to.nodeAfter;
59597
- const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
59598
- if (overrideSpace) {
59599
- range.to += 1;
59600
- }
59601
- editor
59602
- .chain()
59603
- .focus()
59604
- .insertContentAt(range, [
59605
- {
59606
- type: this.name,
59607
- attrs: props,
59608
- },
59609
- {
59610
- type: 'text',
59611
- text: ' ',
59612
- },
59613
- ])
59614
- .run();
59615
- // get reference to `window` object from editor element, to support cross-frame JS usage
59616
- (_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
59617
- },
59618
- allow: ({ state, range }) => {
59619
- const $from = state.doc.resolve(range.from);
59620
- const type = state.schema.nodes[this.name];
59621
- const allow = !!$from.parent.type.contentMatch.matchType(type);
59622
- return allow;
59623
- },
59624
- },
59739
+ suggestions: [],
59740
+ suggestion: {},
59625
59741
  };
59626
59742
  },
59627
59743
  group: 'inline',
@@ -59654,6 +59770,16 @@ img.ProseMirror-separator {
59654
59770
  };
59655
59771
  },
59656
59772
  },
59773
+ // When there are multiple types of mentions, this attribute helps distinguish them
59774
+ mentionSuggestionChar: {
59775
+ default: '@',
59776
+ parseHTML: element => element.getAttribute('data-mention-suggestion-char'),
59777
+ renderHTML: attributes => {
59778
+ return {
59779
+ 'data-mention-suggestion-char': attributes.mentionSuggestionChar,
59780
+ };
59781
+ },
59782
+ },
59657
59783
  };
59658
59784
  },
59659
59785
  parseHTML() {
@@ -59664,6 +59790,7 @@ img.ProseMirror-separator {
59664
59790
  ];
59665
59791
  },
59666
59792
  renderHTML({ node, HTMLAttributes }) {
59793
+ const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar);
59667
59794
  if (this.options.renderLabel !== undefined) {
59668
59795
  console.warn('renderLabel is deprecated use renderText and renderHTML instead');
59669
59796
  return [
@@ -59672,6 +59799,7 @@ img.ProseMirror-separator {
59672
59799
  this.options.renderLabel({
59673
59800
  options: this.options,
59674
59801
  node,
59802
+ suggestion,
59675
59803
  }),
59676
59804
  ];
59677
59805
  }
@@ -59680,6 +59808,7 @@ img.ProseMirror-separator {
59680
59808
  const html = this.options.renderHTML({
59681
59809
  options: mergedOptions,
59682
59810
  node,
59811
+ suggestion,
59683
59812
  });
59684
59813
  if (typeof html === 'string') {
59685
59814
  return [
@@ -59691,17 +59820,16 @@ img.ProseMirror-separator {
59691
59820
  return html;
59692
59821
  },
59693
59822
  renderText({ node }) {
59823
+ const args = {
59824
+ options: this.options,
59825
+ node,
59826
+ suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar),
59827
+ };
59694
59828
  if (this.options.renderLabel !== undefined) {
59695
59829
  console.warn('renderLabel is deprecated use renderText and renderHTML instead');
59696
- return this.options.renderLabel({
59697
- options: this.options,
59698
- node,
59699
- });
59830
+ return this.options.renderLabel(args);
59700
59831
  }
59701
- return this.options.renderText({
59702
- options: this.options,
59703
- node,
59704
- });
59832
+ return this.options.renderText(args);
59705
59833
  },
59706
59834
  addKeyboardShortcuts() {
59707
59835
  return {
@@ -59719,17 +59847,27 @@ img.ProseMirror-separator {
59719
59847
  return false;
59720
59848
  }
59721
59849
  });
59850
+ // Store node and position for later use
59851
+ let mentionNode = new Node$2();
59852
+ let mentionPos = 0;
59853
+ state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
59854
+ if (node.type.name === this.name) {
59855
+ isMention = true;
59856
+ mentionNode = node;
59857
+ mentionPos = pos;
59858
+ return false;
59859
+ }
59860
+ });
59861
+ if (isMention) {
59862
+ tr.insertText(this.options.deleteTriggerWithBackspace ? '' : mentionNode.attrs.mentionSuggestionChar, mentionPos, mentionPos + mentionNode.nodeSize);
59863
+ }
59722
59864
  return isMention;
59723
59865
  }),
59724
59866
  };
59725
59867
  },
59726
59868
  addProseMirrorPlugins() {
59727
- return [
59728
- Suggestion({
59729
- editor: this.editor,
59730
- ...this.options.suggestion,
59731
- }),
59732
- ];
59869
+ // Create a plugin for each suggestion configuration
59870
+ return getSuggestions(this).map(Suggestion);
59733
59871
  },
59734
59872
  });
59735
59873
 
@@ -60092,7 +60230,8 @@ img.ProseMirror-separator {
60092
60230
  mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
60093
60231
  this.options.renderText({
60094
60232
  options: this.options,
60095
- node
60233
+ node,
60234
+ suggestion: null
60096
60235
  })
60097
60236
  ];
60098
60237
  }
@@ -68184,7 +68323,7 @@ focus outline in that case.
68184
68323
  return value;
68185
68324
  }
68186
68325
  }
68187
- const approxEqual = (a, b) => Math.abs(a - b) <= 1;
68326
+ const approxEqual = (a, b) => Math.abs(a - b) < 1.01;
68188
68327
  const debounce = (targetWindow, fn, ms) => {
68189
68328
  let timeoutId;
68190
68329
  return function(...args) {
@@ -68315,7 +68454,6 @@ focus outline in that case.
68315
68454
  this.scrollElement = null;
68316
68455
  this.targetWindow = null;
68317
68456
  this.isScrolling = false;
68318
- this.scrollToIndexTimeoutId = null;
68319
68457
  this.measurementsCache = [];
68320
68458
  this.itemSizeCache = /* @__PURE__ */ new Map();
68321
68459
  this.pendingMeasuredCacheIndexes = [];
@@ -68731,7 +68869,7 @@ focus outline in that case.
68731
68869
  } else if (align === "end") {
68732
68870
  toOffset -= size;
68733
68871
  }
68734
- const maxOffset = this.getTotalSize() - size;
68872
+ const maxOffset = this.getTotalSize() + this.options.scrollMargin - size;
68735
68873
  return Math.max(Math.min(maxOffset, toOffset), 0);
68736
68874
  };
68737
68875
  this.getOffsetForIndex = (index, align = "auto") => {
@@ -68758,14 +68896,7 @@ focus outline in that case.
68758
68896
  ];
68759
68897
  };
68760
68898
  this.isDynamicMode = () => this.elementsCache.size > 0;
68761
- this.cancelScrollToIndex = () => {
68762
- if (this.scrollToIndexTimeoutId !== null && this.targetWindow) {
68763
- this.targetWindow.clearTimeout(this.scrollToIndexTimeoutId);
68764
- this.scrollToIndexTimeoutId = null;
68765
- }
68766
- };
68767
68899
  this.scrollToOffset = (toOffset, { align = "start", behavior } = {}) => {
68768
- this.cancelScrollToIndex();
68769
68900
  if (behavior === "smooth" && this.isDynamicMode()) {
68770
68901
  console.warn(
68771
68902
  "The `smooth` scroll behavior is not fully supported with dynamic size."
@@ -68777,39 +68908,52 @@ focus outline in that case.
68777
68908
  });
68778
68909
  };
68779
68910
  this.scrollToIndex = (index, { align: initialAlign = "auto", behavior } = {}) => {
68780
- index = Math.max(0, Math.min(index, this.options.count - 1));
68781
- this.cancelScrollToIndex();
68782
68911
  if (behavior === "smooth" && this.isDynamicMode()) {
68783
68912
  console.warn(
68784
68913
  "The `smooth` scroll behavior is not fully supported with dynamic size."
68785
68914
  );
68786
68915
  }
68787
- const offsetAndAlign = this.getOffsetForIndex(index, initialAlign);
68788
- if (!offsetAndAlign) return;
68789
- const [offset, align] = offsetAndAlign;
68790
- this._scrollToOffset(offset, { adjustments: void 0, behavior });
68791
- if (behavior !== "smooth" && this.isDynamicMode() && this.targetWindow) {
68792
- this.scrollToIndexTimeoutId = this.targetWindow.setTimeout(() => {
68793
- this.scrollToIndexTimeoutId = null;
68794
- const elementInDOM = this.elementsCache.has(
68795
- this.options.getItemKey(index)
68796
- );
68797
- if (elementInDOM) {
68798
- const result = this.getOffsetForIndex(index, align);
68799
- if (!result) return;
68800
- const [latestOffset] = result;
68801
- const currentScrollOffset = this.getScrollOffset();
68802
- if (!approxEqual(latestOffset, currentScrollOffset)) {
68803
- this.scrollToIndex(index, { align, behavior });
68804
- }
68805
- } else {
68806
- this.scrollToIndex(index, { align, behavior });
68916
+ index = Math.max(0, Math.min(index, this.options.count - 1));
68917
+ let attempts = 0;
68918
+ const maxAttempts = 10;
68919
+ const tryScroll = (currentAlign) => {
68920
+ if (!this.targetWindow) return;
68921
+ const offsetInfo = this.getOffsetForIndex(index, currentAlign);
68922
+ if (!offsetInfo) {
68923
+ console.warn("Failed to get offset for index:", index);
68924
+ return;
68925
+ }
68926
+ const [offset, align] = offsetInfo;
68927
+ this._scrollToOffset(offset, { adjustments: void 0, behavior });
68928
+ this.targetWindow.requestAnimationFrame(() => {
68929
+ const currentOffset = this.getScrollOffset();
68930
+ const afterInfo = this.getOffsetForIndex(index, align);
68931
+ if (!afterInfo) {
68932
+ console.warn("Failed to get offset for index:", index);
68933
+ return;
68934
+ }
68935
+ if (!approxEqual(afterInfo[0], currentOffset)) {
68936
+ scheduleRetry(align);
68807
68937
  }
68808
68938
  });
68809
- }
68939
+ };
68940
+ const scheduleRetry = (align) => {
68941
+ if (!this.targetWindow) return;
68942
+ attempts++;
68943
+ if (attempts < maxAttempts) {
68944
+ if (this.options.debug) {
68945
+ console.info("Schedule retry", attempts, maxAttempts);
68946
+ }
68947
+ this.targetWindow.requestAnimationFrame(() => tryScroll(align));
68948
+ } else {
68949
+ console.warn(
68950
+ `Failed to scroll to index ${index} after ${maxAttempts} attempts.`
68951
+ );
68952
+ }
68953
+ };
68954
+ tryScroll(initialAlign);
68810
68955
  };
68811
68956
  this.scrollBy = (delta, { behavior } = {}) => {
68812
- this.cancelScrollToIndex();
68813
68957
  if (behavior === "smooth" && this.isDynamicMode()) {
68814
68958
  console.warn(
68815
68959
  "The `smooth` scroll behavior is not fully supported with dynamic size."
@@ -79738,7 +79882,7 @@ focus outline in that case.
79738
79882
  /** @ignore */ const isBoolean = (x) => typeof x === 'boolean';
79739
79883
  /** @ignore */ const isFunction = (x) => typeof x === 'function';
79740
79884
  /** @ignore */
79741
- // eslint-disable-next-line @typescript-eslint/ban-types
79885
+ // eslint-disable-next-line @typescript-eslint/no-wrapper-object-types
79742
79886
  const isObject$1 = (x) => x != null && Object(x) === x;
79743
79887
  /** @ignore */
79744
79888
  const isPromise = (x) => {
@@ -79909,6 +80053,7 @@ focus outline in that case.
79909
80053
  const pump$1 = (iterator) => { iterator.next(); return iterator; };
79910
80054
  /** @ignore */
79911
80055
  function* toArrayBufferViewIterator(ArrayCtor, source) {
80056
+ // eslint-disable-next-line unicorn/consistent-function-scoping
79912
80057
  const wrap = function* (x) { yield x; };
79913
80058
  const buffers = (typeof source === 'string') ? wrap(source)
79914
80059
  : (ArrayBuffer.isView(source)) ? wrap(source)
@@ -79931,6 +80076,7 @@ focus outline in that case.
79931
80076
  if (isPromise(source)) {
79932
80077
  return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(toArrayBufferViewAsyncIterator(ArrayCtor, yield __await(source))))));
79933
80078
  }
80079
+ // eslint-disable-next-line unicorn/consistent-function-scoping
79934
80080
  const wrap = function (x) { return __asyncGenerator(this, arguments, function* () { yield yield __await(yield __await(x)); }); };
79935
80081
  const emit = function (source) {
79936
80082
  return __asyncGenerator(this, arguments, function* () {
@@ -80055,7 +80201,8 @@ focus outline in that case.
80055
80201
  } while (!done);
80056
80202
  }
80057
80203
  catch (e) {
80058
- (threw = true) && (typeof it.throw === 'function') && (it.throw(e));
80204
+ threw = true;
80205
+ (typeof it.throw === 'function') && (it.throw(e));
80059
80206
  }
80060
80207
  finally {
80061
80208
  (threw === false) && (typeof it.return === 'function') && (it.return(null));
@@ -80099,7 +80246,8 @@ focus outline in that case.
80099
80246
  } while (!done);
80100
80247
  }
80101
80248
  catch (e) {
80102
- (threw = true) && (typeof it.throw === 'function') && (yield __await(it.throw(e)));
80249
+ threw = true;
80250
+ (typeof it.throw === 'function') && (yield __await(it.throw(e)));
80103
80251
  }
80104
80252
  finally {
80105
80253
  (threw === false) && (typeof it.return === 'function') && (yield __await(it.return(new Uint8Array(0))));
@@ -80147,7 +80295,8 @@ focus outline in that case.
80147
80295
  } while (!done);
80148
80296
  }
80149
80297
  catch (e) {
80150
- (threw = true) && (yield __await(it['cancel'](e)));
80298
+ threw = true;
80299
+ yield __await(it['cancel'](e));
80151
80300
  }
80152
80301
  finally {
80153
80302
  (threw === false) ? (yield __await(it['cancel']()))
@@ -86667,7 +86816,6 @@ focus outline in that case.
86667
86816
  // KIND, either express or implied. See the License for the
86668
86817
  // specific language governing permissions and limitations
86669
86818
  // under the License.
86670
- /* eslint-disable @typescript-eslint/naming-convention */
86671
86819
  var Builder$1 = Builder$2;
86672
86820
  var ByteBuffer$1 = ByteBuffer$2;
86673
86821
  /** @ignore */
@@ -88862,7 +89010,6 @@ focus outline in that case.
88862
89010
  // KIND, either express or implied. See the License for the
88863
89011
  // specific language governing permissions and limitations
88864
89012
  // under the License.
88865
- /* eslint-disable brace-style */
88866
89013
  /** @ignore */
88867
89014
  function schemaFromJSON(_schema, dictionaries = new Map()) {
88868
89015
  return new Schema(schemaFieldsFromJSON(_schema, dictionaries), customMetadataFromJSON(_schema['metadata']), dictionaries);
@@ -89034,7 +89181,6 @@ focus outline in that case.
89034
89181
  // KIND, either express or implied. See the License for the
89035
89182
  // specific language governing permissions and limitations
89036
89183
  // under the License.
89037
- /* eslint-disable brace-style */
89038
89184
  var Builder = Builder$2;
89039
89185
  var ByteBuffer = ByteBuffer$2;
89040
89186
  /**