@ni/spright-components 6.4.24 → 6.4.26

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.
@@ -10117,15 +10117,12 @@
10117
10117
  /* eslint-enable @typescript-eslint/no-non-null-assertion */
10118
10118
 
10119
10119
  /*!
10120
- * tabbable 6.3.0
10120
+ * tabbable 6.4.0
10121
10121
  * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
10122
10122
  */
10123
10123
  // NOTE: separate `:not()` selectors has broader browser support than the newer
10124
10124
  // `:not([inert], [inert] *)` (Feb 2023)
10125
- // CAREFUL: JSDom does not support `:not([inert] *)` as a selector; using it causes
10126
- // the entire query to fail, resulting in no nodes found, which will break a lot
10127
- // of things... so we have to rely on JS to identify nodes inside an inert container
10128
- var candidateSelectors = ['input:not([inert])', 'select:not([inert])', 'textarea:not([inert])', 'a[href]:not([inert])', 'button:not([inert])', '[tabindex]:not(slot):not([inert])', 'audio[controls]:not([inert])', 'video[controls]:not([inert])', '[contenteditable]:not([contenteditable="false"]):not([inert])', 'details>summary:first-of-type:not([inert])', 'details:not([inert])'];
10125
+ var candidateSelectors = ['input:not([inert]):not([inert] *)', 'select:not([inert]):not([inert] *)', 'textarea:not([inert]):not([inert] *)', 'a[href]:not([inert]):not([inert] *)', 'button:not([inert]):not([inert] *)', '[tabindex]:not(slot):not([inert]):not([inert] *)', 'audio[controls]:not([inert]):not([inert] *)', 'video[controls]:not([inert]):not([inert] *)', '[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)', 'details>summary:first-of-type:not([inert]):not([inert] *)', 'details:not([inert]):not([inert] *)'];
10129
10126
  var NoElement = typeof Element === 'undefined';
10130
10127
  var matches$1 = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
10131
10128
  var getRootNode = !NoElement && Element.prototype.getRootNode ? function (element) {
@@ -10134,35 +10131,6 @@
10134
10131
  } : function (element) {
10135
10132
  return element === null || element === void 0 ? void 0 : element.ownerDocument;
10136
10133
  };
10137
-
10138
- /**
10139
- * Determines if a node is inert or in an inert ancestor.
10140
- * @param {Element} [node]
10141
- * @param {boolean} [lookUp] If true and `node` is not inert, looks up at ancestors to
10142
- * see if any of them are inert. If false, only `node` itself is considered.
10143
- * @returns {boolean} True if inert itself or by way of being in an inert ancestor.
10144
- * False if `node` is falsy.
10145
- */
10146
- var _isInert = function isInert(node, lookUp) {
10147
- var _node$getAttribute;
10148
- if (lookUp === void 0) {
10149
- lookUp = true;
10150
- }
10151
- // CAREFUL: JSDom does not support inert at all, so we can't use the `HTMLElement.inert`
10152
- // JS API property; we have to check the attribute, which can either be empty or 'true';
10153
- // if it's `null` (not specified) or 'false', it's an active element
10154
- var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, 'inert');
10155
- var inert = inertAtt === '' || inertAtt === 'true';
10156
-
10157
- // NOTE: this could also be handled with `node.matches('[inert], :is([inert] *)')`
10158
- // if it weren't for `matches()` not being a function on shadow roots; the following
10159
- // code works for any kind of node
10160
- // CAREFUL: JSDom does not appear to support certain selectors like `:not([inert] *)`
10161
- // so it likely would not support `:is([inert] *)` either...
10162
- var result = inert || lookUp && node && _isInert(node.parentNode); // recursive
10163
-
10164
- return result;
10165
- };
10166
10134
  var isInput = function isInput(node) {
10167
10135
  return node.tagName === 'INPUT';
10168
10136
  };
@@ -10379,18 +10347,14 @@
10379
10347
  return false;
10380
10348
  };
10381
10349
  var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(options, node) {
10382
- if (node.disabled ||
10383
- // we must do an inert look up to filter out any elements inside an inert ancestor
10384
- // because we're limited in the type of selectors we can use in JSDom (see related
10385
- // note related to `candidateSelectors`)
10386
- _isInert(node) || isHiddenInput(node) || isHidden(node, options) ||
10350
+ if (node.disabled || isHiddenInput(node) || isHidden(node, options) ||
10387
10351
  // For a details element with a summary, the summary element gets the focus
10388
10352
  isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
10389
10353
  return false;
10390
10354
  }
10391
10355
  return true;
10392
10356
  };
10393
- var focusableCandidateSelector = /* #__PURE__ */candidateSelectors.concat('iframe').join(',');
10357
+ var focusableCandidateSelector = /* #__PURE__ */candidateSelectors.concat('iframe:not([inert]):not([inert] *)').join(',');
10394
10358
  var isFocusable = function isFocusable(node, options) {
10395
10359
  options = options || {};
10396
10360
  if (!node) {
@@ -36582,15 +36546,15 @@ so this becomes the fallback color for the slot */ ''}
36582
36546
  let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
36583
36547
  iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
36584
36548
  if (widget.spec.marks)
36585
- updater.syncToMarks(widget.spec.marks, inline, view);
36549
+ updater.syncToMarks(widget.spec.marks, inline, view, i);
36586
36550
  else if (widget.type.side >= 0 && !insideNode)
36587
- updater.syncToMarks(i == this.node.childCount ? Mark$1.none : this.node.child(i).marks, inline, view);
36551
+ updater.syncToMarks(i == this.node.childCount ? Mark$1.none : this.node.child(i).marks, inline, view, i);
36588
36552
  // If the next node is a desc matching this widget, reuse it,
36589
36553
  // otherwise insert the widget as a new view desc.
36590
36554
  updater.placeWidget(widget, view, off);
36591
36555
  }, (child, outerDeco, innerDeco, i) => {
36592
36556
  // Make sure the wrapping mark descs match the node's marks.
36593
- updater.syncToMarks(child.marks, inline, view);
36557
+ updater.syncToMarks(child.marks, inline, view, i);
36594
36558
  // Try several strategies for drawing this node
36595
36559
  let compIndex;
36596
36560
  if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) ;
@@ -36606,7 +36570,7 @@ so this becomes the fallback color for the slot */ ''}
36606
36570
  off += child.nodeSize;
36607
36571
  });
36608
36572
  // Drop all remaining descs after the current position.
36609
- updater.syncToMarks([], inline, view);
36573
+ updater.syncToMarks([], inline, view, 0);
36610
36574
  if (this.node.isTextblock)
36611
36575
  updater.addTextblockHacks();
36612
36576
  updater.destroyRest();
@@ -36996,7 +36960,7 @@ so this becomes the fallback color for the slot */ ''}
36996
36960
  }
36997
36961
  // Sync the current stack of mark descs with the given array of
36998
36962
  // marks, reusing existing mark descs when possible.
36999
- syncToMarks(marks, inline, view) {
36963
+ syncToMarks(marks, inline, view, parentIndex) {
37000
36964
  let keep = 0, depth = this.stack.length >> 1;
37001
36965
  let maxKeep = Math.min(depth, marks.length);
37002
36966
  while (keep < maxKeep &&
@@ -37012,8 +36976,10 @@ so this becomes the fallback color for the slot */ ''}
37012
36976
  }
37013
36977
  while (depth < marks.length) {
37014
36978
  this.stack.push(this.top, this.index + 1);
37015
- let found = -1;
37016
- for (let i = this.index; i < Math.min(this.index + 3, this.top.children.length); i++) {
36979
+ let found = -1, scanTo = this.top.children.length;
36980
+ if (parentIndex < this.preMatch.index)
36981
+ scanTo = Math.min(this.index + 3, scanTo);
36982
+ for (let i = this.index; i < scanTo; i++) {
37017
36983
  let next = this.top.children[i];
37018
36984
  if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) {
37019
36985
  found = i;
@@ -37209,9 +37175,7 @@ so this becomes the fallback color for the slot */ ''}
37209
37175
  }
37210
37176
  // Iterate from the end of the fragment and array of descs to find
37211
37177
  // directly matching ones, in order to avoid overeagerly reusing those
37212
- // for other nodes. Returns the fragment index of the first node that
37213
- // is part of the sequence of matched nodes at the end of the
37214
- // fragment.
37178
+ // for other nodes.
37215
37179
  function preMatch(frag, parentDesc) {
37216
37180
  let curDesc = parentDesc, descI = curDesc.children.length;
37217
37181
  let fI = frag.childCount, matched = new Map, matches = [];
@@ -37234,7 +37198,6 @@ so this becomes the fallback color for the slot */ ''}
37234
37198
  break outer;
37235
37199
  }
37236
37200
  else {
37237
- // FIXME
37238
37201
  descI = curDesc.parent.children.indexOf(curDesc);
37239
37202
  curDesc = curDesc.parent;
37240
37203
  }
@@ -38281,6 +38244,7 @@ so this becomes the fallback color for the slot */ ''}
38281
38244
  this.compositionNodes = [];
38282
38245
  this.compositionEndedAt = -2e8;
38283
38246
  this.compositionID = 1;
38247
+ this.badSafariComposition = false;
38284
38248
  // Set to a composition ID when there are pending changes at compositionend
38285
38249
  this.compositionPendingChanges = 0;
38286
38250
  this.domChangeCount = 0;
@@ -38727,7 +38691,9 @@ so this becomes the fallback color for the slot */ ''}
38727
38691
  view.input.compositionEndedAt = event.timeStamp;
38728
38692
  view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0;
38729
38693
  view.input.compositionNode = null;
38730
- if (view.input.compositionPendingChanges)
38694
+ if (view.input.badSafariComposition)
38695
+ view.domObserver.forceFlush();
38696
+ else if (view.input.compositionPendingChanges)
38731
38697
  Promise.resolve().then(() => view.domObserver.flush());
38732
38698
  view.input.compositionID++;
38733
38699
  scheduleComposeEnd(view, 20);
@@ -39790,15 +39756,24 @@ so this becomes the fallback color for the slot */ ''}
39790
39756
  new window.MutationObserver(mutations => {
39791
39757
  for (let i = 0; i < mutations.length; i++)
39792
39758
  this.queue.push(mutations[i]);
39793
- // IE11 will sometimes (on backspacing out a single character
39794
- // text node after a BR node) call the observer callback
39795
- // before actually updating the DOM, which will cause
39796
- // ProseMirror to miss the change (see #930)
39797
39759
  if (ie$1 && ie_version <= 11 && mutations.some(m => m.type == "childList" && m.removedNodes.length ||
39798
- m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length))
39760
+ m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length)) {
39761
+ // IE11 will sometimes (on backspacing out a single character
39762
+ // text node after a BR node) call the observer callback
39763
+ // before actually updating the DOM, which will cause
39764
+ // ProseMirror to miss the change (see #930)
39799
39765
  this.flushSoon();
39800
- else
39766
+ }
39767
+ else if (safari && view.composing && mutations.some(m => m.type == "childList" && m.target.nodeName == "TR")) {
39768
+ // Safari does weird stuff when finishing a composition in a
39769
+ // table cell, which tends to involve inserting inappropriate
39770
+ // nodes in the table row.
39771
+ view.input.badSafariComposition = true;
39772
+ this.flushSoon();
39773
+ }
39774
+ else {
39801
39775
  this.flush();
39776
+ }
39802
39777
  });
39803
39778
  if (useCharData) {
39804
39779
  this.onCharData = e => {
@@ -39965,6 +39940,10 @@ so this becomes the fallback color for the slot */ ''}
39965
39940
  view.docView.markDirty(from, to);
39966
39941
  checkCSS(view);
39967
39942
  }
39943
+ if (view.input.badSafariComposition) {
39944
+ view.input.badSafariComposition = false;
39945
+ fixUpBadSafariComposition(view, added);
39946
+ }
39968
39947
  this.handleDOMChange(from, to, typeOver, added);
39969
39948
  if (view.docView && view.docView.dirty)
39970
39949
  view.updateState(view.state);
@@ -40088,6 +40067,37 @@ so this becomes the fallback color for the slot */ ''}
40088
40067
  }
40089
40068
  return null;
40090
40069
  }
40070
+ // Kludge for a Safari bug where, on ending a composition in an
40071
+ // otherwise empty table cell, it randomly moves the composed text
40072
+ // into the table row around that cell, greatly confusing everything
40073
+ // (#188).
40074
+ function fixUpBadSafariComposition(view, addedNodes) {
40075
+ var _a;
40076
+ let { focusNode, focusOffset } = view.domSelectionRange();
40077
+ for (let node of addedNodes) {
40078
+ if (((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.nodeName) == "TR") {
40079
+ let nextCell = node.nextSibling;
40080
+ while (nextCell && (nextCell.nodeName != "TD" && nextCell.nodeName != "TH"))
40081
+ nextCell = nextCell.nextSibling;
40082
+ if (nextCell) {
40083
+ let parent = nextCell;
40084
+ for (;;) {
40085
+ let first = parent.firstChild;
40086
+ if (!first || first.nodeType != 1 || first.contentEditable == "false" ||
40087
+ /^(BR|IMG)$/.test(first.nodeName))
40088
+ break;
40089
+ parent = first;
40090
+ }
40091
+ parent.insertBefore(node, parent.firstChild);
40092
+ if (focusNode == node)
40093
+ view.domSelection().collapse(node, focusOffset);
40094
+ }
40095
+ else {
40096
+ node.parentNode.removeChild(node);
40097
+ }
40098
+ }
40099
+ }
40100
+ }
40091
40101
 
40092
40102
  // Note that all referencing and parsing is done with the
40093
40103
  // start-of-operation selection and document, since that's the one
@@ -40651,7 +40661,7 @@ so this becomes the fallback color for the slot */ ''}
40651
40661
  this.docView.destroy();
40652
40662
  this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this);
40653
40663
  }
40654
- if (chromeKludge && !this.trackWrites)
40664
+ if (chromeKludge && (!this.trackWrites || !this.dom.contains(this.trackWrites)))
40655
40665
  forceSelUpdate = true;
40656
40666
  }
40657
40667
  // Work around for an issue where an update arriving right between
@@ -41778,6 +41788,11 @@ so this becomes the fallback color for the slot */ ''}
41778
41788
  navigator.userAgent.includes("Mac") && "ontouchend" in document;
41779
41789
  }
41780
41790
 
41791
+ // src/utilities/isSafari.ts
41792
+ function isSafari() {
41793
+ return typeof navigator !== "undefined" ? /^((?!chrome|android).)*safari/i.test(navigator.userAgent) : false;
41794
+ }
41795
+
41781
41796
  // src/commands/focus.ts
41782
41797
  var focus = (position = null, options = {}) => ({ editor, view, tr, dispatch }) => {
41783
41798
  options = {
@@ -41788,6 +41803,9 @@ so this becomes the fallback color for the slot */ ''}
41788
41803
  if (isiOS() || isAndroid()) {
41789
41804
  view.dom.focus();
41790
41805
  }
41806
+ if (isSafari() && !isiOS() && !isAndroid()) {
41807
+ view.dom.focus({ preventScroll: true });
41808
+ }
41791
41809
  requestAnimationFrame(() => {
41792
41810
  if (!editor.isDestroyed) {
41793
41811
  view.focus();
@@ -44599,6 +44617,35 @@ so this becomes the fallback color for the slot */ ''}
44599
44617
  })
44600
44618
  );
44601
44619
  }
44620
+ /**
44621
+ * Get the composed dispatchTransaction function from all extensions.
44622
+ * @param baseDispatch The base dispatch function (e.g. from the editor or user props)
44623
+ * @returns A composed dispatch function
44624
+ */
44625
+ dispatchTransaction(baseDispatch) {
44626
+ const { editor } = this;
44627
+ const extensions = sortExtensions([...this.extensions].reverse());
44628
+ return extensions.reduceRight((next, extension) => {
44629
+ const context = {
44630
+ name: extension.name,
44631
+ options: extension.options,
44632
+ storage: this.editor.extensionStorage[extension.name],
44633
+ editor,
44634
+ type: getSchemaTypeByName(extension.name, this.schema)
44635
+ };
44636
+ const dispatchTransaction = getExtensionField(
44637
+ extension,
44638
+ "dispatchTransaction",
44639
+ context
44640
+ );
44641
+ if (!dispatchTransaction) {
44642
+ return next;
44643
+ }
44644
+ return (transaction) => {
44645
+ dispatchTransaction.call(context, { transaction, next });
44646
+ };
44647
+ }, baseDispatch);
44648
+ }
44602
44649
  get markViews() {
44603
44650
  const { editor } = this;
44604
44651
  const { markExtensions } = splitExtensions(this.extensions);
@@ -45433,7 +45480,8 @@ img.ProseMirror-separator {
45433
45480
  },
45434
45481
  onPaste: () => null,
45435
45482
  onDrop: () => null,
45436
- onDelete: () => null
45483
+ onDelete: () => null,
45484
+ enableExtensionDispatchTransaction: true
45437
45485
  };
45438
45486
  this.isCapturingTransaction = false;
45439
45487
  this.capturedTransaction = null;
@@ -45757,15 +45805,17 @@ img.ProseMirror-separator {
45757
45805
  * Creates a ProseMirror view.
45758
45806
  */
45759
45807
  createView(element) {
45760
- var _a;
45808
+ const { editorProps, enableExtensionDispatchTransaction } = this.options;
45809
+ const baseDispatch = editorProps.dispatchTransaction || this.dispatchTransaction.bind(this);
45810
+ const dispatch = enableExtensionDispatchTransaction ? this.extensionManager.dispatchTransaction(baseDispatch) : baseDispatch;
45761
45811
  this.editorView = new EditorView(element, {
45762
- ...this.options.editorProps,
45812
+ ...editorProps,
45763
45813
  attributes: {
45764
45814
  // add `role="textbox"` to the editor element
45765
45815
  role: "textbox",
45766
- ...(_a = this.options.editorProps) == null ? void 0 : _a.attributes
45816
+ ...editorProps == null ? void 0 : editorProps.attributes
45767
45817
  },
45768
- dispatchTransaction: this.dispatchTransaction.bind(this),
45818
+ dispatchTransaction: dispatch,
45769
45819
  state: this.editorState,
45770
45820
  markViews: this.extensionManager.markViews,
45771
45821
  nodeViews: this.extensionManager.nodeViews
@@ -59407,7 +59457,7 @@ ${renderedContent}
59407
59457
  const link = find$1(textContent, { defaultProtocol: options.defaultProtocol }).find(
59408
59458
  (item) => item.isLink && item.value === textContent
59409
59459
  );
59410
- if (!textContent || !link || shouldAutoLink !== void 0 && !shouldAutoLink(link.href)) {
59460
+ if (!textContent || !link || shouldAutoLink !== void 0 && !shouldAutoLink(link.value)) {
59411
59461
  return false;
59412
59462
  }
59413
59463
  return options.editor.commands.setMark(options.type, {
@@ -59474,7 +59524,22 @@ ${renderedContent}
59474
59524
  },
59475
59525
  isAllowedUri: (url, ctx) => !!isAllowedUri(url, ctx.protocols),
59476
59526
  validate: (url) => !!url,
59477
- shouldAutoLink: (url) => !!url
59527
+ shouldAutoLink: (url) => {
59528
+ const hasProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(url);
59529
+ const hasMaybeProtocol = /^[a-z][a-z0-9+.-]*:/i.test(url);
59530
+ if (hasProtocol || hasMaybeProtocol && !url.includes("@")) {
59531
+ return true;
59532
+ }
59533
+ const urlWithoutUserinfo = url.includes("@") ? url.split("@").pop() : url;
59534
+ const hostname = urlWithoutUserinfo.split(/[/?#:]/)[0];
59535
+ if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname)) {
59536
+ return false;
59537
+ }
59538
+ if (!/\./.test(hostname)) {
59539
+ return false;
59540
+ }
59541
+ return true;
59542
+ }
59478
59543
  };
59479
59544
  },
59480
59545
  addAttributes() {
@@ -60487,6 +60552,7 @@ ${nextLine.slice(indentLevel + 2)}`;
60487
60552
  Object.entries(HTMLAttributes).forEach(([key, value]) => {
60488
60553
  listItem.setAttribute(key, value);
60489
60554
  });
60555
+ let prevRenderedAttributeKeys = new Set(Object.keys(HTMLAttributes));
60490
60556
  return {
60491
60557
  dom: listItem,
60492
60558
  contentDOM: content,
@@ -60497,6 +60563,31 @@ ${nextLine.slice(indentLevel + 2)}`;
60497
60563
  listItem.dataset.checked = updatedNode.attrs.checked;
60498
60564
  checkbox.checked = updatedNode.attrs.checked;
60499
60565
  updateA11Y(updatedNode);
60566
+ const extensionAttributes = editor.extensionManager.attributes;
60567
+ const newHTMLAttributes = getRenderedAttributes(updatedNode, extensionAttributes);
60568
+ const newKeys = new Set(Object.keys(newHTMLAttributes));
60569
+ const staticAttrs = this.options.HTMLAttributes;
60570
+ prevRenderedAttributeKeys.forEach((key) => {
60571
+ if (!newKeys.has(key)) {
60572
+ if (key in staticAttrs) {
60573
+ listItem.setAttribute(key, staticAttrs[key]);
60574
+ } else {
60575
+ listItem.removeAttribute(key);
60576
+ }
60577
+ }
60578
+ });
60579
+ Object.entries(newHTMLAttributes).forEach(([key, value]) => {
60580
+ if (value === null || value === void 0) {
60581
+ if (key in staticAttrs) {
60582
+ listItem.setAttribute(key, staticAttrs[key]);
60583
+ } else {
60584
+ listItem.removeAttribute(key);
60585
+ }
60586
+ } else {
60587
+ listItem.setAttribute(key, value);
60588
+ }
60589
+ });
60590
+ prevRenderedAttributeKeys = newKeys;
60500
60591
  return true;
60501
60592
  }
60502
60593
  };
@@ -60730,7 +60821,8 @@ ${nextLine.slice(indentLevel + 2)}`;
60730
60821
  items = () => [],
60731
60822
  render = () => ({}),
60732
60823
  allow = () => true,
60733
- findSuggestionMatch: findSuggestionMatch2 = findSuggestionMatch
60824
+ findSuggestionMatch: findSuggestionMatch2 = findSuggestionMatch,
60825
+ shouldShow
60734
60826
  }) {
60735
60827
  let props;
60736
60828
  const renderer = render == null ? void 0 : render();
@@ -60896,7 +60988,13 @@ ${nextLine.slice(indentLevel + 2)}`;
60896
60988
  state,
60897
60989
  range: match.range,
60898
60990
  isActive: prev.active
60899
- })) {
60991
+ }) && (!shouldShow || shouldShow({
60992
+ editor,
60993
+ range: match.range,
60994
+ query: match.query,
60995
+ text: match.text,
60996
+ transaction
60997
+ }))) {
60900
60998
  next.active = true;
60901
60999
  next.decorationId = prev.decorationId ? prev.decorationId : decorationId;
60902
61000
  next.range = match.range;
@@ -70972,7 +71070,6 @@ focus outline in that case.
70972
71070
  };
70973
71071
  const handler = createHandler(true);
70974
71072
  const endHandler = createHandler(false);
70975
- endHandler();
70976
71073
  element.addEventListener("scroll", handler, addEventListenerOptions);
70977
71074
  const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
70978
71075
  if (registerScrollendEvent) {
@@ -71014,6 +71111,7 @@ focus outline in that case.
71014
71111
  this.scrollElement = null;
71015
71112
  this.targetWindow = null;
71016
71113
  this.isScrolling = false;
71114
+ this.currentScrollToIndex = null;
71017
71115
  this.measurementsCache = [];
71018
71116
  this.itemSizeCache = /* @__PURE__ */ new Map();
71019
71117
  this.laneAssignments = /* @__PURE__ */ new Map();
@@ -71149,10 +71247,6 @@ focus outline in that case.
71149
71247
  this.elementsCache.forEach((cached) => {
71150
71248
  this.observer.observe(cached);
71151
71249
  });
71152
- this._scrollToOffset(this.getScrollOffset(), {
71153
- adjustments: void 0,
71154
- behavior: void 0
71155
- });
71156
71250
  this.unsubs.push(
71157
71251
  this.options.observeElementRect(this, (rect) => {
71158
71252
  this.scrollRect = rect;
@@ -71168,6 +71262,10 @@ focus outline in that case.
71168
71262
  this.maybeNotify();
71169
71263
  })
71170
71264
  );
71265
+ this._scrollToOffset(this.getScrollOffset(), {
71266
+ adjustments: void 0,
71267
+ behavior: void 0
71268
+ });
71171
71269
  }
71172
71270
  };
71173
71271
  this.getSize = () => {
@@ -71239,11 +71337,7 @@ focus outline in that case.
71239
71337
  };
71240
71338
  },
71241
71339
  {
71242
- key: false,
71243
- skipInitialOnChange: true,
71244
- onChange: () => {
71245
- this.notify(this.isScrolling);
71246
- }
71340
+ key: false
71247
71341
  }
71248
71342
  );
71249
71343
  this.getMeasurements = memo(
@@ -71270,7 +71364,7 @@ focus outline in that case.
71270
71364
  this.laneAssignments.clear();
71271
71365
  this.pendingMeasuredCacheIndexes = [];
71272
71366
  }
71273
- if (this.measurementsCache.length === 0) {
71367
+ if (this.measurementsCache.length === 0 && !this.lanesSettling) {
71274
71368
  this.measurementsCache = this.options.initialMeasurementsCache;
71275
71369
  this.measurementsCache.forEach((item) => {
71276
71370
  this.itemSizeCache.set(item.key, item.size);
@@ -71475,7 +71569,17 @@ focus outline in that case.
71475
71569
  )]
71476
71570
  );
71477
71571
  };
71572
+ this.getMaxScrollOffset = () => {
71573
+ if (!this.scrollElement) return 0;
71574
+ if ("scrollHeight" in this.scrollElement) {
71575
+ return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;
71576
+ } else {
71577
+ const doc = this.scrollElement.document.documentElement;
71578
+ return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;
71579
+ }
71580
+ };
71478
71581
  this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
71582
+ if (!this.scrollElement) return 0;
71479
71583
  const size = this.getSize();
71480
71584
  const scrollOffset = this.getScrollOffset();
71481
71585
  if (align === "auto") {
@@ -71486,7 +71590,7 @@ focus outline in that case.
71486
71590
  } else if (align === "end") {
71487
71591
  toOffset -= size;
71488
71592
  }
71489
- const maxOffset = this.getTotalSize() + this.options.scrollMargin - size;
71593
+ const maxOffset = this.getMaxScrollOffset();
71490
71594
  return Math.max(Math.min(maxOffset, toOffset), 0);
71491
71595
  };
71492
71596
  this.getOffsetForIndex = (index, align = "auto") => {
@@ -71506,6 +71610,9 @@ focus outline in that case.
71506
71610
  return [scrollOffset, align];
71507
71611
  }
71508
71612
  }
71613
+ if (align === "end" && index === this.options.count - 1) {
71614
+ return [this.getMaxScrollOffset(), align];
71615
+ }
71509
71616
  const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
71510
71617
  return [
71511
71618
  this.getOffsetForAlignment(toOffset, align, item.size),
@@ -71531,6 +71638,7 @@ focus outline in that case.
71531
71638
  );
71532
71639
  }
71533
71640
  index = Math.max(0, Math.min(index, this.options.count - 1));
71641
+ this.currentScrollToIndex = index;
71534
71642
  let attempts = 0;
71535
71643
  const maxAttempts = 10;
71536
71644
  const tryScroll = (currentAlign) => {
@@ -71543,19 +71651,28 @@ focus outline in that case.
71543
71651
  const [offset, align] = offsetInfo;
71544
71652
  this._scrollToOffset(offset, { adjustments: void 0, behavior });
71545
71653
  this.targetWindow.requestAnimationFrame(() => {
71546
- const currentOffset = this.getScrollOffset();
71547
- const afterInfo = this.getOffsetForIndex(index, align);
71548
- if (!afterInfo) {
71549
- console.warn("Failed to get offset for index:", index);
71550
- return;
71551
- }
71552
- if (!approxEqual(afterInfo[0], currentOffset)) {
71553
- scheduleRetry(align);
71654
+ const verify = () => {
71655
+ if (this.currentScrollToIndex !== index) return;
71656
+ const currentOffset = this.getScrollOffset();
71657
+ const afterInfo = this.getOffsetForIndex(index, align);
71658
+ if (!afterInfo) {
71659
+ console.warn("Failed to get offset for index:", index);
71660
+ return;
71661
+ }
71662
+ if (!approxEqual(afterInfo[0], currentOffset)) {
71663
+ scheduleRetry(align);
71664
+ }
71665
+ };
71666
+ if (this.isDynamicMode()) {
71667
+ this.targetWindow.requestAnimationFrame(verify);
71668
+ } else {
71669
+ verify();
71554
71670
  }
71555
71671
  });
71556
71672
  };
71557
71673
  const scheduleRetry = (align) => {
71558
71674
  if (!this.targetWindow) return;
71675
+ if (this.currentScrollToIndex !== index) return;
71559
71676
  attempts++;
71560
71677
  if (attempts < maxAttempts) {
71561
71678
  if (this.options.debug) {
@@ -77138,7 +77255,7 @@ focus outline in that case.
77138
77255
  });
77139
77256
  }
77140
77257
  resolveOptions(options) {
77141
- if (!options || options.numberTextFormat === NumberTextFormat.default) {
77258
+ if (options?.numberTextFormat === NumberTextFormat.default) {
77142
77259
  return {
77143
77260
  numberTextFormat: NumberTextFormat.default,
77144
77261
  decimalDigits: undefined,
@@ -94031,8 +94148,8 @@ focus outline in that case.
94031
94148
  // significant digits p, where x is positive and p is in [1, 21] or undefined.
94032
94149
  // For example, formatDecimalParts(1.23) returns ["123", 0].
94033
94150
  function formatDecimalParts(x, p) {
94034
- if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
94035
- var i, coefficient = x.slice(0, i);
94151
+ if (!isFinite(x) || x === 0) return null; // NaN, ±Infinity, ±0
94152
+ var i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e"), coefficient = x.slice(0, i);
94036
94153
 
94037
94154
  // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
94038
94155
  // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
@@ -94137,7 +94254,7 @@ focus outline in that case.
94137
94254
 
94138
94255
  function formatPrefixAuto(x, p) {
94139
94256
  var d = formatDecimalParts(x, p);
94140
- if (!d) return x + "";
94257
+ if (!d) return prefixExponent = undefined, x.toPrecision(p);
94141
94258
  var coefficient = d[0],
94142
94259
  exponent = d[1],
94143
94260
  i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
@@ -94191,7 +94308,7 @@ focus outline in that case.
94191
94308
  minus = locale.minus === undefined ? "−" : locale.minus + "",
94192
94309
  nan = locale.nan === undefined ? "NaN" : locale.nan + "";
94193
94310
 
94194
- function newFormat(specifier) {
94311
+ function newFormat(specifier, options) {
94195
94312
  specifier = formatSpecifier(specifier);
94196
94313
 
94197
94314
  var fill = specifier.fill,
@@ -94216,8 +94333,8 @@ focus outline in that case.
94216
94333
 
94217
94334
  // Compute the prefix and suffix.
94218
94335
  // For SI-prefix, the suffix is lazily computed.
94219
- var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
94220
- suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : "";
94336
+ var prefix = (options && options.prefix !== undefined ? options.prefix : "") + (symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : ""),
94337
+ suffix = (symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : "") + (options && options.suffix !== undefined ? options.suffix : "");
94221
94338
 
94222
94339
  // What format function should we use?
94223
94340
  // Is this an integer type?
@@ -94258,7 +94375,7 @@ focus outline in that case.
94258
94375
 
94259
94376
  // Compute the prefix and suffix.
94260
94377
  valuePrefix = (valueNegative ? (sign === "(" ? sign : minus) : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
94261
- valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : "");
94378
+ valueSuffix = (type === "s" && !isNaN(value) && prefixExponent !== undefined ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : "");
94262
94379
 
94263
94380
  // Break the formatted value into the integer “value” part that can be
94264
94381
  // grouped, and fractional or exponential “suffix” part that is not.
@@ -94303,12 +94420,11 @@ focus outline in that case.
94303
94420
  }
94304
94421
 
94305
94422
  function formatPrefix(specifier, value) {
94306
- var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
94307
- e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,
94423
+ var e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,
94308
94424
  k = Math.pow(10, -e),
94309
- prefix = prefixes[8 + e / 3];
94425
+ f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier), {suffix: prefixes[8 + e / 3]});
94310
94426
  return function(value) {
94311
- return f(k * value) + prefix;
94427
+ return f(k * value);
94312
94428
  };
94313
94429
  }
94314
94430