@ni/nimble-components 35.10.0 → 35.11.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.
Files changed (55) hide show
  1. package/dist/all-components-bundle.js +1260 -472
  2. package/dist/all-components-bundle.js.map +1 -1
  3. package/dist/all-components-bundle.min.js +3565 -3320
  4. package/dist/all-components-bundle.min.js.map +1 -1
  5. package/dist/custom-elements.json +90 -0
  6. package/dist/custom-elements.md +11 -10
  7. package/dist/esm/rich-text/editor/models/create-tiptap-editor.js +1 -1
  8. package/dist/esm/rich-text/editor/models/create-tiptap-editor.js.map +1 -1
  9. package/dist/esm/rich-text/editor/testing/rich-text-editor.pageobject.js +1 -1
  10. package/dist/esm/rich-text/editor/testing/rich-text-editor.pageobject.js.map +1 -1
  11. package/dist/esm/rich-text/models/markdown-parser.js +2 -2
  12. package/dist/esm/rich-text/models/markdown-parser.js.map +1 -1
  13. package/dist/esm/table/components/group-row/index.d.ts +6 -0
  14. package/dist/esm/table/components/group-row/index.js +14 -0
  15. package/dist/esm/table/components/group-row/index.js.map +1 -1
  16. package/dist/esm/table/components/group-row/styles.js +91 -5
  17. package/dist/esm/table/components/group-row/styles.js.map +1 -1
  18. package/dist/esm/table/components/group-row/template.js +6 -1
  19. package/dist/esm/table/components/group-row/template.js.map +1 -1
  20. package/dist/esm/table/components/row/index.js +3 -1
  21. package/dist/esm/table/components/row/index.js.map +1 -1
  22. package/dist/esm/table/components/row/styles.js +79 -2
  23. package/dist/esm/table/components/row/styles.js.map +1 -1
  24. package/dist/esm/table/components/row/template.js +43 -31
  25. package/dist/esm/table/components/row/template.js.map +1 -1
  26. package/dist/esm/table/index.d.ts +13 -0
  27. package/dist/esm/table/index.js +51 -2
  28. package/dist/esm/table/index.js.map +1 -1
  29. package/dist/esm/table/models/table-layout-manager.d.ts +1 -1
  30. package/dist/esm/table/models/table-layout-manager.js +8 -6
  31. package/dist/esm/table/models/table-layout-manager.js.map +1 -1
  32. package/dist/esm/table/models/table-update-tracker.d.ts +1 -1
  33. package/dist/esm/table/models/table-update-tracker.js +7 -1
  34. package/dist/esm/table/models/table-update-tracker.js.map +1 -1
  35. package/dist/esm/table/models/table-validator.d.ts +2 -0
  36. package/dist/esm/table/models/table-validator.js +10 -2
  37. package/dist/esm/table/models/table-validator.js.map +1 -1
  38. package/dist/esm/table/styles.js +23 -5
  39. package/dist/esm/table/styles.js.map +1 -1
  40. package/dist/esm/table/template.d.ts +2 -1
  41. package/dist/esm/table/template.js +23 -13
  42. package/dist/esm/table/template.js.map +1 -1
  43. package/dist/esm/table/types.d.ts +9 -0
  44. package/dist/esm/table/types.js +7 -0
  45. package/dist/esm/table/types.js.map +1 -1
  46. package/dist/esm/table-column/base/models/column-internals.d.ts +5 -1
  47. package/dist/esm/table-column/base/models/column-internals.js +4 -1
  48. package/dist/esm/table-column/base/models/column-internals.js.map +1 -1
  49. package/dist/esm/table-column/mapping/index.d.ts +4 -0
  50. package/dist/esm/table-column/mapping/index.js +2 -1
  51. package/dist/esm/table-column/mapping/index.js.map +1 -1
  52. package/dist/esm/table-column/mixins/pinnable-column.d.ts +11 -0
  53. package/dist/esm/table-column/mixins/pinnable-column.js +18 -0
  54. package/dist/esm/table-column/mixins/pinnable-column.js.map +1 -0
  55. package/package.json +2 -2
@@ -10094,12 +10094,12 @@
10094
10094
  /* eslint-enable @typescript-eslint/no-non-null-assertion */
10095
10095
 
10096
10096
  /*!
10097
- * tabbable 6.4.0
10097
+ * tabbable 6.5.0
10098
10098
  * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
10099
10099
  */
10100
10100
  // NOTE: separate `:not()` selectors has broader browser support than the newer
10101
10101
  // `:not([inert], [inert] *)` (Feb 2023)
10102
- 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] *)'];
10102
+ var candidateSelectors = ['input:not([inert]):not([inert] *)', 'select:not([inert]):not([inert] *)', 'textarea:not([inert]):not([inert] *)', 'a[href]:not([inert]):not([inert] *)', 'area[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] *)'];
10103
10103
  var NoElement = typeof Element === 'undefined';
10104
10104
  var matches$1 = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
10105
10105
  var getRootNode = !NoElement && Element.prototype.getRootNode ? function (element) {
@@ -10204,7 +10204,9 @@
10204
10204
  // (this is legacy behavior from a very long way back)
10205
10205
  // NOTE: we check this regardless of `displayCheck="none"` because this is a
10206
10206
  // _visibility_ check, not a _display_ check
10207
- if (getComputedStyle(node).visibility === 'hidden') {
10207
+ var _getComputedStyle = getComputedStyle(node),
10208
+ visibility = _getComputedStyle.visibility;
10209
+ if (visibility === 'hidden' || visibility === 'collapse') {
10208
10210
  return true;
10209
10211
  }
10210
10212
  var isDirectSummary = matches$1.call(node, 'details>summary:first-of-type');
@@ -28860,8 +28862,11 @@ so this becomes the fallback color for the slot */ ''}
28860
28862
  if (!childA.sameMarkup(childB))
28861
28863
  return pos;
28862
28864
  if (childA.isText && childA.text != childB.text) {
28863
- for (let j = 0; childA.text[j] == childB.text[j]; j++)
28865
+ let tA = childA.text, tB = childB.text, j = 0;
28866
+ for (; tA[j] == tB[j]; j++)
28864
28867
  pos++;
28868
+ if (j && j < tA.length && j < tB.length && surrogateHigh(tA.charCodeAt(j - 1)) && surrogateLow(tA.charCodeAt(j)))
28869
+ pos--;
28865
28870
  return pos;
28866
28871
  }
28867
28872
  if (childA.content.size || childB.content.size) {
@@ -28885,12 +28890,17 @@ so this becomes the fallback color for the slot */ ''}
28885
28890
  if (!childA.sameMarkup(childB))
28886
28891
  return { a: posA, b: posB };
28887
28892
  if (childA.isText && childA.text != childB.text) {
28888
- let same = 0, minSize = Math.min(childA.text.length, childB.text.length);
28889
- while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) {
28890
- same++;
28893
+ let tA = childA.text, tB = childB.text, iA = tA.length, iB = tB.length;
28894
+ while (iA > 0 && iB > 0 && tA[iA - 1] == tB[iB - 1]) {
28895
+ iA--;
28896
+ iB--;
28891
28897
  posA--;
28892
28898
  posB--;
28893
28899
  }
28900
+ if (iA && iB && iA < tA.length && surrogateHigh(tA.charCodeAt(iA - 1)) && surrogateLow(tA.charCodeAt(iA))) {
28901
+ posA++;
28902
+ posB++;
28903
+ }
28894
28904
  return { a: posA, b: posB };
28895
28905
  }
28896
28906
  if (childA.content.size || childB.content.size) {
@@ -28902,6 +28912,8 @@ so this becomes the fallback color for the slot */ ''}
28902
28912
  posB -= size;
28903
28913
  }
28904
28914
  }
28915
+ function surrogateLow(ch) { return ch >= 0xDC00 && ch < 0xE000; }
28916
+ function surrogateHigh(ch) { return ch >= 0xD800 && ch < 0xDC00; }
28905
28917
 
28906
28918
  /**
28907
28919
  A fragment represents a node's collection of child nodes.
@@ -29582,7 +29594,8 @@ so this becomes the fallback color for the slot */ ''}
29582
29594
  addNode($end.nodeBefore, target);
29583
29595
  }
29584
29596
  function close(node, content) {
29585
- node.type.checkContent(content);
29597
+ if (!node.type.validContent(content))
29598
+ throw new ReplaceError("Invalid content for node " + node.type.name);
29586
29599
  return node.copy(content);
29587
29600
  }
29588
29601
  function replaceThreeWay($from, $start, $end, $to, depth) {
@@ -30893,13 +30906,12 @@ so this becomes the fallback color for the slot */ ''}
30893
30906
  return built;
30894
30907
  }
30895
30908
  function checkAttrs(attrs, values, type, name) {
30896
- for (let name in values)
30897
- if (!(name in attrs))
30898
- throw new RangeError(`Unsupported attribute ${name} for ${type} of type ${name}`);
30899
- for (let name in attrs) {
30900
- let attr = attrs[name];
30901
- if (attr.validate)
30902
- attr.validate(values[name]);
30909
+ for (let attr in values)
30910
+ if (!(attr in attrs))
30911
+ throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
30912
+ for (let attr in attrs) {
30913
+ if (attrs[attr].validate)
30914
+ attrs[attr].validate(values[attr]);
30903
30915
  }
30904
30916
  }
30905
30917
  function initAttrs(typeName, attrs) {
@@ -38552,14 +38564,14 @@ so this becomes the fallback color for the slot */ ''}
38552
38564
  syncNodeSelection(view, sel);
38553
38565
  if (!editorOwnsSelection(view))
38554
38566
  return;
38555
- // The delayed drag selection causes issues with Cell Selections
38556
- // in Safari. And the drag selection delay is to workarond issues
38557
- // which only present in Chrome.
38558
- if (!force && view.input.mouseDown && view.input.mouseDown.allowDefault && chrome) {
38567
+ // Need to delay selection normalization during a native selection
38568
+ // drag on Chrome, or it will cause further dragging to glitch.
38569
+ let mouseDown = view.input.mouseDown;
38570
+ if (!force && chrome && mouseDown) {
38559
38571
  let domSel = view.domSelectionRange(), curSel = view.domObserver.currentSelection;
38560
38572
  if (domSel.anchorNode && curSel.anchorNode &&
38561
- isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset)) {
38562
- view.input.mouseDown.delayedSelectionSync = true;
38573
+ isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset) &&
38574
+ mouseDown.delaySelUpdate()) {
38563
38575
  view.domObserver.setCurSelection();
38564
38576
  return;
38565
38577
  }
@@ -39411,6 +39423,8 @@ so this becomes the fallback color for the slot */ ''}
39411
39423
  view.input.lastSelectionTime = Date.now();
39412
39424
  }
39413
39425
  function destroyInput(view) {
39426
+ if (view.input.mouseDown)
39427
+ view.input.mouseDown.done();
39414
39428
  view.domObserver.stop();
39415
39429
  for (let type in view.input.eventHandlers)
39416
39430
  view.dom.removeEventListener(type, view.input.eventHandlers[type]);
@@ -39449,7 +39463,7 @@ so this becomes the fallback color for the slot */ ''}
39449
39463
  editHandlers.keydown = (view, _event) => {
39450
39464
  let event = _event;
39451
39465
  view.input.shiftKey = event.keyCode == 16 || event.shiftKey;
39452
- if (inOrNearComposition(view, event))
39466
+ if (inOrNearComposition(view))
39453
39467
  return;
39454
39468
  view.input.lastKeyCode = event.keyCode;
39455
39469
  view.input.lastKeyCodeTime = Date.now();
@@ -39487,7 +39501,7 @@ so this becomes the fallback color for the slot */ ''}
39487
39501
  };
39488
39502
  editHandlers.keypress = (view, _event) => {
39489
39503
  let event = _event;
39490
- if (inOrNearComposition(view, event) || !event.charCode ||
39504
+ if (inOrNearComposition(view) || !event.charCode ||
39491
39505
  event.ctrlKey && !event.altKey || mac$2 && event.metaKey)
39492
39506
  return;
39493
39507
  if (view.someProp("handleKeyPress", f => f(view, event))) {
@@ -39581,26 +39595,28 @@ so this becomes the fallback color for the slot */ ''}
39581
39595
  function defaultTripleClick(view, inside, event) {
39582
39596
  if (event.button != 0)
39583
39597
  return false;
39584
- let doc = view.state.doc;
39585
- if (inside == -1) {
39586
- if (doc.inlineContent) {
39587
- updateSelection(view, TextSelection.create(doc, 0, doc.content.size));
39588
- return true;
39589
- }
39598
+ let selection = selectionForTripleClick(view, inside, true), doc = view.state.doc;
39599
+ if (!selection)
39590
39600
  return false;
39591
- }
39601
+ updateSelection(view, selection);
39602
+ if (selection instanceof TextSelection && doc.eq(view.state.doc))
39603
+ view.input.mouseDown = new TripleClickDrag(view, selection);
39604
+ return true;
39605
+ }
39606
+ function selectionForTripleClick(view, inside, selectNodes) {
39607
+ let doc = view.state.doc;
39608
+ if (inside == -1)
39609
+ return doc.inlineContent ? TextSelection.create(doc, 0, doc.content.size) : null;
39592
39610
  let $pos = doc.resolve(inside);
39593
39611
  for (let i = $pos.depth + 1; i > 0; i--) {
39594
39612
  let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i);
39595
39613
  let nodePos = $pos.before(i);
39596
39614
  if (node.inlineContent)
39597
- updateSelection(view, TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size));
39598
- else if (NodeSelection.isSelectable(node))
39599
- updateSelection(view, NodeSelection.create(doc, nodePos));
39600
- else
39601
- continue;
39602
- return true;
39615
+ return TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size);
39616
+ else if (selectNodes && NodeSelection.isSelectable(node))
39617
+ return NodeSelection.create(doc, nodePos);
39603
39618
  }
39619
+ return null;
39604
39620
  }
39605
39621
  function forceDOMFlush(view) {
39606
39622
  return endComposition(view);
@@ -39619,13 +39635,13 @@ so this becomes the fallback color for the slot */ ''}
39619
39635
  type = "tripleClick";
39620
39636
  }
39621
39637
  view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type, button: event.button };
39638
+ if (view.input.mouseDown)
39639
+ view.input.mouseDown.done();
39622
39640
  let pos = view.posAtCoords(eventCoords(event));
39623
39641
  if (!pos)
39624
39642
  return;
39625
39643
  if (type == "singleClick") {
39626
- if (view.input.mouseDown)
39627
- view.input.mouseDown.done();
39628
- view.input.mouseDown = new MouseDown(view, pos, event, !!flushed);
39644
+ view.input.mouseDown = new LeftMouseDown(view, pos, event, !!flushed);
39629
39645
  }
39630
39646
  else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) {
39631
39647
  event.preventDefault();
@@ -39635,13 +39651,34 @@ so this becomes the fallback color for the slot */ ''}
39635
39651
  }
39636
39652
  };
39637
39653
  class MouseDown {
39638
- constructor(view, pos, event, flushed) {
39654
+ constructor(view) {
39639
39655
  this.view = view;
39656
+ this.mightDrag = null;
39657
+ view.root.addEventListener("mouseup", this.up = this.up.bind(this));
39658
+ view.root.addEventListener("mousemove", this.move = this.move.bind(this));
39659
+ }
39660
+ up(event) {
39661
+ this.done();
39662
+ }
39663
+ move(event) {
39664
+ if (event.buttons == 0)
39665
+ this.done();
39666
+ }
39667
+ done() {
39668
+ this.view.root.removeEventListener("mouseup", this.up);
39669
+ this.view.root.removeEventListener("mousemove", this.move);
39670
+ if (this.view.input.mouseDown == this)
39671
+ this.view.input.mouseDown = null;
39672
+ }
39673
+ delaySelUpdate() { return false; }
39674
+ }
39675
+ class LeftMouseDown extends MouseDown {
39676
+ constructor(view, pos, event, flushed) {
39677
+ super(view);
39640
39678
  this.pos = pos;
39641
39679
  this.event = event;
39642
39680
  this.flushed = flushed;
39643
39681
  this.delayedSelectionSync = false;
39644
- this.mightDrag = null;
39645
39682
  this.startDoc = view.state.doc;
39646
39683
  this.selectNode = !!event[selectNodeModifier];
39647
39684
  this.allowDefault = event.shiftKey;
@@ -39679,13 +39716,10 @@ so this becomes the fallback color for the slot */ ''}
39679
39716
  }, 20);
39680
39717
  this.view.domObserver.start();
39681
39718
  }
39682
- view.root.addEventListener("mouseup", this.up = this.up.bind(this));
39683
- view.root.addEventListener("mousemove", this.move = this.move.bind(this));
39684
39719
  setSelectionOrigin(view, "pointer");
39685
39720
  }
39686
39721
  done() {
39687
- this.view.root.removeEventListener("mouseup", this.up);
39688
- this.view.root.removeEventListener("mousemove", this.move);
39722
+ super.done();
39689
39723
  if (this.mightDrag && this.target) {
39690
39724
  this.view.domObserver.stop();
39691
39725
  if (this.mightDrag.addAttr)
@@ -39695,8 +39729,10 @@ so this becomes the fallback color for the slot */ ''}
39695
39729
  this.view.domObserver.start();
39696
39730
  }
39697
39731
  if (this.delayedSelectionSync)
39698
- setTimeout(() => selectionToDOM(this.view));
39699
- this.view.input.mouseDown = null;
39732
+ setTimeout(() => {
39733
+ if (!this.view.isDestroyed)
39734
+ selectionToDOM(this.view);
39735
+ });
39700
39736
  }
39701
39737
  up(event) {
39702
39738
  this.done();
@@ -39735,14 +39771,41 @@ so this becomes the fallback color for the slot */ ''}
39735
39771
  move(event) {
39736
39772
  this.updateAllowDefault(event);
39737
39773
  setSelectionOrigin(this.view, "pointer");
39738
- if (event.buttons == 0)
39739
- this.done();
39774
+ super.move(event);
39740
39775
  }
39741
39776
  updateAllowDefault(event) {
39742
39777
  if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 ||
39743
39778
  Math.abs(this.event.y - event.clientY) > 4))
39744
39779
  this.allowDefault = true;
39745
39780
  }
39781
+ delaySelUpdate() {
39782
+ if (!this.allowDefault)
39783
+ return false;
39784
+ this.delayedSelectionSync = true;
39785
+ return true;
39786
+ }
39787
+ }
39788
+ class TripleClickDrag extends MouseDown {
39789
+ constructor(view, startSelection) {
39790
+ super(view);
39791
+ this.startSelection = startSelection;
39792
+ this.startDoc = view.state.doc;
39793
+ }
39794
+ move(event) {
39795
+ if (event.buttons == 0 || this.view.isDestroyed || !this.view.state.doc.eq(this.startDoc)) {
39796
+ this.done();
39797
+ return;
39798
+ }
39799
+ event.preventDefault();
39800
+ setSelectionOrigin(this.view, "pointer");
39801
+ let pos = this.view.posAtCoords(eventCoords(event));
39802
+ let target = pos && selectionForTripleClick(this.view, pos.inside, false);
39803
+ if (!target)
39804
+ return;
39805
+ let { doc } = this.view.state, start = this.startSelection;
39806
+ let [anchor, head] = target.from < start.from ? [start.to, target.from] : [start.from, target.to];
39807
+ updateSelection(this.view, TextSelection.create(doc, anchor, head));
39808
+ }
39746
39809
  }
39747
39810
  handlers.touchstart = view => {
39748
39811
  view.input.lastTouch = Date.now();
@@ -39767,7 +39830,7 @@ so this becomes the fallback color for the slot */ ''}
39767
39830
  // This guards against the case where compositionend is triggered without the keyboard
39768
39831
  // (e.g. character confirmation may be done with the mouse), and keydown is triggered
39769
39832
  // afterwards- we wouldn't want to ignore the keydown event in this case.
39770
- if (safari && Math.abs(event.timeStamp - view.input.compositionEndedAt) < 500) {
39833
+ if (safari && Math.abs(Date.now() - view.input.compositionEndedAt) < 500) {
39771
39834
  view.input.compositionEndedAt = -2e8;
39772
39835
  return true;
39773
39836
  }
@@ -39826,7 +39889,7 @@ so this becomes the fallback color for the slot */ ''}
39826
39889
  editHandlers.compositionend = (view, event) => {
39827
39890
  if (view.composing) {
39828
39891
  view.input.composing = false;
39829
- view.input.compositionEndedAt = event.timeStamp;
39892
+ view.input.compositionEndedAt = Date.now();
39830
39893
  view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0;
39831
39894
  view.input.compositionNode = null;
39832
39895
  if (view.input.badSafariComposition)
@@ -39845,7 +39908,7 @@ so this becomes the fallback color for the slot */ ''}
39845
39908
  function clearComposition(view) {
39846
39909
  if (view.composing) {
39847
39910
  view.input.composing = false;
39848
- view.input.compositionEndedAt = timestampFromCustomEvent();
39911
+ view.input.compositionEndedAt = Date.now();
39849
39912
  }
39850
39913
  while (view.input.compositionNodes.length > 0)
39851
39914
  view.input.compositionNodes.pop().markParentsDirty();
@@ -39871,11 +39934,6 @@ so this becomes the fallback color for the slot */ ''}
39871
39934
  }
39872
39935
  return textBefore || textAfter;
39873
39936
  }
39874
- function timestampFromCustomEvent() {
39875
- let event = document.createEvent("Event");
39876
- event.initEvent("event", true, true);
39877
- return event.timeStamp;
39878
- }
39879
39937
  /**
39880
39938
  @internal
39881
39939
  */
@@ -41032,7 +41090,10 @@ so this becomes the fallback color for the slot */ ''}
41032
41090
  }
41033
41091
  }
41034
41092
  }
41035
- if (added.some(n => n.nodeName == "BR") && (view.input.lastKeyCode == 8 || view.input.lastKeyCode == 46)) {
41093
+ if (added.some(n => n.nodeName == "BR") &&
41094
+ (view.input.lastKeyCode == 8 || view.input.lastKeyCode == 46 ||
41095
+ chrome && (view.composing || view.input.compositionEndedAt > Date.now() - 50) &&
41096
+ mutations.some(m => m.type == "childList" && m.removedNodes.length))) {
41036
41097
  // Browsers sometimes insert a bogus break node if you
41037
41098
  // backspace out the last bit of text before an inline-flex node (#1552)
41038
41099
  for (let node of added)
@@ -41588,38 +41649,28 @@ so this becomes the fallback color for the slot */ ''}
41588
41649
  return end;
41589
41650
  }
41590
41651
  function findDiff(a, b, pos, preferredPos, preferredSide) {
41591
- let start = a.findDiffStart(b, pos);
41652
+ let start = a.findDiffStart(b, pos), lenA = pos + a.size, lenB = pos + b.size;
41592
41653
  if (start == null)
41593
41654
  return null;
41594
- let { a: endA, b: endB } = a.findDiffEnd(b, pos + a.size, pos + b.size);
41655
+ let { a: endA, b: endB } = a.findDiffEnd(b, lenA, lenB);
41595
41656
  if (preferredSide == "end") {
41596
41657
  let adjust = Math.max(0, start - Math.min(endA, endB));
41597
41658
  preferredPos -= endA + adjust - start;
41598
41659
  }
41599
- if (endA < start && a.size < b.size) {
41660
+ if (endA < start && lenA < lenB) {
41600
41661
  let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0;
41601
41662
  start -= move;
41602
- if (start && start < b.size && isSurrogatePair(b.textBetween(start - 1, start + 1)))
41603
- start += move ? 1 : -1;
41604
41663
  endB = start + (endB - endA);
41605
41664
  endA = start;
41606
41665
  }
41607
41666
  else if (endB < start) {
41608
41667
  let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0;
41609
41668
  start -= move;
41610
- if (start && start < a.size && isSurrogatePair(a.textBetween(start - 1, start + 1)))
41611
- start += move ? 1 : -1;
41612
41669
  endA = start + (endA - endB);
41613
41670
  endB = start;
41614
41671
  }
41615
41672
  return { start, endA, endB };
41616
41673
  }
41617
- function isSurrogatePair(str) {
41618
- if (str.length != 2)
41619
- return false;
41620
- let a = str.charCodeAt(0), b = str.charCodeAt(1);
41621
- return a >= 0xDC00 && a <= 0xDFFF && b >= 0xD800 && b <= 0xDBFF;
41622
- }
41623
41674
  /**
41624
41675
  An editor view manages the DOM structure that represents an
41625
41676
  editable document. Its state and behavior are determined by its
@@ -41811,9 +41862,10 @@ so this becomes the fallback color for the slot */ ''}
41811
41862
  // a DOM selection change and the "selectionchange" event for it
41812
41863
  // can cause a spurious DOM selection update, disrupting mouse
41813
41864
  // drag selection.
41865
+ let mouseDown = this.input.mouseDown;
41814
41866
  if (forceSelUpdate ||
41815
- !(this.input.mouseDown && this.domObserver.currentSelection.eq(this.domSelectionRange()) &&
41816
- anchorInRightPlace(this))) {
41867
+ !(mouseDown && this.domObserver.currentSelection.eq(this.domSelectionRange()) &&
41868
+ anchorInRightPlace(this) && mouseDown.delaySelUpdate())) {
41817
41869
  selectionToDOM(this, forceSelUpdate);
41818
41870
  }
41819
41871
  else {
@@ -42739,7 +42791,9 @@ so this becomes the fallback color for the slot */ ''}
42739
42791
  function getNodeType(nameOrType, schema) {
42740
42792
  if (typeof nameOrType === "string") {
42741
42793
  if (!schema.nodes[nameOrType]) {
42742
- throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
42794
+ throw Error(
42795
+ `There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`
42796
+ );
42743
42797
  }
42744
42798
  return schema.nodes[nameOrType];
42745
42799
  }
@@ -42898,7 +42952,9 @@ so this becomes the fallback color for the slot */ ''}
42898
42952
  function getMarkType(nameOrType, schema) {
42899
42953
  if (typeof nameOrType === "string") {
42900
42954
  if (!schema.marks[nameOrType]) {
42901
- throw Error(`There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`);
42955
+ throw Error(
42956
+ `There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`
42957
+ );
42902
42958
  }
42903
42959
  return schema.marks[nameOrType];
42904
42960
  }
@@ -42955,9 +43011,17 @@ so this becomes the fallback color for the slot */ ''}
42955
43011
  const minPos = selectionAtStart.from;
42956
43012
  const maxPos = selectionAtEnd.to;
42957
43013
  if (position === "all") {
42958
- return TextSelection.create(doc, minMax(0, minPos, maxPos), minMax(doc.content.size, minPos, maxPos));
43014
+ return TextSelection.create(
43015
+ doc,
43016
+ minMax(0, minPos, maxPos),
43017
+ minMax(doc.content.size, minPos, maxPos)
43018
+ );
42959
43019
  }
42960
- return TextSelection.create(doc, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos));
43020
+ return TextSelection.create(
43021
+ doc,
43022
+ minMax(position, minPos, maxPos),
43023
+ minMax(position, minPos, maxPos)
43024
+ );
42961
43025
  }
42962
43026
 
42963
43027
  // src/utilities/isAndroid.ts
@@ -42967,7 +43031,9 @@ so this becomes the fallback color for the slot */ ''}
42967
43031
 
42968
43032
  // src/utilities/isiOS.ts
42969
43033
  function isiOS() {
42970
- return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes(navigator.platform) || // iPad on iOS 13 detection
43034
+ return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes(
43035
+ navigator.platform
43036
+ ) || // iPad on iOS 13 detection
42971
43037
  navigator.userAgent.includes("Mac") && "ontouchend" in document;
42972
43038
  }
42973
43039
 
@@ -43030,7 +43096,11 @@ so this becomes the fallback color for the slot */ ''}
43030
43096
 
43031
43097
  // src/commands/insertContent.ts
43032
43098
  var insertContent = (value, options) => ({ tr, commands }) => {
43033
- return commands.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, value, options);
43099
+ return commands.insertContentAt(
43100
+ { from: tr.selection.from, to: tr.selection.to },
43101
+ value,
43102
+ options
43103
+ );
43034
43104
  };
43035
43105
 
43036
43106
  // src/utilities/elementFromString.ts
@@ -43048,7 +43118,9 @@ so this becomes the fallback color for the slot */ ''}
43048
43118
  };
43049
43119
  function elementFromString(value) {
43050
43120
  if (typeof window === "undefined") {
43051
- throw new Error("[tiptap error]: there is no window object available, so this function cannot be used");
43121
+ throw new Error(
43122
+ "[tiptap error]: there is no window object available, so this function cannot be used"
43123
+ );
43052
43124
  }
43053
43125
  const wrappedValue = `<body>${value}</body>`;
43054
43126
  const html = new window.DOMParser().parseFromString(wrappedValue, "text/html").body;
@@ -43113,9 +43185,15 @@ so this becomes the fallback color for the slot */ ''}
43113
43185
  })
43114
43186
  });
43115
43187
  if (options.slice) {
43116
- DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
43188
+ DOMParser.fromSchema(contentCheckSchema).parseSlice(
43189
+ elementFromString(content),
43190
+ options.parseOptions
43191
+ );
43117
43192
  } else {
43118
- DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
43193
+ DOMParser.fromSchema(contentCheckSchema).parse(
43194
+ elementFromString(content),
43195
+ options.parseOptions
43196
+ );
43119
43197
  }
43120
43198
  if (options.errorOnInvalidContent && hasInvalidContent) {
43121
43199
  throw new Error("[tiptap error]: Invalid HTML content", {
@@ -43485,7 +43563,11 @@ so this becomes the fallback color for the slot */ ''}
43485
43563
  if (markType === mark.type) {
43486
43564
  canReset = true;
43487
43565
  if (dispatch) {
43488
- tr.addMark(pos, pos + node.nodeSize, markType.create(deleteProps(mark.attrs, attributes)));
43566
+ tr.addMark(
43567
+ pos,
43568
+ pos + node.nodeSize,
43569
+ markType.create(deleteProps(mark.attrs, attributes))
43570
+ );
43489
43571
  }
43490
43572
  }
43491
43573
  });
@@ -43654,7 +43736,11 @@ so this becomes the fallback color for the slot */ ''}
43654
43736
  options: extension.options,
43655
43737
  storage: extension.storage
43656
43738
  };
43657
- const addExtensions = getExtensionField(extension, "addExtensions", context);
43739
+ const addExtensions = getExtensionField(
43740
+ extension,
43741
+ "addExtensions",
43742
+ context
43743
+ );
43658
43744
  if (addExtensions) {
43659
43745
  return [extension, ...flattenExtensions(addExtensions())];
43660
43746
  }
@@ -43692,7 +43778,9 @@ so this becomes the fallback color for the slot */ ''}
43692
43778
 
43693
43779
  // src/helpers/splitExtensions.ts
43694
43780
  function splitExtensions(extensions) {
43695
- const baseExtensions = extensions.filter((extension) => extension.type === "extension");
43781
+ const baseExtensions = extensions.filter(
43782
+ (extension) => extension.type === "extension"
43783
+ );
43696
43784
  const nodeExtensions = extensions.filter((extension) => extension.type === "node");
43697
43785
  const markExtensions = extensions.filter((extension) => extension.type === "mark");
43698
43786
  return {
@@ -43768,11 +43856,7 @@ so this becomes the fallback color for the slot */ ''}
43768
43856
  options: extension.options,
43769
43857
  storage: extension.storage
43770
43858
  };
43771
- const addAttributes = getExtensionField(
43772
- extension,
43773
- "addAttributes",
43774
- context
43775
- );
43859
+ const addAttributes = getExtensionField(extension, "addAttributes", context);
43776
43860
  if (!addAttributes) {
43777
43861
  return;
43778
43862
  }
@@ -43872,10 +43956,15 @@ so this becomes the fallback color for the slot */ ''}
43872
43956
  if (key === "class") {
43873
43957
  const valueClasses = value ? String(value).split(" ") : [];
43874
43958
  const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(" ") : [];
43875
- const insertClasses = valueClasses.filter((valueClass) => !existingClasses.includes(valueClass));
43959
+ const insertClasses = valueClasses.filter(
43960
+ (valueClass) => !existingClasses.includes(valueClass)
43961
+ );
43876
43962
  mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" ");
43877
43963
  } else if (key === "style") {
43878
- const styleMap = new Map([...parseStyleEntries(mergedAttributes[key]), ...parseStyleEntries(value)]);
43964
+ const styleMap = new Map([
43965
+ ...parseStyleEntries(mergedAttributes[key]),
43966
+ ...parseStyleEntries(value)
43967
+ ]);
43879
43968
  mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; ");
43880
43969
  } else {
43881
43970
  mergedAttributes[key] = value;
@@ -43971,7 +44060,9 @@ so this becomes the fallback color for the slot */ ''}
43971
44060
  const topNode = (_a = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))) == null ? void 0 : _a.name;
43972
44061
  const nodes = Object.fromEntries(
43973
44062
  nodeExtensions.map((extension) => {
43974
- const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
44063
+ const extensionAttributes = allAttributes.filter(
44064
+ (attribute) => attribute.type === extension.name
44065
+ );
43975
44066
  const context = {
43976
44067
  name: extension.name,
43977
44068
  options: extension.options,
@@ -43979,7 +44070,11 @@ so this becomes the fallback color for the slot */ ''}
43979
44070
  editor
43980
44071
  };
43981
44072
  const extraNodeFields = extensions.reduce((fields, e) => {
43982
- const extendNodeSchema = getExtensionField(e, "extendNodeSchema", context);
44073
+ const extendNodeSchema = getExtensionField(
44074
+ e,
44075
+ "extendNodeSchema",
44076
+ context
44077
+ );
43983
44078
  return {
43984
44079
  ...fields,
43985
44080
  ...extendNodeSchema ? extendNodeSchema(extension) : {}
@@ -43987,36 +44082,62 @@ so this becomes the fallback color for the slot */ ''}
43987
44082
  }, {});
43988
44083
  const schema = cleanUpSchemaItem({
43989
44084
  ...extraNodeFields,
43990
- content: callOrReturn(getExtensionField(extension, "content", context)),
44085
+ content: callOrReturn(
44086
+ getExtensionField(extension, "content", context)
44087
+ ),
43991
44088
  marks: callOrReturn(getExtensionField(extension, "marks", context)),
43992
44089
  group: callOrReturn(getExtensionField(extension, "group", context)),
43993
44090
  inline: callOrReturn(getExtensionField(extension, "inline", context)),
43994
44091
  atom: callOrReturn(getExtensionField(extension, "atom", context)),
43995
- selectable: callOrReturn(getExtensionField(extension, "selectable", context)),
43996
- draggable: callOrReturn(getExtensionField(extension, "draggable", context)),
44092
+ selectable: callOrReturn(
44093
+ getExtensionField(extension, "selectable", context)
44094
+ ),
44095
+ draggable: callOrReturn(
44096
+ getExtensionField(extension, "draggable", context)
44097
+ ),
43997
44098
  code: callOrReturn(getExtensionField(extension, "code", context)),
43998
- whitespace: callOrReturn(getExtensionField(extension, "whitespace", context)),
44099
+ whitespace: callOrReturn(
44100
+ getExtensionField(extension, "whitespace", context)
44101
+ ),
43999
44102
  linebreakReplacement: callOrReturn(
44000
- getExtensionField(extension, "linebreakReplacement", context)
44103
+ getExtensionField(
44104
+ extension,
44105
+ "linebreakReplacement",
44106
+ context
44107
+ )
44108
+ ),
44109
+ defining: callOrReturn(
44110
+ getExtensionField(extension, "defining", context)
44111
+ ),
44112
+ isolating: callOrReturn(
44113
+ getExtensionField(extension, "isolating", context)
44001
44114
  ),
44002
- defining: callOrReturn(getExtensionField(extension, "defining", context)),
44003
- isolating: callOrReturn(getExtensionField(extension, "isolating", context)),
44004
44115
  attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec))
44005
44116
  });
44006
- const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
44117
+ const parseHTML = callOrReturn(
44118
+ getExtensionField(extension, "parseHTML", context)
44119
+ );
44007
44120
  if (parseHTML) {
44008
44121
  schema.parseDOM = parseHTML.map(
44009
44122
  (parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)
44010
44123
  );
44011
44124
  }
44012
- const renderHTML = getExtensionField(extension, "renderHTML", context);
44125
+ const renderHTML = getExtensionField(
44126
+ extension,
44127
+ "renderHTML",
44128
+ context
44129
+ );
44013
44130
  if (renderHTML) {
44014
44131
  schema.toDOM = (node) => renderHTML({
44015
44132
  node,
44016
44133
  HTMLAttributes: getRenderedAttributes(node, extensionAttributes)
44017
44134
  });
44018
44135
  }
44019
- const renderText = getExtensionField(extension, "renderText", context);
44136
+ const renderText = getExtensionField(
44137
+ extension,
44138
+ "renderText",
44139
+ context
44140
+ );
44020
44141
  if (renderText) {
44021
44142
  schema.toText = renderText;
44022
44143
  }
@@ -44025,7 +44146,9 @@ so this becomes the fallback color for the slot */ ''}
44025
44146
  );
44026
44147
  const marks = Object.fromEntries(
44027
44148
  markExtensions.map((extension) => {
44028
- const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
44149
+ const extensionAttributes = allAttributes.filter(
44150
+ (attribute) => attribute.type === extension.name
44151
+ );
44029
44152
  const context = {
44030
44153
  name: extension.name,
44031
44154
  options: extension.options,
@@ -44033,7 +44156,11 @@ so this becomes the fallback color for the slot */ ''}
44033
44156
  editor
44034
44157
  };
44035
44158
  const extraMarkFields = extensions.reduce((fields, e) => {
44036
- const extendMarkSchema = getExtensionField(e, "extendMarkSchema", context);
44159
+ const extendMarkSchema = getExtensionField(
44160
+ e,
44161
+ "extendMarkSchema",
44162
+ context
44163
+ );
44037
44164
  return {
44038
44165
  ...fields,
44039
44166
  ...extendMarkSchema ? extendMarkSchema(extension) : {}
@@ -44041,20 +44168,32 @@ so this becomes the fallback color for the slot */ ''}
44041
44168
  }, {});
44042
44169
  const schema = cleanUpSchemaItem({
44043
44170
  ...extraMarkFields,
44044
- inclusive: callOrReturn(getExtensionField(extension, "inclusive", context)),
44045
- excludes: callOrReturn(getExtensionField(extension, "excludes", context)),
44171
+ inclusive: callOrReturn(
44172
+ getExtensionField(extension, "inclusive", context)
44173
+ ),
44174
+ excludes: callOrReturn(
44175
+ getExtensionField(extension, "excludes", context)
44176
+ ),
44046
44177
  group: callOrReturn(getExtensionField(extension, "group", context)),
44047
- spanning: callOrReturn(getExtensionField(extension, "spanning", context)),
44178
+ spanning: callOrReturn(
44179
+ getExtensionField(extension, "spanning", context)
44180
+ ),
44048
44181
  code: callOrReturn(getExtensionField(extension, "code", context)),
44049
44182
  attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec))
44050
44183
  });
44051
- const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
44184
+ const parseHTML = callOrReturn(
44185
+ getExtensionField(extension, "parseHTML", context)
44186
+ );
44052
44187
  if (parseHTML) {
44053
44188
  schema.parseDOM = parseHTML.map(
44054
44189
  (parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)
44055
44190
  );
44056
44191
  }
44057
- const renderHTML = getExtensionField(extension, "renderHTML", context);
44192
+ const renderHTML = getExtensionField(
44193
+ extension,
44194
+ "renderHTML",
44195
+ context
44196
+ );
44058
44197
  if (renderHTML) {
44059
44198
  schema.toDOM = (mark) => renderHTML({
44060
44199
  mark,
@@ -44308,16 +44447,20 @@ so this becomes the fallback color for the slot */ ''}
44308
44447
  var getTextContentFromNodes = ($from, maxMatch = 500) => {
44309
44448
  let textBefore = "";
44310
44449
  const sliceEndPos = $from.parentOffset;
44311
- $from.parent.nodesBetween(Math.max(0, sliceEndPos - maxMatch), sliceEndPos, (node, pos, parent, index) => {
44312
- var _a, _b;
44313
- const chunk = ((_b = (_a = node.type.spec).toText) == null ? void 0 : _b.call(_a, {
44314
- node,
44315
- pos,
44316
- parent,
44317
- index
44318
- })) || node.textContent || "%leaf%";
44319
- textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
44320
- });
44450
+ $from.parent.nodesBetween(
44451
+ Math.max(0, sliceEndPos - maxMatch),
44452
+ sliceEndPos,
44453
+ (node, pos, parent, index) => {
44454
+ var _a, _b;
44455
+ const chunk = ((_b = (_a = node.type.spec).toText) == null ? void 0 : _b.call(_a, {
44456
+ node,
44457
+ pos,
44458
+ parent,
44459
+ index
44460
+ })) || node.textContent || "%leaf%";
44461
+ textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
44462
+ }
44463
+ );
44321
44464
  return textBefore;
44322
44465
  };
44323
44466
 
@@ -44688,7 +44831,11 @@ so this becomes the fallback color for the slot */ ''}
44688
44831
  const { selection, doc } = tr;
44689
44832
  const { $from, $to } = selection;
44690
44833
  const extensionAttributes = editor.extensionManager.attributes;
44691
- const newAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs);
44834
+ const newAttributes = getSplittedAttributes(
44835
+ extensionAttributes,
44836
+ $from.node().type.name,
44837
+ $from.node().attrs
44838
+ );
44692
44839
  if (selection instanceof NodeSelection && selection.node.isBlock) {
44693
44840
  if (!$from.parentOffset || !canSplit(doc, $from.pos)) {
44694
44841
  return false;
@@ -44767,7 +44914,7 @@ so this becomes the fallback color for the slot */ ''}
44767
44914
  wrap = Fragment.from($from.node(d).copy(wrap));
44768
44915
  }
44769
44916
  const depthAfter = (
44770
- // eslint-disable-next-line no-nested-ternary
44917
+ // oxlint-disable-next-line no-nested-ternary
44771
44918
  $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3
44772
44919
  );
44773
44920
  const newNextTypeAttributes2 = {
@@ -44996,15 +45143,22 @@ so this becomes the fallback color for the slot */ ''}
44996
45143
  };
44997
45144
 
44998
45145
  // src/commands/unsetAllMarks.ts
44999
- var unsetAllMarks = () => ({ tr, dispatch }) => {
45146
+ var unsetAllMarks = (options = {}) => ({ tr, dispatch, editor }) => {
45147
+ const { ignoreClearable = false } = options;
45000
45148
  const { selection } = tr;
45001
45149
  const { empty, ranges } = selection;
45002
45150
  if (empty) {
45003
45151
  return true;
45004
45152
  }
45153
+ const { nonClearableMarks } = editor.extensionManager;
45005
45154
  if (dispatch) {
45155
+ const clearableMarkTypes = Object.values(editor.schema.marks).filter(
45156
+ (markType) => ignoreClearable || !nonClearableMarks.includes(markType.name)
45157
+ );
45006
45158
  ranges.forEach((range) => {
45007
- tr.removeMark(range.$from.pos, range.$to.pos);
45159
+ for (const markType of clearableMarkTypes) {
45160
+ tr.removeMark(range.$from.pos, range.$to.pos, markType);
45161
+ }
45008
45162
  });
45009
45163
  }
45010
45164
  return true;
@@ -45239,7 +45393,9 @@ so this becomes the fallback color for the slot */ ''}
45239
45393
  result.data = inputRuleMatch.data;
45240
45394
  if (inputRuleMatch.replaceWith) {
45241
45395
  if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
45242
- console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".');
45396
+ console.warn(
45397
+ '[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'
45398
+ );
45243
45399
  }
45244
45400
  result.push(inputRuleMatch.replaceWith);
45245
45401
  }
@@ -45447,7 +45603,7 @@ so this becomes the fallback color for the slot */ ''}
45447
45603
  getExtensionField(this, "addOptions", {
45448
45604
  name: this.name
45449
45605
  })
45450
- ) || {}
45606
+ )
45451
45607
  };
45452
45608
  }
45453
45609
  get storage() {
@@ -45457,7 +45613,7 @@ so this becomes the fallback color for the slot */ ''}
45457
45613
  name: this.name,
45458
45614
  options: this.options
45459
45615
  })
45460
- ) || {}
45616
+ )
45461
45617
  };
45462
45618
  }
45463
45619
  configure(options = {}) {
@@ -45551,7 +45707,9 @@ so this becomes the fallback color for the slot */ ''}
45551
45707
  result.data = pasteRuleMatch.data;
45552
45708
  if (pasteRuleMatch.replaceWith) {
45553
45709
  if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) {
45554
- console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".');
45710
+ console.warn(
45711
+ '[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".'
45712
+ );
45555
45713
  }
45556
45714
  result.push(pasteRuleMatch.replaceWith);
45557
45715
  }
@@ -45693,7 +45851,10 @@ so this becomes the fallback color for the slot */ ''}
45693
45851
  setTimeout(() => {
45694
45852
  const selection = dragFromOtherEditor.state.selection;
45695
45853
  if (selection) {
45696
- dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to });
45854
+ dragFromOtherEditor.commands.deleteRange({
45855
+ from: selection.from,
45856
+ to: selection.to
45857
+ });
45697
45858
  }
45698
45859
  }, 10);
45699
45860
  }
@@ -45758,6 +45919,7 @@ so this becomes the fallback color for the slot */ ''}
45758
45919
  var ExtensionManager = class {
45759
45920
  constructor(extensions, editor) {
45760
45921
  this.splittableMarks = [];
45922
+ this.nonClearableMarks = [];
45761
45923
  this.editor = editor;
45762
45924
  this.baseExtensions = extensions;
45763
45925
  this.extensions = resolveExtensions(extensions);
@@ -45777,7 +45939,11 @@ so this becomes the fallback color for the slot */ ''}
45777
45939
  editor: this.editor,
45778
45940
  type: getSchemaTypeByName(extension.name, this.schema)
45779
45941
  };
45780
- const addCommands = getExtensionField(extension, "addCommands", context);
45942
+ const addCommands = getExtensionField(
45943
+ extension,
45944
+ "addCommands",
45945
+ context
45946
+ );
45781
45947
  if (!addCommands) {
45782
45948
  return commands;
45783
45949
  }
@@ -45822,7 +45988,11 @@ so this becomes the fallback color for the slot */ ''}
45822
45988
  }
45823
45989
  const keyMapPlugin = keymap(defaultBindings);
45824
45990
  plugins.push(keyMapPlugin);
45825
- const addInputRules = getExtensionField(extension, "addInputRules", context);
45991
+ const addInputRules = getExtensionField(
45992
+ extension,
45993
+ "addInputRules",
45994
+ context
45995
+ );
45826
45996
  if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
45827
45997
  const rules = addInputRules();
45828
45998
  if (rules && rules.length) {
@@ -45834,7 +46004,11 @@ so this becomes the fallback color for the slot */ ''}
45834
46004
  plugins.push(...inputPlugins);
45835
46005
  }
45836
46006
  }
45837
- const addPasteRules = getExtensionField(extension, "addPasteRules", context);
46007
+ const addPasteRules = getExtensionField(
46008
+ extension,
46009
+ "addPasteRules",
46010
+ context
46011
+ );
45838
46012
  if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) {
45839
46013
  const rules = addPasteRules();
45840
46014
  if (rules && rules.length) {
@@ -45871,7 +46045,9 @@ so this becomes the fallback color for the slot */ ''}
45871
46045
  const { nodeExtensions } = splitExtensions(this.extensions);
45872
46046
  return Object.fromEntries(
45873
46047
  nodeExtensions.filter((extension) => !!getExtensionField(extension, "addNodeView")).map((extension) => {
45874
- const extensionAttributes = this.attributes.filter((attribute) => attribute.type === extension.name);
46048
+ const extensionAttributes = this.attributes.filter(
46049
+ (attribute) => attribute.type === extension.name
46050
+ );
45875
46051
  const context = {
45876
46052
  name: extension.name,
45877
46053
  options: extension.options,
@@ -45879,7 +46055,11 @@ so this becomes the fallback color for the slot */ ''}
45879
46055
  editor,
45880
46056
  type: getNodeType(extension.name, this.schema)
45881
46057
  };
45882
- const addNodeView = getExtensionField(extension, "addNodeView", context);
46058
+ const addNodeView = getExtensionField(
46059
+ extension,
46060
+ "addNodeView",
46061
+ context
46062
+ );
45883
46063
  if (!addNodeView) {
45884
46064
  return [];
45885
46065
  }
@@ -45973,7 +46153,9 @@ so this becomes the fallback color for the slot */ ''}
45973
46153
  const { markExtensions } = splitExtensions(this.extensions);
45974
46154
  return Object.fromEntries(
45975
46155
  markExtensions.filter((extension) => !!getExtensionField(extension, "addMarkView")).map((extension) => {
45976
- const extensionAttributes = this.attributes.filter((attribute) => attribute.type === extension.name);
46156
+ const extensionAttributes = this.attributes.filter(
46157
+ (attribute) => attribute.type === extension.name
46158
+ );
45977
46159
  const context = {
45978
46160
  name: extension.name,
45979
46161
  options: extension.options,
@@ -45981,7 +46163,11 @@ so this becomes the fallback color for the slot */ ''}
45981
46163
  editor,
45982
46164
  type: getMarkType(extension.name, this.schema)
45983
46165
  };
45984
- const addMarkView = getExtensionField(extension, "addMarkView", context);
46166
+ const addMarkView = getExtensionField(
46167
+ extension,
46168
+ "addMarkView",
46169
+ context
46170
+ );
45985
46171
  if (!addMarkView) {
45986
46172
  return [];
45987
46173
  }
@@ -46045,7 +46231,7 @@ so this becomes the fallback color for the slot */ ''}
46045
46231
  extensions.map((extension) => [extension.name, extension.storage])
46046
46232
  );
46047
46233
  extensions.forEach((extension) => {
46048
- var _a;
46234
+ var _a, _b;
46049
46235
  const context = {
46050
46236
  name: extension.name,
46051
46237
  options: extension.options,
@@ -46058,8 +46244,18 @@ so this becomes the fallback color for the slot */ ''}
46058
46244
  if (keepOnSplit) {
46059
46245
  this.splittableMarks.push(extension.name);
46060
46246
  }
46247
+ const clearable = (_b = callOrReturn(
46248
+ getExtensionField(extension, "clearable", context)
46249
+ )) != null ? _b : true;
46250
+ if (!clearable) {
46251
+ this.nonClearableMarks.push(extension.name);
46252
+ }
46061
46253
  }
46062
- const onBeforeCreate = getExtensionField(extension, "onBeforeCreate", context);
46254
+ const onBeforeCreate = getExtensionField(
46255
+ extension,
46256
+ "onBeforeCreate",
46257
+ context
46258
+ );
46063
46259
  const onCreate = getExtensionField(extension, "onCreate", context);
46064
46260
  const onUpdate = getExtensionField(extension, "onUpdate", context);
46065
46261
  const onSelectionUpdate = getExtensionField(
@@ -46067,7 +46263,11 @@ so this becomes the fallback color for the slot */ ''}
46067
46263
  "onSelectionUpdate",
46068
46264
  context
46069
46265
  );
46070
- const onTransaction = getExtensionField(extension, "onTransaction", context);
46266
+ const onTransaction = getExtensionField(
46267
+ extension,
46268
+ "onTransaction",
46269
+ context
46270
+ );
46071
46271
  const onFocus = getExtensionField(extension, "onFocus", context);
46072
46272
  const onBlur = getExtensionField(extension, "onBlur", context);
46073
46273
  const onDestroy = getExtensionField(extension, "onDestroy", context);
@@ -46158,15 +46358,16 @@ so this becomes the fallback color for the slot */ ''}
46158
46358
  const { editor } = this;
46159
46359
  const { state, schema } = editor;
46160
46360
  const { doc, selection } = state;
46161
- const { ranges } = selection;
46162
- const from = Math.min(...ranges.map((range2) => range2.$from.pos));
46163
- const to = Math.max(...ranges.map((range2) => range2.$to.pos));
46164
46361
  const textSerializers = getTextSerializersFromSchema(schema);
46165
- const range = { from, to };
46166
- return getTextBetween(doc, range, {
46167
- ...this.options.blockSeparator !== void 0 ? { blockSeparator: this.options.blockSeparator } : {},
46362
+ const { blockSeparator } = this.options;
46363
+ const options = {
46364
+ ...blockSeparator !== void 0 ? { blockSeparator } : {},
46168
46365
  textSerializers
46169
- });
46366
+ };
46367
+ const sortedRanges = [...selection.ranges].sort((a, b) => a.$from.pos - b.$from.pos);
46368
+ return sortedRanges.map(
46369
+ ({ $from, $to }) => getTextBetween(doc, { from: $from.pos, to: $to.pos }, options)
46370
+ ).join(blockSeparator != null ? blockSeparator : "\n\n");
46170
46371
  }
46171
46372
  }
46172
46373
  })
@@ -46192,28 +46393,35 @@ so this becomes the fallback color for the slot */ ''}
46192
46393
  if ((_d = (_c2 = (_b2 = (_a2 = this.editor.options.coreExtensionOptions) == null ? void 0 : _a2.delete) == null ? void 0 : _b2.filterTransaction) == null ? void 0 : _c2.call(_b2, transaction)) != null ? _d : transaction.getMeta("y-sync$")) {
46193
46394
  return;
46194
46395
  }
46195
- const nextTransaction = combineTransactionSteps(transaction.before, [transaction, ...appendedTransactions]);
46396
+ const nextTransaction = combineTransactionSteps(transaction.before, [
46397
+ transaction,
46398
+ ...appendedTransactions
46399
+ ]);
46196
46400
  const changes = getChangedRanges(nextTransaction);
46197
46401
  changes.forEach((change) => {
46198
46402
  if (nextTransaction.mapping.mapResult(change.oldRange.from).deletedAfter && nextTransaction.mapping.mapResult(change.oldRange.to).deletedBefore) {
46199
- nextTransaction.before.nodesBetween(change.oldRange.from, change.oldRange.to, (node, from) => {
46200
- const to = from + node.nodeSize - 2;
46201
- const isFullyWithinRange = change.oldRange.from <= from && to <= change.oldRange.to;
46202
- this.editor.emit("delete", {
46203
- type: "node",
46204
- node,
46205
- from,
46206
- to,
46207
- newFrom: nextTransaction.mapping.map(from),
46208
- newTo: nextTransaction.mapping.map(to),
46209
- deletedRange: change.oldRange,
46210
- newRange: change.newRange,
46211
- partial: !isFullyWithinRange,
46212
- editor: this.editor,
46213
- transaction,
46214
- combinedTransform: nextTransaction
46215
- });
46216
- });
46403
+ nextTransaction.before.nodesBetween(
46404
+ change.oldRange.from,
46405
+ change.oldRange.to,
46406
+ (node, from) => {
46407
+ const to = from + node.nodeSize - 2;
46408
+ const isFullyWithinRange = change.oldRange.from <= from && to <= change.oldRange.to;
46409
+ this.editor.emit("delete", {
46410
+ type: "node",
46411
+ node,
46412
+ from,
46413
+ to,
46414
+ newFrom: nextTransaction.mapping.map(from),
46415
+ newTo: nextTransaction.mapping.map(to),
46416
+ deletedRange: change.oldRange,
46417
+ newRange: change.newRange,
46418
+ partial: !isFullyWithinRange,
46419
+ editor: this.editor,
46420
+ transaction,
46421
+ combinedTransform: nextTransaction
46422
+ });
46423
+ }
46424
+ );
46217
46425
  }
46218
46426
  });
46219
46427
  const mapping = nextTransaction.mapping;
@@ -46393,7 +46601,9 @@ so this becomes the fallback color for the slot */ ''}
46393
46601
  return;
46394
46602
  }
46395
46603
  const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc);
46396
- const ignoreTr = transactions.some((transaction) => transaction.getMeta("preventClearDocument"));
46604
+ const ignoreTr = transactions.some(
46605
+ (transaction) => transaction.getMeta("preventClearDocument")
46606
+ );
46397
46607
  if (!docChanges || ignoreTr) {
46398
46608
  return;
46399
46609
  }
@@ -46562,7 +46772,9 @@ so this becomes the fallback color for the slot */ ''}
46562
46772
  let to = this.to;
46563
46773
  if (this.isBlock) {
46564
46774
  if (this.content.size === 0) {
46565
- console.error(`You can\u2019t set content on a block node. Tried to set content on ${this.name} at ${this.pos}`);
46775
+ console.error(
46776
+ `You can\u2019t set content on a block node. Tried to set content on ${this.name} at ${this.pos}`
46777
+ );
46566
46778
  return;
46567
46779
  }
46568
46780
  from = this.from + 1;
@@ -46633,7 +46845,12 @@ so this becomes the fallback color for the slot */ ''}
46633
46845
  if (!isBlock && !isInline && $pos.depth <= this.depth) {
46634
46846
  return;
46635
46847
  }
46636
- const childNodePos = new _NodePos($pos, this.editor, isBlock, isBlock || isInline ? node : null);
46848
+ const childNodePos = new _NodePos(
46849
+ $pos,
46850
+ this.editor,
46851
+ isBlock,
46852
+ isBlock || isInline ? node : null
46853
+ );
46637
46854
  if (isBlock) {
46638
46855
  childNodePos.actualDepth = this.depth + 1;
46639
46856
  }
@@ -46684,7 +46901,9 @@ so this becomes the fallback color for the slot */ ''}
46684
46901
  return;
46685
46902
  }
46686
46903
  if (childPos.node.type.name === selector) {
46687
- const doesAllAttributesMatch = attrKeys.every((key) => attributes[key] === childPos.node.attrs[key]);
46904
+ const doesAllAttributesMatch = attrKeys.every(
46905
+ (key) => attributes[key] === childPos.node.attrs[key]
46906
+ );
46688
46907
  if (doesAllAttributesMatch) {
46689
46908
  nodes.push(childPos);
46690
46909
  }
@@ -46781,7 +47000,7 @@ img.ProseMirror-separator {
46781
47000
 
46782
47001
  // src/utilities/createStyleTag.ts
46783
47002
  function createStyleTag(style2, nonce, suffix) {
46784
- const tiptapStyleTag = document.querySelector(`style[data-tiptap-style${""}]`);
47003
+ const tiptapStyleTag = document.querySelector(`style[data-tiptap-style${suffix ? `-${suffix}` : ""}]`);
46785
47004
  if (tiptapStyleTag !== null) {
46786
47005
  return tiptapStyleTag;
46787
47006
  }
@@ -46789,7 +47008,7 @@ img.ProseMirror-separator {
46789
47008
  if (nonce) {
46790
47009
  styleNode.setAttribute("nonce", nonce);
46791
47010
  }
46792
- styleNode.setAttribute(`data-tiptap-style${""}`, "");
47011
+ styleNode.setAttribute(`data-tiptap-style${suffix ? `-${suffix}` : ""}`, "");
46793
47012
  styleNode.innerHTML = style2;
46794
47013
  document.getElementsByTagName("head")[0].appendChild(styleNode);
46795
47014
  return styleNode;
@@ -47148,7 +47367,9 @@ img.ProseMirror-separator {
47148
47367
  errorOnInvalidContent: this.options.enableContentCheck
47149
47368
  });
47150
47369
  } catch (e) {
47151
- if (!(e instanceof Error) || !["[tiptap error]: Invalid JSON content", "[tiptap error]: Invalid HTML content"].includes(e.message)) {
47370
+ if (!(e instanceof Error) || !["[tiptap error]: Invalid JSON content", "[tiptap error]: Invalid HTML content"].includes(
47371
+ e.message
47372
+ )) {
47152
47373
  throw e;
47153
47374
  }
47154
47375
  this.emit("contentError", {
@@ -47158,7 +47379,9 @@ img.ProseMirror-separator {
47158
47379
  if ("collaboration" in this.storage && typeof this.storage.collaboration === "object" && this.storage.collaboration) {
47159
47380
  this.storage.collaboration.isDisabled = true;
47160
47381
  }
47161
- this.options.extensions = this.options.extensions.filter((extension) => extension.name !== "collaboration");
47382
+ this.options.extensions = this.options.extensions.filter(
47383
+ (extension) => extension.name !== "collaboration"
47384
+ );
47162
47385
  this.createExtensionManager();
47163
47386
  }
47164
47387
  });
@@ -47276,7 +47499,7 @@ img.ProseMirror-separator {
47276
47499
  this.emit("focus", {
47277
47500
  editor: this,
47278
47501
  event: focus2.event,
47279
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
47502
+ // oxlint-disable-next-lineno-non-null-assertion
47280
47503
  transaction: mostRecentFocusTr
47281
47504
  });
47282
47505
  }
@@ -47284,7 +47507,7 @@ img.ProseMirror-separator {
47284
47507
  this.emit("blur", {
47285
47508
  editor: this,
47286
47509
  event: blur2.event,
47287
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
47510
+ // oxlint-disable-next-lineno-non-null-assertion
47288
47511
  transaction: mostRecentFocusTr
47289
47512
  });
47290
47513
  }
@@ -47802,7 +48025,9 @@ ${renderedContent}
47802
48025
  return index !== void 0 ? index : -1;
47803
48026
  },
47804
48027
  tokenize(src, _tokens, _lexer) {
47805
- const tokenPattern = selfClosing ? new RegExp(`^\\[${escapedShortcode}\\s*([^\\]]*)\\]`) : new RegExp(`^\\[${escapedShortcode}\\s*([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escapedShortcode}\\]`);
48028
+ const tokenPattern = selfClosing ? new RegExp(`^\\[${escapedShortcode}\\s*([^\\]]*)\\]`) : new RegExp(
48029
+ `^\\[${escapedShortcode}\\s*([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escapedShortcode}\\]`
48030
+ );
47806
48031
  const match = src.match(tokenPattern);
47807
48032
  if (!match) {
47808
48033
  return void 0;
@@ -48098,7 +48323,9 @@ ${indentedChild}`;
48098
48323
  const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
48099
48324
  return chain().insertContent({ type: this.name }).command(({ tr, dispatch }) => {
48100
48325
  if (dispatch && marks && keepMarks) {
48101
- const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
48326
+ const filteredMarks = marks.filter(
48327
+ (mark) => splittableMarks.includes(mark.type.name)
48328
+ );
48102
48329
  tr.ensureMarks(filteredMarks);
48103
48330
  }
48104
48331
  return true;
@@ -58284,7 +58511,7 @@ ${indentedChild}`;
58284
58511
  href: {},
58285
58512
  rel: { default: 'noopener noreferrer' },
58286
58513
  // Adding `class` here is a workaround to render two mentions without a whitespace as display names
58287
- // This attribute can be removed when the below issue is resolved
58514
+ // For more details on this behavior, refer to the issue below:
58288
58515
  // https://github.com/ni/nimble/issues/1707
58289
58516
  class: { default: '' }
58290
58517
  },
@@ -58323,7 +58550,7 @@ ${indentedChild}`;
58323
58550
  : null,
58324
58551
  rel: node.attrs.rel,
58325
58552
  // Adding `class` here is a workaround to render two mentions without a whitespace as display names
58326
- // This attribute can be removed when the below issue is resolved
58553
+ // For more details on this behavior, refer to the issue below:
58327
58554
  // https://github.com/ni/nimble/issues/1707
58328
58555
  class: href,
58329
58556
  'underline-hidden': _a$4.startsWithHttpOrHttps(href)
@@ -58869,7 +59096,9 @@ ${indentedChild}`;
58869
59096
  }
58870
59097
  const { children, ...rest } = attributes != null ? attributes : {};
58871
59098
  if (tag === "svg") {
58872
- throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");
59099
+ throw new Error(
59100
+ "SVG elements are not supported in the JSX syntax, use the array syntax instead"
59101
+ );
58873
59102
  }
58874
59103
  return [tag, rest, children];
58875
59104
  };
@@ -60840,7 +61069,9 @@ ${indentedChild}`;
60840
61069
  key: new PluginKey("autolink"),
60841
61070
  appendTransaction: (transactions, oldState, newState) => {
60842
61071
  const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc);
60843
- const preventAutolink = transactions.some((transaction) => transaction.getMeta("preventAutolink"));
61072
+ const preventAutolink = transactions.some(
61073
+ (transaction) => transaction.getMeta("preventAutolink")
61074
+ );
60844
61075
  if (!docChanges || preventAutolink) {
60845
61076
  return;
60846
61077
  }
@@ -60848,7 +61079,11 @@ ${indentedChild}`;
60848
61079
  const transform = combineTransactionSteps(oldState.doc, [...transactions]);
60849
61080
  const changes = getChangedRanges(transform);
60850
61081
  changes.forEach(({ newRange }) => {
60851
- const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, (node) => node.isTextblock);
61082
+ const nodesInChangedRanges = findChildrenInRange(
61083
+ newState.doc,
61084
+ newRange,
61085
+ (node) => node.isTextblock
61086
+ );
60852
61087
  let textBlock;
60853
61088
  let textBeforeWhitespace;
60854
61089
  if (nodesInChangedRanges.length > 1) {
@@ -60865,7 +61100,12 @@ ${indentedChild}`;
60865
61100
  return;
60866
61101
  }
60867
61102
  textBlock = nodesInChangedRanges[0];
60868
- textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, void 0, " ");
61103
+ textBeforeWhitespace = newState.doc.textBetween(
61104
+ textBlock.pos,
61105
+ newRange.to,
61106
+ void 0,
61107
+ " "
61108
+ );
60869
61109
  }
60870
61110
  if (textBlock && textBeforeWhitespace) {
60871
61111
  const wordsBeforeWhitespace = textBeforeWhitespace.split(UNICODE_WHITESPACE_REGEX).filter(Boolean);
@@ -60877,7 +61117,9 @@ ${indentedChild}`;
60877
61117
  if (!lastWordBeforeSpace) {
60878
61118
  return false;
60879
61119
  }
60880
- const linksBeforeSpace = tokenize(lastWordBeforeSpace).map((t) => t.toObject(options.defaultProtocol));
61120
+ const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(
61121
+ (t) => t.toObject(options.defaultProtocol)
61122
+ );
60881
61123
  if (!isValidLinkStructure(linksBeforeSpace)) {
60882
61124
  return false;
60883
61125
  }
@@ -60891,7 +61133,9 @@ ${indentedChild}`;
60891
61133
  }
60892
61134
  return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
60893
61135
  }).filter((link) => options.validate(link.value)).filter((link) => options.shouldAutoLink(link.value)).forEach((link) => {
60894
- if (getMarksBetween(link.from, link.to, newState.doc).some((item) => item.mark.type === options.type)) {
61136
+ if (getMarksBetween(link.from, link.to, newState.doc).some(
61137
+ (item) => item.mark.type === options.type
61138
+ )) {
60895
61139
  return;
60896
61140
  }
60897
61141
  tr.addMark(
@@ -60989,7 +61233,18 @@ ${indentedChild}`;
60989
61233
  });
60990
61234
  }
60991
61235
  function isAllowedUri(uri, protocols) {
60992
- const allowedProtocols = ["http", "https", "ftp", "ftps", "mailto", "tel", "callto", "sms", "cid", "xmpp"];
61236
+ const allowedProtocols = [
61237
+ "http",
61238
+ "https",
61239
+ "ftp",
61240
+ "ftps",
61241
+ "mailto",
61242
+ "tel",
61243
+ "callto",
61244
+ "sms",
61245
+ "cid",
61246
+ "xmpp"
61247
+ ];
60993
61248
  if (protocols) {
60994
61249
  protocols.forEach((protocol) => {
60995
61250
  const nextProtocol = typeof protocol === "string" ? protocol : protocol.scheme;
@@ -61000,7 +61255,7 @@ ${indentedChild}`;
61000
61255
  }
61001
61256
  return !uri || uri.replace(UNICODE_WHITESPACE_REGEX_GLOBAL, "").match(
61002
61257
  new RegExp(
61003
- // eslint-disable-next-line no-useless-escape
61258
+ // oxlint-disable-next-line no-useless-escape
61004
61259
  `^(?:(?:${allowedProtocols.join("|")}):|[^a-z]|[a-z0-9+.-]+(?:[^a-z+.-:]|$))`,
61005
61260
  "i"
61006
61261
  )
@@ -61014,7 +61269,9 @@ ${indentedChild}`;
61014
61269
  onCreate() {
61015
61270
  if (this.options.validate && !this.options.shouldAutoLink) {
61016
61271
  this.options.shouldAutoLink = this.options.validate;
61017
- console.warn("The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.");
61272
+ console.warn(
61273
+ "The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead."
61274
+ );
61018
61275
  }
61019
61276
  this.options.protocols.forEach((protocol) => {
61020
61277
  if (typeof protocol === "string") {
@@ -61321,6 +61578,109 @@ ${indentedChild}`;
61321
61578
  return [inputRule];
61322
61579
  }
61323
61580
  });
61581
+
61582
+ // src/helpers/getBranchingNestedListAtCursor.ts
61583
+ var getBranchingNestedListAtCursor = (state, itemName, wrapperNames) => {
61584
+ const { selection } = state;
61585
+ if (!selection.empty) {
61586
+ return null;
61587
+ }
61588
+ const { $from } = selection;
61589
+ if (!$from.parent.isTextblock) {
61590
+ return null;
61591
+ }
61592
+ if ($from.parentOffset !== $from.parent.content.size) {
61593
+ return null;
61594
+ }
61595
+ let listItemDepth = -1;
61596
+ for (let depth = $from.depth; depth > 0; depth -= 1) {
61597
+ if ($from.node(depth).type.name === itemName) {
61598
+ listItemDepth = depth;
61599
+ break;
61600
+ }
61601
+ }
61602
+ if (listItemDepth < 0) {
61603
+ return null;
61604
+ }
61605
+ const listItem = $from.node(listItemDepth);
61606
+ const indexInListItem = $from.index(listItemDepth);
61607
+ if (indexInListItem + 1 >= listItem.childCount) {
61608
+ return null;
61609
+ }
61610
+ const nextChild = listItem.child(indexInListItem + 1);
61611
+ if (!wrapperNames.includes(nextChild.type.name)) {
61612
+ return null;
61613
+ }
61614
+ const itemType = state.schema.nodes[itemName];
61615
+ let hasBranching = false;
61616
+ nextChild.forEach((child) => {
61617
+ if (child.type === itemType && child.childCount > 1) {
61618
+ hasBranching = true;
61619
+ }
61620
+ });
61621
+ if (!hasBranching) {
61622
+ return null;
61623
+ }
61624
+ const nodeAfter = state.doc.resolve($from.after()).nodeAfter;
61625
+ if (!nodeAfter || !wrapperNames.includes(nodeAfter.type.name)) {
61626
+ return null;
61627
+ }
61628
+ const items = [];
61629
+ nodeAfter.forEach((child) => {
61630
+ items.push(child);
61631
+ });
61632
+ if (items.length === 0) {
61633
+ return null;
61634
+ }
61635
+ return {
61636
+ listItemDepth,
61637
+ nestedList: nodeAfter,
61638
+ nestedListPos: $from.after(),
61639
+ insertPos: $from.after(listItemDepth),
61640
+ items
61641
+ };
61642
+ };
61643
+
61644
+ // src/helpers/hoistBranchingNestedList.ts
61645
+ var hoistBranchingNestedList = (state, dispatch, itemName, wrapperNames) => {
61646
+ const context = getBranchingNestedListAtCursor(state, itemName, wrapperNames);
61647
+ if (!context) {
61648
+ return false;
61649
+ }
61650
+ const { selection } = state;
61651
+ const { nestedList, nestedListPos, insertPos, items } = context;
61652
+ const tr = state.tr;
61653
+ tr.delete(nestedListPos, nestedListPos + nestedList.nodeSize);
61654
+ const mappedInsertPos = tr.mapping.map(insertPos);
61655
+ tr.insert(mappedInsertPos, Fragment.from(items));
61656
+ tr.setSelection(selection.map(tr.doc, tr.mapping));
61657
+ if (dispatch) {
61658
+ dispatch(tr);
61659
+ }
61660
+ return true;
61661
+ };
61662
+
61663
+ // src/helpers/handleDeleteBranchingNestedList.ts
61664
+ var handleDeleteBranchingNestedList = (editor, itemName, wrapperNames) => {
61665
+ return hoistBranchingNestedList(editor.state, editor.view.dispatch, itemName, wrapperNames);
61666
+ };
61667
+
61668
+ // src/helpers/createBranchingListDeleteKeymap.ts
61669
+ var createBranchingListDeleteKeymap = (itemName, wrapperNames) => {
61670
+ return Extension.create({
61671
+ name: `${itemName}BranchingDeleteKeymap`,
61672
+ priority: 101,
61673
+ addKeyboardShortcuts() {
61674
+ const handleDelete2 = () => handleDeleteBranchingNestedList(this.editor, itemName, wrapperNames);
61675
+ return {
61676
+ Delete: handleDelete2,
61677
+ "Mod-Delete": handleDelete2
61678
+ };
61679
+ }
61680
+ });
61681
+ };
61682
+
61683
+ // src/item/list-item.ts
61324
61684
  function isSameLineOrderedListToken(token) {
61325
61685
  var _a, _b;
61326
61686
  const nestedToken = (_a = token.tokens) == null ? void 0 : _a[0];
@@ -61435,6 +61795,14 @@ ${indentedChild}`;
61435
61795
  ctx
61436
61796
  );
61437
61797
  },
61798
+ addExtensions() {
61799
+ return [
61800
+ createBranchingListDeleteKeymap(this.name, [
61801
+ this.options.bulletListTypeName,
61802
+ this.options.orderedListTypeName
61803
+ ])
61804
+ ];
61805
+ },
61438
61806
  addKeyboardShortcuts() {
61439
61807
  return {
61440
61808
  Enter: () => this.editor.commands.splitListItem(this.name),
@@ -61499,33 +61867,6 @@ ${indentedChild}`;
61499
61867
  return true;
61500
61868
  };
61501
61869
 
61502
- // src/keymap/listHelpers/hasListItemBefore.ts
61503
- var hasListItemBefore = (typeOrName, state) => {
61504
- var _a;
61505
- const { $anchor } = state.selection;
61506
- const $targetPos = state.doc.resolve($anchor.pos - 2);
61507
- if ($targetPos.index() === 0) {
61508
- return false;
61509
- }
61510
- if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
61511
- return false;
61512
- }
61513
- return true;
61514
- };
61515
- var listItemHasSubList = (typeOrName, state, node) => {
61516
- if (!node) {
61517
- return false;
61518
- }
61519
- const nodeType = getNodeType(typeOrName, state.schema);
61520
- let hasSubList = false;
61521
- node.descendants((child) => {
61522
- if (child.type === nodeType) {
61523
- hasSubList = true;
61524
- }
61525
- });
61526
- return hasSubList;
61527
- };
61528
-
61529
61870
  // src/keymap/listHelpers/handleBackspace.ts
61530
61871
  var handleBackspace = (editor, name, parentListTypes) => {
61531
61872
  if (editor.commands.undoInputRule()) {
@@ -61556,16 +61897,6 @@ ${indentedChild}`;
61556
61897
  if (!isAtStartOfNode(editor.state)) {
61557
61898
  return false;
61558
61899
  }
61559
- const listItemPos = findListItemPos(name, editor.state);
61560
- if (!listItemPos) {
61561
- return false;
61562
- }
61563
- const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2);
61564
- const prevNode = $prev.node(listItemPos.depth);
61565
- const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode);
61566
- if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {
61567
- return editor.commands.joinItemBackward();
61568
- }
61569
61900
  return editor.chain().liftListItem(name).run();
61570
61901
  };
61571
61902
 
@@ -61631,6 +61962,33 @@ ${indentedChild}`;
61631
61962
  return true;
61632
61963
  };
61633
61964
 
61965
+ // src/keymap/listHelpers/hasListItemBefore.ts
61966
+ var hasListItemBefore = (typeOrName, state) => {
61967
+ var _a;
61968
+ const { $anchor } = state.selection;
61969
+ const $targetPos = state.doc.resolve($anchor.pos - 2);
61970
+ if ($targetPos.index() === 0) {
61971
+ return false;
61972
+ }
61973
+ if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) {
61974
+ return false;
61975
+ }
61976
+ return true;
61977
+ };
61978
+ var listItemHasSubList = (typeOrName, state, node) => {
61979
+ if (!node) {
61980
+ return false;
61981
+ }
61982
+ const nodeType = getNodeType(typeOrName, state.schema);
61983
+ let hasSubList = false;
61984
+ node.descendants((child) => {
61985
+ if (child.type === nodeType) {
61986
+ hasSubList = true;
61987
+ }
61988
+ });
61989
+ return hasSubList;
61990
+ };
61991
+
61634
61992
  // src/keymap/list-keymap.ts
61635
61993
  var ListKeymap = Extension.create({
61636
61994
  name: "listKeymap",
@@ -61707,7 +62065,14 @@ ${indentedChild}`;
61707
62065
  var INDENTED_LINE_REGEX = /^\s/;
61708
62066
  function isBlockContentLine(line) {
61709
62067
  const trimmedLine = line.trimStart();
61710
- return /^[-+*]\s+/.test(trimmedLine) || /^\d+\.\s+/.test(trimmedLine) || /^>\s?/.test(trimmedLine) || /^```/.test(trimmedLine) || /^~~~/.test(trimmedLine);
62068
+ return (
62069
+ // oxlint-disable-next-line prefer-string-starts-ends-with
62070
+ /^[-+*]\s+/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with
62071
+ /^\d+\.\s+/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with
62072
+ /^>\s?/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with
62073
+ /^```/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with
62074
+ /^~~~/.test(trimmedLine)
62075
+ );
61711
62076
  }
61712
62077
  function splitItemContent(contentLines) {
61713
62078
  const paragraphLines = [];
@@ -62083,6 +62448,12 @@ ${indentedChild}`;
62083
62448
  const prefix = `- [${checkedChar}] `;
62084
62449
  return renderNestedMarkdownContent(node, h, prefix);
62085
62450
  },
62451
+ addExtensions() {
62452
+ if (!this.options.nested) {
62453
+ return [];
62454
+ }
62455
+ return [createBranchingListDeleteKeymap(this.name, [this.options.taskListTypeName])];
62456
+ },
62086
62457
  addKeyboardShortcuts() {
62087
62458
  const shortcuts = {
62088
62459
  Enter: () => this.editor.commands.splitListItem(this.name),
@@ -62221,7 +62592,11 @@ ${indentedChild}`;
62221
62592
  ];
62222
62593
  },
62223
62594
  renderHTML({ HTMLAttributes }) {
62224
- return ["ul", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }), 0];
62595
+ return [
62596
+ "ul",
62597
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }),
62598
+ 0
62599
+ ];
62225
62600
  },
62226
62601
  parseMarkdown: (token, h) => {
62227
62602
  return h.createNode("taskList", {}, h.parseChildren(token.items || []));
@@ -62358,7 +62733,14 @@ ${indentedChild}`;
62358
62733
  // src/suggestion.ts
62359
62734
  function findSuggestionMatch(config) {
62360
62735
  var _a;
62361
- const { char, allowSpaces: allowSpacesOption, allowToIncludeChar, allowedPrefixes, startOfLine, $position } = config;
62736
+ const {
62737
+ char,
62738
+ allowSpaces: allowSpacesOption,
62739
+ allowToIncludeChar,
62740
+ allowedPrefixes,
62741
+ startOfLine,
62742
+ $position
62743
+ } = config;
62362
62744
  const allowSpaces = allowSpacesOption && !allowToIncludeChar;
62363
62745
  const escapedChar = escapeForRegEx(char);
62364
62746
  const suffix = new RegExp(`\\s${escapedChar}$`);
@@ -62491,7 +62873,11 @@ ${indentedChild}`;
62491
62873
  text: (state == null ? void 0 : state.text) || null,
62492
62874
  items: [],
62493
62875
  command: (commandProps) => {
62494
- return command({ editor, range: (state == null ? void 0 : state.range) || { from: 0, to: 0 }, props: commandProps });
62876
+ return command({
62877
+ editor,
62878
+ range: (state == null ? void 0 : state.range) || { from: 0, to: 0 },
62879
+ props: commandProps
62880
+ });
62495
62881
  },
62496
62882
  decorationNode,
62497
62883
  clientRect: clientRectFor(view, decorationNode)
@@ -62521,7 +62907,9 @@ ${indentedChild}`;
62521
62907
  return;
62522
62908
  }
62523
62909
  const state = handleExit && !handleStart ? prev : next;
62524
- const decorationNode = view.dom.querySelector(`[data-decoration-id="${state.decorationId}"]`);
62910
+ const decorationNode = view.dom.querySelector(
62911
+ `[data-decoration-id="${state.decorationId}"]`
62912
+ );
62525
62913
  props = {
62526
62914
  editor,
62527
62915
  range: state.range,
@@ -62873,7 +63261,11 @@ ${indentedChild}`;
62873
63261
  suggestion
62874
63262
  });
62875
63263
  if (typeof html === "string") {
62876
- return ["span", mergeAttributes({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes), html];
63264
+ return [
63265
+ "span",
63266
+ mergeAttributes({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes),
63267
+ html
63268
+ ];
62877
63269
  }
62878
63270
  return html;
62879
63271
  },
@@ -64206,6 +64598,9 @@ ${indentedChild}`;
64206
64598
  };
64207
64599
  }
64208
64600
  });
64601
+ var DEFAULT_DATA_ATTRIBUTE = "placeholder";
64602
+ var PLUGIN_KEY = new PluginKey("tiptap__placeholder");
64603
+ var VIEWPORT_OVERSCAN_PX = 200;
64209
64604
  function createPlaceholderDecoration(options) {
64210
64605
  const {
64211
64606
  editor,
@@ -64232,6 +64627,96 @@ ${indentedChild}`;
64232
64627
  });
64233
64628
  }
64234
64629
 
64630
+ // src/placeholder/utils/buildPlaceholderDecorations.ts
64631
+ function resolveEmptyNodeClass(emptyNodeClass, props) {
64632
+ return typeof emptyNodeClass === "function" ? emptyNodeClass(props) : emptyNodeClass;
64633
+ }
64634
+ function buildPlaceholderDecorations({
64635
+ editor,
64636
+ options,
64637
+ dataAttribute,
64638
+ doc,
64639
+ selection
64640
+ }) {
64641
+ var _a, _b;
64642
+ const active = editor.isEditable || !options.showOnlyWhenEditable;
64643
+ if (!active) {
64644
+ return null;
64645
+ }
64646
+ const { anchor } = selection;
64647
+ const decorations = [];
64648
+ const isEmptyDoc = editor.isEmpty;
64649
+ const useResolvedPath = options.showOnlyCurrent && !options.includeChildren;
64650
+ if (useResolvedPath) {
64651
+ const resolved = doc.resolve(anchor);
64652
+ const node = resolved.depth > 0 ? resolved.node(1) : resolved.nodeAfter;
64653
+ const nodeStart = resolved.depth > 0 ? resolved.before(1) : anchor;
64654
+ if (node && node.type.isTextblock && isNodeEmpty(node)) {
64655
+ const hasAnchor = anchor >= nodeStart && anchor <= nodeStart + node.nodeSize;
64656
+ decorations.push(
64657
+ createPlaceholderDecoration({
64658
+ editor,
64659
+ isEmptyDoc,
64660
+ dataAttribute,
64661
+ hasAnchor,
64662
+ placeholder: options.placeholder,
64663
+ classes: {
64664
+ emptyEditor: options.emptyEditorClass,
64665
+ emptyNode: resolveEmptyNodeClass(options.emptyNodeClass, {
64666
+ editor,
64667
+ node,
64668
+ pos: nodeStart,
64669
+ hasAnchor
64670
+ })
64671
+ },
64672
+ node,
64673
+ pos: nodeStart
64674
+ })
64675
+ );
64676
+ }
64677
+ } else {
64678
+ const pluginState = PLUGIN_KEY.getState(editor.state);
64679
+ const from = (_a = pluginState == null ? void 0 : pluginState.topPos) != null ? _a : 0;
64680
+ const to = (_b = pluginState == null ? void 0 : pluginState.bottomPos) != null ? _b : doc.content.size;
64681
+ doc.nodesBetween(from, to, (node, pos) => {
64682
+ const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
64683
+ const isEmpty = !node.isLeaf && isNodeEmpty(node);
64684
+ if (!node.type.isTextblock) {
64685
+ return options.includeChildren;
64686
+ }
64687
+ if ((hasAnchor || !options.showOnlyCurrent) && isEmpty) {
64688
+ decorations.push(
64689
+ createPlaceholderDecoration({
64690
+ editor,
64691
+ isEmptyDoc,
64692
+ dataAttribute,
64693
+ hasAnchor,
64694
+ placeholder: options.placeholder,
64695
+ classes: {
64696
+ emptyEditor: options.emptyEditorClass,
64697
+ emptyNode: resolveEmptyNodeClass(options.emptyNodeClass, {
64698
+ editor,
64699
+ node,
64700
+ pos,
64701
+ hasAnchor
64702
+ })
64703
+ },
64704
+ node,
64705
+ pos
64706
+ })
64707
+ );
64708
+ }
64709
+ return options.includeChildren;
64710
+ });
64711
+ }
64712
+ return DecorationSet.create(doc, decorations);
64713
+ }
64714
+
64715
+ // src/placeholder/utils/preparePlaceholderAttribute.ts
64716
+ function preparePlaceholderAttribute(attr) {
64717
+ return attr.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9-]/g, "").replace(/^[0-9-]+/, "").replace(/^-+/, "").toLowerCase();
64718
+ }
64719
+
64235
64720
  // src/placeholder/utils/findScrollParent.ts
64236
64721
  function isScrollable(el) {
64237
64722
  const style = getComputedStyle(el);
@@ -64272,8 +64757,8 @@ ${indentedChild}`;
64272
64757
  }) {
64273
64758
  const editorRect = view.dom.getBoundingClientRect();
64274
64759
  const containerRect = scrollContainer ? getContainerRect(scrollContainer) : { top: 0, bottom: window.innerHeight };
64275
- const visibleTop = Math.max(editorRect.top, containerRect.top);
64276
- const visibleBottom = Math.min(editorRect.bottom, containerRect.bottom);
64760
+ const visibleTop = Math.max(editorRect.top, containerRect.top) - VIEWPORT_OVERSCAN_PX;
64761
+ const visibleBottom = Math.min(editorRect.bottom, containerRect.bottom) + VIEWPORT_OVERSCAN_PX;
64277
64762
  if (visibleTop >= visibleBottom) {
64278
64763
  return { top: 0, bottom: doc.content.size };
64279
64764
  }
@@ -64287,33 +64772,97 @@ ${indentedChild}`;
64287
64772
  };
64288
64773
  }
64289
64774
 
64290
- // src/placeholder/utils/throttle.ts
64291
- function throttle(fn, delay) {
64292
- let timer = null;
64293
- const call = ((...args) => {
64294
- if (timer) {
64775
+ // src/placeholder/utils/viewportTracking.ts
64776
+ var viewportPluginState = {
64777
+ /**
64778
+ * Initialises the viewport state with no known positions.
64779
+ * @returns The initial viewport state.
64780
+ */
64781
+ init() {
64782
+ return { topPos: null, bottomPos: null };
64783
+ },
64784
+ /**
64785
+ * Updates the viewport state from incoming transactions.
64786
+ * @param tr - The transaction being applied.
64787
+ * @param prev - The previous viewport state.
64788
+ * @returns The next viewport state.
64789
+ */
64790
+ apply(tr, prev) {
64791
+ const meta = tr.getMeta(PLUGIN_KEY);
64792
+ if (meta == null ? void 0 : meta.positions) {
64793
+ return { topPos: meta.positions.top, bottomPos: meta.positions.bottom };
64794
+ }
64795
+ if (!tr.docChanged) {
64796
+ return prev;
64797
+ }
64798
+ return {
64799
+ topPos: prev.topPos !== null ? tr.mapping.map(prev.topPos) : null,
64800
+ bottomPos: prev.bottomPos !== null ? tr.mapping.map(prev.bottomPos) : null
64801
+ };
64802
+ }
64803
+ };
64804
+ function createViewportPluginView(view) {
64805
+ const scrollContainer = findScrollParent(view.dom);
64806
+ const computeAndDispatch = () => {
64807
+ const positions = getViewportBoundaryPositions({
64808
+ view,
64809
+ doc: view.state.doc,
64810
+ scrollContainer
64811
+ });
64812
+ const prev = PLUGIN_KEY.getState(view.state);
64813
+ if ((prev == null ? void 0 : prev.topPos) === positions.top && (prev == null ? void 0 : prev.bottomPos) === positions.bottom) {
64295
64814
  return;
64296
64815
  }
64297
- fn(...args);
64298
- timer = setTimeout(() => {
64299
- timer = null;
64300
- }, delay);
64301
- });
64302
- const cancel = () => {
64303
- if (timer) {
64304
- clearTimeout(timer);
64305
- timer = null;
64816
+ const tr = view.state.tr.setMeta(PLUGIN_KEY, { positions });
64817
+ view.dispatch(tr);
64818
+ };
64819
+ let frame = null;
64820
+ let lastCompute = 0;
64821
+ const MIN_SCROLL_INTERVAL = 150;
64822
+ const scheduleFrame = () => {
64823
+ if (frame !== null) return;
64824
+ frame = requestAnimationFrame(() => {
64825
+ frame = null;
64826
+ const now = performance.now();
64827
+ if (now - lastCompute >= MIN_SCROLL_INTERVAL) {
64828
+ lastCompute = now;
64829
+ computeAndDispatch();
64830
+ } else {
64831
+ scheduleFrame();
64832
+ }
64833
+ });
64834
+ };
64835
+ scrollContainer.addEventListener("scroll", scheduleFrame, { passive: true });
64836
+ computeAndDispatch();
64837
+ return {
64838
+ update(_view, prevState) {
64839
+ if (view.state.doc.content.size !== prevState.doc.content.size) {
64840
+ scheduleFrame();
64841
+ }
64842
+ },
64843
+ destroy: () => {
64844
+ if (frame !== null) {
64845
+ cancelAnimationFrame(frame);
64846
+ }
64847
+ scrollContainer.removeEventListener("scroll", scheduleFrame);
64306
64848
  }
64307
64849
  };
64308
- return { call, cancel };
64309
64850
  }
64310
64851
 
64311
- // src/placeholder/placeholder.ts
64312
- var DEFAULT_DATA_ATTRIBUTE = "placeholder";
64313
- function preparePlaceholderAttribute(attr) {
64314
- return attr.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9-]/g, "").replace(/^[0-9-]+/, "").replace(/^-+/, "").toLowerCase();
64852
+ // src/placeholder/plugins/PlaceholderPlugin.ts
64853
+ function createPlaceholderPlugin({ editor, options }) {
64854
+ const dataAttribute = options.dataAttribute ? `data-${preparePlaceholderAttribute(options.dataAttribute)}` : `data-${DEFAULT_DATA_ATTRIBUTE}`;
64855
+ return new Plugin({
64856
+ key: PLUGIN_KEY,
64857
+ state: viewportPluginState,
64858
+ view: createViewportPluginView,
64859
+ props: {
64860
+ decorations: ({ doc, selection }) => buildPlaceholderDecorations({ editor, options, dataAttribute, doc, selection })
64861
+ }
64862
+ });
64315
64863
  }
64316
- var PLUGIN_KEY = new PluginKey("tiptap__placeholder");
64864
+
64865
+ // src/placeholder/placeholder.ts
64317
64866
  var Placeholder = Extension.create({
64318
64867
  name: "placeholder",
64319
64868
  addOptions() {
@@ -64328,134 +64877,16 @@ ${indentedChild}`;
64328
64877
  };
64329
64878
  },
64330
64879
  addProseMirrorPlugins() {
64331
- const dataAttribute = this.options.dataAttribute ? `data-${preparePlaceholderAttribute(this.options.dataAttribute)}` : `data-${DEFAULT_DATA_ATTRIBUTE}`;
64332
- return [
64333
- new Plugin({
64334
- state: {
64335
- init() {
64336
- return {
64337
- // null means "no viewport info yet" — decoration callback falls
64338
- // back to full document scan until the scroll handler fires.
64339
- topPos: null,
64340
- bottomPos: null
64341
- };
64342
- },
64343
- apply(tr, prev) {
64344
- const meta = tr.getMeta(PLUGIN_KEY);
64345
- if (meta == null ? void 0 : meta.positions) {
64346
- return {
64347
- topPos: meta.positions.top,
64348
- bottomPos: meta.positions.bottom
64349
- };
64350
- }
64351
- if (!tr.docChanged) {
64352
- return prev;
64353
- }
64354
- return {
64355
- topPos: prev.topPos !== null ? tr.mapping.map(prev.topPos) : null,
64356
- bottomPos: prev.bottomPos !== null ? tr.mapping.map(prev.bottomPos) : null
64357
- };
64358
- }
64359
- },
64360
- key: PLUGIN_KEY,
64361
- view(view) {
64362
- const scrollContainer = findScrollParent(view.dom);
64363
- const computeAndDispatch = () => {
64364
- const positions = getViewportBoundaryPositions({
64365
- view,
64366
- doc: view.state.doc,
64367
- scrollContainer
64368
- });
64369
- const prev = PLUGIN_KEY.getState(view.state);
64370
- if (prev.topPos === positions.top && prev.bottomPos === positions.bottom) {
64371
- return;
64372
- }
64373
- const tr = view.state.tr.setMeta(PLUGIN_KEY, { positions }).setMeta("tiptap__viewportUpdate", true);
64374
- view.dispatch(tr);
64375
- };
64376
- const { call: throttledUpdate, cancel: cancelThrottle } = throttle(computeAndDispatch, 250);
64377
- const scrollParent = scrollContainer;
64378
- scrollParent.addEventListener("scroll", throttledUpdate, { passive: true });
64379
- computeAndDispatch();
64380
- return {
64381
- update(_, prevState) {
64382
- if (view.state.doc.content.size !== prevState.doc.content.size) {
64383
- computeAndDispatch();
64384
- }
64385
- },
64386
- destroy: () => {
64387
- cancelThrottle();
64388
- scrollParent.removeEventListener("scroll", throttledUpdate);
64389
- }
64390
- };
64391
- },
64392
- props: {
64393
- decorations: ({ doc, selection }) => {
64394
- var _a, _b;
64395
- const active = this.editor.isEditable || !this.options.showOnlyWhenEditable;
64396
- if (!active) {
64397
- return null;
64398
- }
64399
- const { anchor } = selection;
64400
- const decorations = [];
64401
- const isEmptyDoc = this.editor.isEmpty;
64402
- const useResolvedPath = this.options.showOnlyCurrent && !this.options.includeChildren;
64403
- if (useResolvedPath) {
64404
- const resolved = doc.resolve(anchor);
64405
- if (resolved.depth > 0) {
64406
- const node = resolved.node(1);
64407
- const nodeStart = resolved.before(1);
64408
- if (node.type.isTextblock && isNodeEmpty(node)) {
64409
- const hasAnchor = anchor >= nodeStart && anchor <= nodeStart + node.nodeSize;
64410
- const decoration = createPlaceholderDecoration({
64411
- node,
64412
- dataAttribute,
64413
- hasAnchor,
64414
- placeholder: this.options.placeholder,
64415
- classes: {
64416
- emptyEditor: this.options.emptyEditorClass,
64417
- emptyNode: this.options.emptyNodeClass
64418
- },
64419
- editor: this.editor,
64420
- isEmptyDoc,
64421
- pos: resolved.before(1)
64422
- });
64423
- decorations.push(decoration);
64424
- }
64425
- }
64426
- } else {
64427
- const pluginState = PLUGIN_KEY.getState(this.editor.state);
64428
- const from = (_a = pluginState.topPos) != null ? _a : 0;
64429
- const to = (_b = pluginState.bottomPos) != null ? _b : doc.content.size;
64430
- doc.nodesBetween(from, to, (node, pos) => {
64431
- const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
64432
- const isEmpty = !node.isLeaf && isNodeEmpty(node);
64433
- if (!node.type.isTextblock) {
64434
- return this.options.includeChildren;
64435
- }
64436
- if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
64437
- const decoration = createPlaceholderDecoration({
64438
- classes: { emptyEditor: this.options.emptyEditorClass, emptyNode: this.options.emptyNodeClass },
64439
- editor: this.editor,
64440
- isEmptyDoc,
64441
- dataAttribute,
64442
- hasAnchor,
64443
- placeholder: this.options.placeholder,
64444
- node,
64445
- pos
64446
- });
64447
- decorations.push(decoration);
64448
- }
64449
- return this.options.includeChildren;
64450
- });
64451
- }
64452
- return DecorationSet.create(doc, decorations);
64453
- }
64454
- }
64455
- })
64456
- ];
64880
+ return [createPlaceholderPlugin({ editor: this.editor, options: this.options })];
64457
64881
  }
64458
64882
  });
64883
+ var selectionStyle = `.ProseMirror:not(.ProseMirror-focused) *::selection {
64884
+ background: transparent;
64885
+ }
64886
+
64887
+ .ProseMirror:not(.ProseMirror-focused) *::-moz-selection {
64888
+ background: transparent;
64889
+ }`;
64459
64890
  Extension.create({
64460
64891
  name: "selection",
64461
64892
  addOptions() {
@@ -64465,6 +64896,9 @@ ${indentedChild}`;
64465
64896
  },
64466
64897
  addProseMirrorPlugins() {
64467
64898
  const { editor, options } = this;
64899
+ if (editor.options.injectCSS && typeof document !== "undefined") {
64900
+ createStyleTag(selectionStyle, editor.options.injectNonce, "selection");
64901
+ }
64468
64902
  return [
64469
64903
  new Plugin({
64470
64904
  key: new PluginKey("selection"),
@@ -64485,7 +64919,10 @@ ${indentedChild}`;
64485
64919
  }
64486
64920
  });
64487
64921
  var skipTrailingNodeMeta = "skipTrailingNode";
64488
- function nodeEqualsType({ types, node }) {
64922
+ function nodeEqualsType({
64923
+ types,
64924
+ node
64925
+ }) {
64489
64926
  return node && Array.isArray(types) && types.includes(node.type) || (node == null ? void 0 : node.type) === types;
64490
64927
  }
64491
64928
  Extension.create({
@@ -64670,7 +65107,7 @@ ${indentedChild}`;
64670
65107
  rel: 'noopener noreferrer',
64671
65108
  target: null,
64672
65109
  // Adding `class` here is a workaround to render two mentions without a whitespace as display names
64673
- // This attribute can be removed when the below issue is resolved
65110
+ // For more details on this behavior, refer to the issue below:
64674
65111
  // https://github.com/ni/nimble/issues/1707
64675
65112
  class: ''
64676
65113
  },
@@ -71144,6 +71581,12 @@ ${indentedChild}`;
71144
71581
  canLoadChildren: 'can-load-children',
71145
71582
  loadingChildren: 'loading-children'
71146
71583
  };
71584
+ /**
71585
+ * The possible pin locations for a table column.
71586
+ */
71587
+ const TableColumnPinLocation = {
71588
+ left: 'left'
71589
+ };
71147
71590
  /**
71148
71591
  * The possible directions a table column can be sorted in.
71149
71592
  */
@@ -71484,6 +71927,9 @@ ${indentedChild}`;
71484
71927
  __decorate([
71485
71928
  observable
71486
71929
  ], ColumnInternals.prototype, "currentSortDirection", void 0);
71930
+ __decorate([
71931
+ observable
71932
+ ], ColumnInternals.prototype, "pinLocation", void 0);
71487
71933
  function isColumnInternalsProperty(changedProperty, ...args) {
71488
71934
  for (const arg of args) {
71489
71935
  if (changedProperty === arg) {
@@ -71557,6 +72003,7 @@ ${indentedChild}`;
71557
72003
  this.idFieldNameNotConfigured = false;
71558
72004
  this.invalidColumnConfiguration = false;
71559
72005
  this.invalidParentIdConfiguration = false;
72006
+ this.invalidPinnedColumnConfiguration = false;
71560
72007
  this.recordIds = new Set();
71561
72008
  }
71562
72009
  getValidity() {
@@ -71570,7 +72017,8 @@ ${indentedChild}`;
71570
72017
  duplicateGroupIndex: this.duplicateGroupIndex,
71571
72018
  idFieldNameNotConfigured: this.idFieldNameNotConfigured,
71572
72019
  invalidColumnConfiguration: this.invalidColumnConfiguration,
71573
- invalidParentIdConfiguration: this.invalidParentIdConfiguration
72020
+ invalidParentIdConfiguration: this.invalidParentIdConfiguration,
72021
+ invalidPinnedColumnConfiguration: this.invalidPinnedColumnConfiguration
71574
72022
  };
71575
72023
  }
71576
72024
  isValid() {
@@ -71653,6 +72101,12 @@ ${indentedChild}`;
71653
72101
  this.invalidColumnConfiguration = columns.some(x => !x.columnInternals.validator.isColumnValid);
71654
72102
  return !this.invalidColumnConfiguration;
71655
72103
  }
72104
+ validatePinnedColumnConfigurations(columns) {
72105
+ this.invalidPinnedColumnConfiguration = columns.some(x => x.columnInternals.pinLocation === TableColumnPinLocation.left
72106
+ && (x.columnInternals.pixelWidth === undefined
72107
+ || !x.columnInternals.resizingDisabled));
72108
+ return !this.invalidPinnedColumnConfiguration;
72109
+ }
71656
72110
  getPresentRecordIds(requestedRecordIds) {
71657
72111
  return requestedRecordIds.filter(id => this.recordIds.has(id));
71658
72112
  }
@@ -71712,12 +72166,7 @@ focus outline in that case.
71712
72166
  .header-row-container {
71713
72167
  position: sticky;
71714
72168
  top: 0;
71715
- }
71716
-
71717
- .header-row {
71718
72169
  display: flex;
71719
- background: ${applicationBackgroundColor};
71720
- position: relative;
71721
72170
  width: fit-content;
71722
72171
  min-width: max(
71723
72172
  100%,
@@ -71726,8 +72175,16 @@ focus outline in that case.
71726
72175
  var(--ni-private-table-header-container-margin-right)
71727
72176
  )
71728
72177
  );
72178
+ }
72179
+
72180
+ .header-row {
72181
+ display: flex;
72182
+ background: ${applicationBackgroundColor};
72183
+ position: relative;
72184
+ width: fit-content;
71729
72185
  left: var(--ni-private-table-scroll-x);
71730
72186
  align-items: center;
72187
+ flex: 1;
71731
72188
  }
71732
72189
 
71733
72190
  .header-row-action-container {
@@ -71779,6 +72236,17 @@ focus outline in that case.
71779
72236
  overflow: hidden;
71780
72237
  }
71781
72238
 
72239
+ .pinned-columns-header-container {
72240
+ display: grid;
72241
+ grid-template-columns: var(--ni-private-table-pinned-columns-row-grid-columns);
72242
+ position: sticky;
72243
+ left: 0;
72244
+ align-self: stretch;
72245
+ background: ${applicationBackgroundColor};
72246
+ z-index: ${ZIndexLevels.zIndex1};
72247
+ box-shadow: inset -2px 0 0 0 ${tableRowBorderColor};
72248
+ }
72249
+
71782
72250
  .column-divider {
71783
72251
  border-left: var(--ni-private-column-divider-width) solid
71784
72252
  ${popupBorderColor};
@@ -71879,6 +72347,10 @@ focus outline in that case.
71879
72347
  ${accessiblyHidden}
71880
72348
  }
71881
72349
  `.withBehaviors(themeBehavior(Theme.color, css `
72350
+ .pinned-columns-header-container {
72351
+ box-shadow: inset -2px 0 0 0 ${hexToRgbaCssColor(White, 0.1)};
72352
+ }
72353
+
71882
72354
  .table-row-container::before {
71883
72355
  content: '';
71884
72356
  width: 100%;
@@ -72060,7 +72532,7 @@ focus outline in that case.
72060
72532
  position: absolute;
72061
72533
  }
72062
72534
 
72063
- :host([selectable]:not([selected])[allow-hover]:hover)::before {
72535
+ :host([selectable][allow-hover]:hover)::before {
72064
72536
  background-color: ${fillHoverColor};
72065
72537
  }
72066
72538
 
@@ -72133,6 +72605,46 @@ focus outline in that case.
72133
72605
  width: ${mediumPadding};
72134
72606
  }
72135
72607
 
72608
+ .pinned-cell-container {
72609
+ display: grid;
72610
+ grid-template-columns: var(--ni-private-table-pinned-columns-row-grid-columns);
72611
+ position: sticky;
72612
+ left: 0;
72613
+ background: ${applicationBackgroundColor};
72614
+ z-index: ${ZIndexLevels.zIndex1};
72615
+ box-shadow: inset -2px 0 0 0 ${tableRowBorderColor};
72616
+ }
72617
+
72618
+ :host([selectable][allow-hover]:hover) .pinned-cell-container {
72619
+ background: linear-gradient(${fillHoverColor}, ${fillHoverColor}),
72620
+ ${applicationBackgroundColor};
72621
+ }
72622
+
72623
+ :host([selected]) .pinned-cell-container {
72624
+ background: linear-gradient(${fillSelectedColor}, ${fillSelectedColor}),
72625
+ ${applicationBackgroundColor};
72626
+ }
72627
+
72628
+ :host([selected][allow-hover]:hover) .pinned-cell-container {
72629
+ background: linear-gradient(
72630
+ ${fillHoverSelectedColor},
72631
+ ${fillHoverSelectedColor}
72632
+ ),
72633
+ ${applicationBackgroundColor};
72634
+ }
72635
+
72636
+ :host(${focusVisible}) .pinned-cell-container {
72637
+ box-shadow:
72638
+ inset calc(2 * ${borderWidth}) 0 0 ${borderHoverColor},
72639
+ inset 0 calc(2 * ${borderWidth}) 0 ${borderHoverColor},
72640
+ inset 0 calc(-2 * ${borderWidth}) 0 ${borderHoverColor},
72641
+ inset -2px 0 0 0 ${tableRowBorderColor};
72642
+ }
72643
+ ${'' /* Pushing the pinned-cell-container to a higher z-index for breakpoint menu behavior (not required by table directly) */}
72644
+ :host([menu-open]) .pinned-cell-container {
72645
+ z-index: ${ZIndexLevels.zIndex1000};
72646
+ }
72647
+
72136
72648
  .cell-container {
72137
72649
  display: grid;
72138
72650
  width: 100%;
@@ -72208,6 +72720,42 @@ focus outline in that case.
72208
72720
  :host([selected][allow-hover]:hover)::before {
72209
72721
  background-color: ${hexToRgbaCssColor(White, 0.2)};
72210
72722
  }
72723
+
72724
+ .pinned-cell-container {
72725
+ box-shadow: inset -2px 0 0 0 ${hexToRgbaCssColor(White, 0.1)};
72726
+ }
72727
+
72728
+ :host([selectable][allow-hover]:hover) .pinned-cell-container {
72729
+ background: linear-gradient(
72730
+ ${hexToRgbaCssColor(White, 0.05)},
72731
+ ${hexToRgbaCssColor(White, 0.05)}
72732
+ ),
72733
+ ${applicationBackgroundColor};
72734
+ }
72735
+
72736
+ :host([selected]) .pinned-cell-container {
72737
+ background: linear-gradient(
72738
+ ${hexToRgbaCssColor(White, 0.25)},
72739
+ ${hexToRgbaCssColor(White, 0.25)}
72740
+ ),
72741
+ ${applicationBackgroundColor};
72742
+ }
72743
+
72744
+ :host([selected][allow-hover]:hover) .pinned-cell-container {
72745
+ background: linear-gradient(
72746
+ ${hexToRgbaCssColor(White, 0.2)},
72747
+ ${hexToRgbaCssColor(White, 0.2)}
72748
+ ),
72749
+ ${applicationBackgroundColor};
72750
+ }
72751
+
72752
+ :host(${focusVisible}) .pinned-cell-container {
72753
+ box-shadow:
72754
+ inset calc(2 * ${borderWidth}) 0 0 ${borderHoverColor},
72755
+ inset 0 calc(2 * ${borderWidth}) 0 ${borderHoverColor},
72756
+ inset 0 calc(-2 * ${borderWidth}) 0 ${borderHoverColor},
72757
+ inset -2px 0 0 0 ${hexToRgbaCssColor(White, 0.1)};
72758
+ }
72211
72759
  `));
72212
72760
 
72213
72761
  const styles$i = css `
@@ -72358,6 +72906,37 @@ focus outline in that case.
72358
72906
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleTableCell());
72359
72907
  const tableCellTag = 'nimble-table-cell';
72360
72908
 
72909
+ const rowCellTemplate = html `
72910
+ <${tableCellTag}
72911
+ class="cell"
72912
+ :cellState="${(_, c) => c.parent.cellStates[c.index]}"
72913
+ :cellViewTemplate="${x => x.columnInternals.cellViewTemplate}"
72914
+ :column="${x => x}"
72915
+ column-id="${x => x.columnId}"
72916
+ :recordId="${(_, c) => c.parent.recordId}"
72917
+ ?has-action-menu="${x => !!x.actionMenuSlot}"
72918
+ action-menu-label="${x => x.actionMenuLabel}"
72919
+ @cell-action-menu-beforetoggle="${(x, c) => c.parent.onCellActionMenuBeforeToggle(c.event, x)}"
72920
+ @cell-action-menu-toggle="${(x, c) => c.parent.onCellActionMenuToggle(c.event, x)}"
72921
+ @cell-view-slots-request="${(x, c) => c.parent.onCellViewSlotsRequest(x, c.event)}"
72922
+ :nestingLevel="${(_, c) => c.parent.cellIndentLevels[c.index]}"
72923
+ >
72924
+
72925
+ ${when((x, c) => (c.parent.currentActionMenuColumn === x) && x.actionMenuSlot, html `
72926
+ <slot
72927
+ name="${x => `row-action-menu-${x.actionMenuSlot}`}"
72928
+ slot="cellActionMenu"
72929
+ ></slot>
72930
+ `)}
72931
+
72932
+ ${repeat(x => x.columnInternals.slotNames, html `
72933
+ <slot
72934
+ name="${(x, c) => uniquifySlotNameForColumn(c.parent, x)}"
72935
+ slot="${(x, c) => uniquifySlotNameForColumn(c.parent, x)}"
72936
+ ></slot>
72937
+ `)}
72938
+ </${tableCellTag}>
72939
+ `;
72361
72940
  const template$j = html `
72362
72941
  <template
72363
72942
  role="row"
@@ -72365,6 +72944,14 @@ focus outline in that case.
72365
72944
  aria-expanded=${x => x.expanded}
72366
72945
  style="--ni-private-table-row-indent-level: ${x => x.nestingLevel};"
72367
72946
  >
72947
+ <span class="pinned-cell-container">
72948
+ ${repeat(x => x.columns, html `
72949
+ ${when(x => !x.columnHidden && x.columnInternals.pinLocation === TableColumnPinLocation.left, html `
72950
+ ${rowCellTemplate}
72951
+ `)}
72952
+ `, { recycle: false, positioning: true })}
72953
+ </span>
72954
+
72368
72955
  ${when(x => !x.rowOperationGridCellHidden, html `
72369
72956
  <span role="gridcell" class="row-operations-container">
72370
72957
  ${when(x => x.showSelectionCheckbox, html `
@@ -72382,7 +72969,7 @@ focus outline in that case.
72382
72969
  `)}
72383
72970
  </span>
72384
72971
  `)}
72385
- <span class="row-front-spacer ${x => (x.isTopLevelParentRow || !x.reserveCollapseSpace ? 'reduced-size-spacer' : '')}"></span>
72972
+ <span class="row-front-spacer ${x => (x.isTopLevelParentRow || !x.reserveCollapseSpace ? 'reduced-size-spacer' : '')} ${x => (x.showSelectionCheckbox ? 'selectable' : '')}"></span>
72386
72973
  ${when(x => x.isParentRow, html `
72387
72974
  ${when(x => x.loading, html `
72388
72975
  <span class="spinner-container">
@@ -72413,36 +73000,8 @@ focus outline in that case.
72413
73000
  class="cell-container ${x => (x.isNestedParent ? 'nested-parent' : '')}"
72414
73001
  >
72415
73002
  ${repeat(x => x.columns, html `
72416
- ${when(x => !x.columnHidden, html `
72417
- <${tableCellTag}
72418
- class="cell"
72419
- :cellState="${(_, c) => c.parent.cellStates[c.index]}"
72420
- :cellViewTemplate="${x => x.columnInternals.cellViewTemplate}"
72421
- :column="${x => x}"
72422
- column-id="${x => x.columnId}"
72423
- :recordId="${(_, c) => c.parent.recordId}"
72424
- ?has-action-menu="${x => !!x.actionMenuSlot}"
72425
- action-menu-label="${x => x.actionMenuLabel}"
72426
- @cell-action-menu-beforetoggle="${(x, c) => c.parent.onCellActionMenuBeforeToggle(c.event, x)}"
72427
- @cell-action-menu-toggle="${(x, c) => c.parent.onCellActionMenuToggle(c.event, x)}"
72428
- @cell-view-slots-request="${(x, c) => c.parent.onCellViewSlotsRequest(x, c.event)}"
72429
- :nestingLevel="${(_, c) => c.parent.cellIndentLevels[c.index]}"
72430
- >
72431
-
72432
- ${when((x, c) => (c.parent.currentActionMenuColumn === x) && x.actionMenuSlot, html `
72433
- <slot
72434
- name="${x => `row-action-menu-${x.actionMenuSlot}`}"
72435
- slot="cellActionMenu"
72436
- ></slot>
72437
- `)}
72438
-
72439
- ${repeat(x => x.columnInternals.slotNames, html `
72440
- <slot
72441
- name="${(x, c) => uniquifySlotNameForColumn(c.parent, x)}"
72442
- slot="${(x, c) => uniquifySlotNameForColumn(c.parent, x)}"
72443
- ></slot>
72444
- `)}
72445
- </${tableCellTag}>
73003
+ ${when(x => !x.columnHidden && x.columnInternals.pinLocation !== TableColumnPinLocation.left, html `
73004
+ ${rowCellTemplate}
72446
73005
  `)}
72447
73006
  `, { recycle: false, positioning: true })}
72448
73007
  </span>
@@ -72625,8 +73184,9 @@ focus outline in that case.
72625
73184
  this.updateCellIndentLevels();
72626
73185
  }
72627
73186
  updateCellIndentLevels() {
73187
+ const firstNonPinnedIndex = this.columns.findIndex(col => col.columnInternals.pinLocation !== TableColumnPinLocation.left);
72628
73188
  this.cellIndentLevels = this.columns.map((_, i) => {
72629
- return i === 0 ? this.nestingLevel : 0;
73189
+ return i === firstNonPinnedIndex ? this.nestingLevel : 0;
72630
73190
  });
72631
73191
  }
72632
73192
  removeColumnObservers() {
@@ -72768,6 +73328,7 @@ focus outline in that case.
72768
73328
  height: calc(${controlHeight} + 2 * ${borderWidth});
72769
73329
  border-top: calc(2 * ${borderWidth}) solid ${applicationBackgroundColor};
72770
73330
  grid-template-columns:
73331
+ calc(var(--ni-private-table-group-row-pinned-column-offset))
72771
73332
  calc(
72772
73333
  ${controlHeight} *
72773
73334
  (var(--ni-private-table-group-row-indent-level) + 1)
@@ -72777,6 +73338,7 @@ focus outline in that case.
72777
73338
 
72778
73339
  :host([selectable]) {
72779
73340
  grid-template-columns:
73341
+ calc(var(--ni-private-table-group-row-pinned-column-offset))
72780
73342
  ${controlHeight}
72781
73343
  calc(
72782
73344
  ${controlHeight} *
@@ -72803,6 +73365,37 @@ focus outline in that case.
72803
73365
  outline-offset: calc(-2 * ${borderWidth});
72804
73366
  }
72805
73367
 
73368
+ :host([has-pinned-columns]) .pinned-column-spacer {
73369
+ display: block;
73370
+ height: 100%;
73371
+ position: sticky;
73372
+ left: 0;
73373
+ background: ${tableRowBorderColor};
73374
+ z-index: ${ZIndexLevels.zIndex1};
73375
+ }
73376
+
73377
+ :host([allow-hover][has-pinned-columns]:hover) .pinned-column-spacer {
73378
+ background: linear-gradient(${fillHoverColor}, ${fillHoverColor}),
73379
+ ${tableRowBorderColor};
73380
+ }
73381
+
73382
+ :host([has-pinned-columns]${focusVisible}) .pinned-column-spacer {
73383
+ box-shadow: inset 2px -2px 0 ${borderHoverColor};
73384
+ }
73385
+
73386
+ .checkbox-container {
73387
+ display: flex;
73388
+ }
73389
+
73390
+ :host([has-pinned-columns]) .checkbox-container {
73391
+ position: relative;
73392
+ }
73393
+
73394
+ :host([allow-hover][has-pinned-columns]:hover) .checkbox-container {
73395
+ background: linear-gradient(${fillHoverColor}, ${fillHoverColor}),
73396
+ ${tableRowBorderColor};
73397
+ }
73398
+
72806
73399
  .expand-collapse-button {
72807
73400
  margin-left: calc(
72808
73401
  ${mediumPadding} + ${standardPadding} * 2 *
@@ -72828,10 +73421,6 @@ focus outline in that case.
72828
73421
  ${userSelectNone}
72829
73422
  }
72830
73423
 
72831
- .checkbox-container {
72832
- display: flex;
72833
- }
72834
-
72835
73424
  .selection-checkbox {
72836
73425
  margin-left: ${standardPadding};
72837
73426
  }
@@ -72843,10 +73432,66 @@ focus outline in that case.
72843
73432
  :host([allow-hover]:hover)::before {
72844
73433
  background-color: ${hexToRgbaCssColor(White, 0.05)};
72845
73434
  }
73435
+
73436
+ :host([has-pinned-columns]) .pinned-column-spacer {
73437
+ background: linear-gradient(
73438
+ ${hexToRgbaCssColor(White, 0.1)},
73439
+ ${hexToRgbaCssColor(White, 0.1)}
73440
+ ),
73441
+ ${tableRowBorderColor};
73442
+ }
73443
+
73444
+ :host([allow-hover][has-pinned-columns]:hover) .pinned-column-spacer {
73445
+ background: linear-gradient(
73446
+ ${hexToRgbaCssColor(White, 0.05)},
73447
+ ${hexToRgbaCssColor(White, 0.05)}
73448
+ ),
73449
+ linear-gradient(
73450
+ ${hexToRgbaCssColor(White, 0.1)},
73451
+ ${hexToRgbaCssColor(White, 0.1)}
73452
+ ),
73453
+ ${tableRowBorderColor};
73454
+ }
73455
+
73456
+ :host([has-pinned-columns]) .checkbox-container {
73457
+ background: linear-gradient(
73458
+ ${hexToRgbaCssColor(White, 0.1)},
73459
+ ${hexToRgbaCssColor(White, 0.1)}
73460
+ ),
73461
+ ${tableRowBorderColor};
73462
+ }
73463
+
73464
+ :host([allow-hover][has-pinned-columns]:hover) .checkbox-container {
73465
+ background: linear-gradient(
73466
+ ${hexToRgbaCssColor(White, 0.05)},
73467
+ ${hexToRgbaCssColor(White, 0.05)}
73468
+ ),
73469
+ linear-gradient(
73470
+ ${hexToRgbaCssColor(White, 0.1)},
73471
+ ${hexToRgbaCssColor(White, 0.1)}
73472
+ ),
73473
+ ${tableRowBorderColor};
73474
+ }
72846
73475
  `), themeBehavior(Theme.dark, css `
72847
73476
  :host([allow-hover]:hover)::before {
72848
73477
  background-color: ${hexToRgbaCssColor(White, 0.1)};
72849
73478
  }
73479
+
73480
+ :host([allow-hover][has-pinned-columns]:hover) .pinned-column-spacer {
73481
+ background: linear-gradient(
73482
+ ${hexToRgbaCssColor(White, 0.1)},
73483
+ ${hexToRgbaCssColor(White, 0.1)}
73484
+ ),
73485
+ ${tableRowBorderColor};
73486
+ }
73487
+
73488
+ :host([allow-hover][has-pinned-columns]:hover) .checkbox-container {
73489
+ background: linear-gradient(
73490
+ ${hexToRgbaCssColor(White, 0.1)},
73491
+ ${hexToRgbaCssColor(White, 0.1)}
73492
+ ),
73493
+ ${tableRowBorderColor};
73494
+ }
72850
73495
  `));
72851
73496
 
72852
73497
  const template$i = html `
@@ -72854,8 +73499,13 @@ focus outline in that case.
72854
73499
  role="row"
72855
73500
  @click=${x => x.onGroupExpandToggle()}
72856
73501
  aria-expanded=${x => x.expanded}
72857
- style="--ni-private-table-group-row-indent-level: ${x => x.nestingLevel};"
73502
+ style="
73503
+ --ni-private-table-group-row-indent-level: ${x => x.nestingLevel};
73504
+ --ni-private-table-group-row-pinned-column-offset: ${x => x.pinnedColumnOffset}px;
73505
+ "
72858
73506
  >
73507
+ <span class="pinned-column-spacer"></span>
73508
+
72859
73509
  ${when(x => x.selectable, html `
72860
73510
  <span role="gridcell" class="checkbox-container">
72861
73511
  <${checkboxTag}
@@ -72898,6 +73548,11 @@ focus outline in that case.
72898
73548
  constructor() {
72899
73549
  super(...arguments);
72900
73550
  this.nestingLevel = 0;
73551
+ this.pinnedColumnOffset = 0;
73552
+ /**
73553
+ * @internal
73554
+ */
73555
+ this.hasPinnedColumns = false;
72901
73556
  this.expanded = false;
72902
73557
  this.selectable = false;
72903
73558
  this.selectionState = TableRowSelectionState.notSelected;
@@ -72955,6 +73610,9 @@ focus outline in that case.
72955
73610
  cells: []
72956
73611
  };
72957
73612
  }
73613
+ pinnedColumnOffsetChanged() {
73614
+ this.hasPinnedColumns = this.pinnedColumnOffset > 0;
73615
+ }
72958
73616
  selectionStateChanged() {
72959
73617
  this.setSelectionCheckboxState();
72960
73618
  }
@@ -72977,6 +73635,12 @@ focus outline in that case.
72977
73635
  __decorate([
72978
73636
  observable
72979
73637
  ], TableGroupRow.prototype, "nestingLevel", void 0);
73638
+ __decorate([
73639
+ observable
73640
+ ], TableGroupRow.prototype, "pinnedColumnOffset", void 0);
73641
+ __decorate([
73642
+ attr({ attribute: 'has-pinned-columns', mode: 'boolean' })
73643
+ ], TableGroupRow.prototype, "hasPinnedColumns", void 0);
72980
73644
  __decorate([
72981
73645
  observable
72982
73646
  ], TableGroupRow.prototype, "resolvedRowIndex", void 0);
@@ -73012,6 +73676,21 @@ focus outline in that case.
73012
73676
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleTableGroupRow());
73013
73677
  const tableGroupRowTag = 'nimble-table-group-row';
73014
73678
 
73679
+ const tableHeaderTemplate = html `
73680
+ <${tableHeaderTag}
73681
+ class="header"
73682
+ ${'' /* tabindex managed dynamically by KeyboardNavigationManager (if column sorting not disabled) */}
73683
+ sort-direction="${x => (typeof x.columnInternals.currentSortIndex === 'number' ? x.columnInternals.currentSortDirection : TableColumnSortDirection.none)}"
73684
+ ?first-sorted-column="${(x, c) => x === c.parent.firstSortedColumn}"
73685
+ ?indicators-hidden="${x => x.columnInternals.hideHeaderIndicators}"
73686
+ @keydown="${(x, c) => c.parent.onHeaderKeyDown(x, c.event)}"
73687
+ @click="${(x, c) => c.parent.toggleColumnSort(x, c.event.shiftKey)}"
73688
+ :alignment="${x => x.columnInternals.headerAlignment}"
73689
+ :isGrouped="${x => (typeof x.columnInternals.groupIndex === 'number' && !x.columnInternals.groupingDisabled) || undefined}"
73690
+ >
73691
+ <slot name="${x => x.slot}"></slot>
73692
+ </${tableHeaderTag}>
73693
+ `;
73015
73694
  const template$h = html `
73016
73695
  <template
73017
73696
  role="treegrid"
@@ -73029,8 +73708,14 @@ focus outline in that case.
73029
73708
  --ni-private-table-row-grid-columns: ${x => (x.rowGridColumns ? x.rowGridColumns : '')};
73030
73709
  --ni-private-table-cursor-override: ${x => (x.layoutManager.isColumnBeingSized ? 'col-resize' : 'default')};
73031
73710
  --ni-private-table-scrollable-min-width: ${x => x.tableScrollableMinWidth}px;
73711
+ --ni-private-table-pinned-columns-row-grid-columns: ${x => x.pinnedColumnsGridTemplateColumns};
73032
73712
  ">
73033
73713
  <div role="rowgroup" class="header-row-container">
73714
+ <div class="pinned-columns-header-container">
73715
+ ${repeat(x => x.pinnedColumns, html `
73716
+ ${tableHeaderTemplate}
73717
+ `, { positioning: true })}
73718
+ </div>
73034
73719
  <div class="header-row" role="row">
73035
73720
  <span role="${x => (x.showRowOperationColumn ? 'columnheader' : '')}" class="header-row-action-container" ${ref('headerRowActionContainer')}>
73036
73721
  ${when(x => x.showRowOperationColumn, html `
@@ -73083,19 +73768,7 @@ focus outline in that case.
73083
73768
  @pointerdown="${(_, c) => c.parent.onLeftDividerPointerDown(c.event, c.index)}">
73084
73769
  </div>
73085
73770
  `)}
73086
- <${tableHeaderTag}
73087
- class="header"
73088
- ${'' /* tabindex managed dynamically by KeyboardNavigationManager (if column sorting not disabled) */}
73089
- sort-direction="${x => (typeof x.columnInternals.currentSortIndex === 'number' ? x.columnInternals.currentSortDirection : TableColumnSortDirection.none)}"
73090
- ?first-sorted-column="${(x, c) => x === c.parent.firstSortedColumn}"
73091
- ?indicators-hidden="${x => x.columnInternals.hideHeaderIndicators}"
73092
- @keydown="${(x, c) => c.parent.onHeaderKeyDown(x, c.event)}"
73093
- @click="${(x, c) => c.parent.toggleColumnSort(x, c.event.shiftKey)}"
73094
- :alignment="${x => x.columnInternals.headerAlignment}"
73095
- :isGrouped=${x => (typeof x.columnInternals.groupIndex === 'number' && !x.columnInternals.groupingDisabled)}
73096
- >
73097
- <slot name="${x => x.slot}"></slot>
73098
- </${tableHeaderTag}>
73771
+ ${tableHeaderTemplate}
73099
73772
  ${when((_, c) => c.index < c.length - 1, html `
73100
73773
  <div
73101
73774
  class="
@@ -73128,6 +73801,7 @@ focus outline in that case.
73128
73801
  :groupRowValue="${(x, c) => c.parent.tableData[x.index]?.groupRowValue}"
73129
73802
  ?expanded="${(x, c) => c.parent.tableData[x.index]?.isExpanded}"
73130
73803
  :nestingLevel="${(x, c) => c.parent.tableData[x.index]?.nestingLevel}"
73804
+ :pinnedColumnOffset="${(_, c) => c.parent.pinnedColumnOffset}"
73131
73805
  :immediateChildCount="${(x, c) => c.parent.tableData[x.index]?.immediateChildCount}"
73132
73806
  :groupColumn="${(x, c) => c.parent.tableData[x.index]?.groupColumn}"
73133
73807
  ?selectable="${(_, c) => c.parent.selectionMode === TableRowSelectionMode.multiple}"
@@ -73387,6 +74061,11 @@ focus outline in that case.
73387
74061
  return horizontal ? el.scrollLeft * (isRtl && -1 || 1) : el.scrollTop;
73388
74062
  });
73389
74063
  const measureElement = (element, entry, instance) => {
74064
+ if (instance.options.useCachedMeasurements) {
74065
+ const index = instance.indexFromElement(element);
74066
+ const key = instance.options.getItemKey(index);
74067
+ return instance.itemSizeCache.get(key) ?? instance.options.estimateSize(index);
74068
+ }
73390
74069
  if (entry == null ? void 0 : entry.borderBoxSize) {
73391
74070
  const box = entry.borderBoxSize[0];
73392
74071
  if (box) {
@@ -73396,6 +74075,14 @@ focus outline in that case.
73396
74075
  return size;
73397
74076
  }
73398
74077
  }
74078
+ if (!entry) {
74079
+ const index = instance.indexFromElement(element);
74080
+ const key = instance.options.getItemKey(index);
74081
+ const cachedSize = instance.itemSizeCache.get(key);
74082
+ if (cachedSize !== void 0) {
74083
+ return cachedSize;
74084
+ }
74085
+ }
73399
74086
  return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
73400
74087
  };
73401
74088
  const scrollWithAdjustments = (offset, {
@@ -73522,7 +74209,8 @@ focus outline in that case.
73522
74209
  isRtl: false,
73523
74210
  useScrollendEvent: false,
73524
74211
  useAnimationFrameWithResizeObserver: false,
73525
- laneAssignmentMode: "estimate"
74212
+ laneAssignmentMode: "estimate",
74213
+ useCachedMeasurements: false
73526
74214
  };
73527
74215
  for (const key in opts2) {
73528
74216
  const v = opts2[key];
@@ -73531,6 +74219,7 @@ focus outline in that case.
73531
74219
  const prevOptions = this.options;
73532
74220
  let anchor = null;
73533
74221
  let followOnAppend = null;
74222
+ let edgeKeysChanged = false;
73534
74223
  if (prevOptions !== void 0 && prevOptions.enabled && merged.enabled && merged.anchorTo === "end" && this.scrollElement !== null) {
73535
74224
  const prevCount = prevOptions.count;
73536
74225
  const nextCount = merged.count;
@@ -73540,6 +74229,7 @@ focus outline in that case.
73540
74229
  const didCountChange = nextCount !== prevCount;
73541
74230
  const didEdgeKeysChange = didCountChange || prevCount > 0 && nextCount > 0 && (merged.getItemKey(0) !== prevFirstKey || merged.getItemKey(nextCount - 1) !== prevLastKey);
73542
74231
  if (didEdgeKeysChange) {
74232
+ edgeKeysChanged = true;
73543
74233
  const item = prevCount > 0 ? this.getVirtualItemForOffset(this.getScrollOffset()) ?? measurements[0] : null;
73544
74234
  if (item) {
73545
74235
  anchor = [item.key, this.getScrollOffset() - item.start];
@@ -73551,11 +74241,38 @@ focus outline in that case.
73551
74241
  }
73552
74242
  }
73553
74243
  this.options = merged;
73554
- if (anchor || followOnAppend) {
74244
+ if (edgeKeysChanged) {
74245
+ this.pendingMin = 0;
74246
+ this.itemSizeCacheVersion++;
74247
+ }
74248
+ let anchorResolved = false;
74249
+ let anchorDelta = 0;
74250
+ if (anchor && this.scrollOffset !== null) {
74251
+ const [anchorKey, anchorOffset] = anchor;
74252
+ const newMeasurements = this.getMeasurements();
74253
+ const { count, getItemKey } = this.options;
74254
+ let idx = 0;
74255
+ while (idx < count && getItemKey(idx) !== anchorKey) {
74256
+ idx++;
74257
+ }
74258
+ if (idx < count) {
74259
+ const anchorItem = newMeasurements[idx];
74260
+ if (anchorItem) {
74261
+ const newOffset = anchorItem.start + anchorOffset;
74262
+ if (newOffset !== this.scrollOffset) {
74263
+ anchorDelta = newOffset - this.scrollOffset;
74264
+ this.scrollOffset = newOffset;
74265
+ anchorResolved = true;
74266
+ }
74267
+ }
74268
+ }
74269
+ }
74270
+ if (anchorResolved || followOnAppend) {
73555
74271
  this.pendingScrollAnchor = [
73556
- (anchor == null ? void 0 : anchor[0]) ?? null,
73557
- (anchor == null ? void 0 : anchor[1]) ?? 0,
73558
- followOnAppend
74272
+ anchorResolved ? anchor[0] : null,
74273
+ anchorResolved ? anchor[1] : 0,
74274
+ followOnAppend,
74275
+ anchorDelta
73559
74276
  ];
73560
74277
  }
73561
74278
  };
@@ -73692,19 +74409,17 @@ focus outline in that case.
73692
74409
  const anchor = this.pendingScrollAnchor;
73693
74410
  this.pendingScrollAnchor = null;
73694
74411
  if (anchor && this.scrollElement && this.options.enabled) {
73695
- const [key, offset, followOnAppend] = anchor;
73696
- if (key !== null) {
73697
- const { count, getItemKey } = this.options;
73698
- let index = 0;
73699
- while (index < count && getItemKey(index) !== key) {
73700
- index++;
73701
- }
73702
- const item = index < count ? this.getMeasurements()[index] : void 0;
73703
- if (item) {
73704
- const delta = item.start + offset - this.getScrollOffset();
73705
- if (!approxEqual(delta, 0)) {
73706
- this.applyScrollAdjustment(delta);
74412
+ const [key, _offset, followOnAppend, anchorDelta] = anchor;
74413
+ if (key !== null && !followOnAppend) {
74414
+ if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) {
74415
+ if (anchorDelta !== 0) {
74416
+ this._iosDeferredAdjustment += anchorDelta;
73707
74417
  }
74418
+ } else {
74419
+ this._scrollToOffset(this.getScrollOffset(), {
74420
+ adjustments: void 0,
74421
+ behavior: void 0
74422
+ });
73708
74423
  }
73709
74424
  }
73710
74425
  if (followOnAppend) {
@@ -74072,13 +74787,13 @@ focus outline in that case.
74072
74787
  delta,
74073
74788
  this
74074
74789
  ) : (
74075
- // Default: adjust scrollTop only when the resize is an above-
74076
- // viewport item AND we're not actively scrolling backward.
74077
- // Adjusting during backward scroll fights the user's scroll
74078
- // direction and produces the "items jump while scrolling up"
74079
- // jank reported across many issues. Users who want the old
74080
- // behavior can pass shouldAdjustScrollPositionOnItemSizeChange.
74081
- itemStart < this.getScrollOffset() + this.scrollAdjustments && this.scrollDirection !== "backward"
74790
+ // Default: adjust when the resize is an above-viewport item.
74791
+ // First measurement (!has(key)): always adjust the item
74792
+ // has never been sized, so the estimate→actual delta must
74793
+ // be compensated regardless of scroll direction.
74794
+ // Re-measurement (has(key)): skip during backward scroll
74795
+ // to avoid the "items jump while scrolling up" cascade.
74796
+ itemStart < this.getScrollOffset() + this.scrollAdjustments && (!this.itemSizeCache.has(key) || this.scrollDirection !== "backward")
74082
74797
  ));
74083
74798
  if (this.pendingMin === null || index < this.pendingMin) {
74084
74799
  this.pendingMin = index;
@@ -74671,7 +75386,7 @@ focus outline in that case.
74671
75386
  };
74672
75387
  }
74673
75388
  getGridTemplateColumns() {
74674
- return this.getVisibleColumns()
75389
+ return this.getUnpinnedVisibleColumns()
74675
75390
  .map(column => {
74676
75391
  const { minPixelWidth, currentPixelWidth, currentFractionalWidth } = column.columnInternals;
74677
75392
  if (currentPixelWidth !== undefined) {
@@ -74697,7 +75412,7 @@ focus outline in that case.
74697
75412
  this.activeColumnIndex = this.leftColumnIndex + (this.activeColumnDivider % 2);
74698
75413
  this.dragStart = dragStart;
74699
75414
  this.currentTotalDelta = 0;
74700
- this.visibleColumns = this.getVisibleColumns();
75415
+ this.visibleColumns = this.getUnpinnedVisibleColumns();
74701
75416
  this.setColumnsToFixedSize();
74702
75417
  this.initialTableScrollableWidth = this.table.viewport.scrollWidth;
74703
75418
  this.initialTableScrollableMinWidth = this.table.tableScrollableMinWidth;
@@ -74768,7 +75483,7 @@ focus outline in that case.
74768
75483
  */
74769
75484
  getFirstLeftResizableColumnIndex(columnIndex) {
74770
75485
  const visibleColumns = this.visibleColumns.length === 0
74771
- ? this.getVisibleColumns()
75486
+ ? this.getUnpinnedVisibleColumns()
74772
75487
  : this.visibleColumns;
74773
75488
  for (let i = columnIndex; i >= 0; i--) {
74774
75489
  const column = visibleColumns[i];
@@ -74788,7 +75503,7 @@ focus outline in that case.
74788
75503
  */
74789
75504
  getFirstRightResizableColumnIndex(columnIndex) {
74790
75505
  const visibleColumns = this.visibleColumns.length === 0
74791
- ? this.getVisibleColumns()
75506
+ ? this.getUnpinnedVisibleColumns()
74792
75507
  : this.visibleColumns;
74793
75508
  for (let i = columnIndex; i < visibleColumns.length; i++) {
74794
75509
  const column = visibleColumns[i];
@@ -74885,8 +75600,9 @@ focus outline in that case.
74885
75600
  }
74886
75601
  }
74887
75602
  }
74888
- getVisibleColumns() {
74889
- return this.table.columns.filter(column => !column.columnHidden);
75603
+ getUnpinnedVisibleColumns() {
75604
+ return this.table.columns.filter(column => !column.columnHidden
75605
+ && column.columnInternals.pinLocation !== TableColumnPinLocation.left);
74890
75606
  }
74891
75607
  getLeftColumnIndexFromDivider(dividerIndex) {
74892
75608
  return Math.floor(dividerIndex / 2);
@@ -74922,7 +75638,8 @@ focus outline in that case.
74922
75638
  'columnDefinition',
74923
75639
  'actionMenuSlots',
74924
75640
  'selectionMode',
74925
- 'actionMenusPreserveSelection'
75641
+ 'actionMenusPreserveSelection',
75642
+ 'columnPinned'
74926
75643
  ];
74927
75644
  /**
74928
75645
  * Helper class to track what updates are needed to the table based on configuration
@@ -74981,6 +75698,7 @@ focus outline in that case.
74981
75698
  return (this.isTracked('columnSortDisabled')
74982
75699
  || this.isTracked('columnDefinition')
74983
75700
  || this.isTracked('columnHidden')
75701
+ || this.isTracked('columnPinned')
74984
75702
  || this.isTracked('selectionMode')
74985
75703
  || this.isTracked('actionMenuSlots'));
74986
75704
  }
@@ -75012,6 +75730,10 @@ focus outline in that case.
75012
75730
  this.track('columnWidths');
75013
75731
  this.track('columnHidden');
75014
75732
  }
75733
+ else if (isColumnInternalsProperty(changedColumnProperty, 'pinLocation')) {
75734
+ this.track('columnWidths');
75735
+ this.track('columnPinned');
75736
+ }
75015
75737
  else if (isColumnProperty(changedColumnProperty, 'actionMenuSlot')) {
75016
75738
  this.track('actionMenuSlots');
75017
75739
  }
@@ -76713,6 +77435,34 @@ focus outline in that case.
76713
77435
  }
76714
77436
  return '';
76715
77437
  }
77438
+ /**
77439
+ * @internal
77440
+ */
77441
+ get pinnedColumnOffset() {
77442
+ let offset = 0;
77443
+ for (const column of this.pinnedColumns) {
77444
+ const resolvedPixelWidth = this.getPinnedColumnResolvedPixelWidth(column);
77445
+ if (resolvedPixelWidth !== undefined) {
77446
+ const coercedPixelWidth = Math.max(column.columnInternals.minPixelWidth, resolvedPixelWidth);
77447
+ offset += coercedPixelWidth;
77448
+ }
77449
+ }
77450
+ return offset;
77451
+ }
77452
+ /**
77453
+ * @internal
77454
+ */
77455
+ get pinnedColumnsGridTemplateColumns() {
77456
+ return this.pinnedColumns.map(column => {
77457
+ const resolvedPixelWidth = this.getPinnedColumnResolvedPixelWidth(column);
77458
+ if (resolvedPixelWidth !== undefined) {
77459
+ const coercedPixelWidth = Math.max(column.columnInternals.minPixelWidth, resolvedPixelWidth);
77460
+ return `${coercedPixelWidth}px`;
77461
+ }
77462
+ return '';
77463
+ })
77464
+ .join(' ');
77465
+ }
76716
77466
  /**
76717
77467
  * @internal
76718
77468
  */
@@ -76763,6 +77513,10 @@ focus outline in that case.
76763
77513
  * @internal
76764
77514
  */
76765
77515
  this.visibleColumns = [];
77516
+ /**
77517
+ * @internal
77518
+ */
77519
+ this.pinnedColumns = [];
76766
77520
  /**
76767
77521
  * @internal
76768
77522
  * This value determines the size of the viewport area when a user has created horizontal scrollable
@@ -77115,7 +77869,10 @@ focus outline in that case.
77115
77869
  }
77116
77870
  if (this.tableUpdateTracker.updateColumnWidths) {
77117
77871
  this.rowGridColumns = this.layoutManager.getGridTemplateColumns();
77118
- this.visibleColumns = this.columns.filter(column => !column.columnHidden);
77872
+ this.visibleColumns = this.columns.filter(column => !column.columnHidden
77873
+ && column.columnInternals.pinLocation !== TableColumnPinLocation.left);
77874
+ this.pinnedColumns = this.columns.filter(column => !column.columnHidden
77875
+ && column.columnInternals.pinLocation === TableColumnPinLocation.left);
77119
77876
  }
77120
77877
  if (this.tableUpdateTracker.requiresKeyboardFocusReset) {
77121
77878
  this.keyboardNavigationManager.resetFocusState();
@@ -77193,6 +77950,10 @@ focus outline in that case.
77193
77950
  this.observeColumns();
77194
77951
  this.tableUpdateTracker.trackColumnInstancesChanged();
77195
77952
  }
77953
+ getPinnedColumnResolvedPixelWidth(column) {
77954
+ const { currentPixelWidth } = column.columnInternals;
77955
+ return currentPixelWidth;
77956
+ }
77196
77957
  updateRequestedSlotsForOpeningActionMenu(openActionMenuRecordId) {
77197
77958
  for (const actionMenuSlot of this.actionMenuSlots) {
77198
77959
  this.requestedSlots.set(actionMenuSlot, {
@@ -77367,6 +78128,7 @@ focus outline in that case.
77367
78128
  this.tableValidator.validateColumnSortIndices(this.getColumnsParticipatingInSorting().map(x => x.columnInternals.currentSortIndex));
77368
78129
  this.tableValidator.validateColumnGroupIndices(this.getColumnsParticipatingInGrouping().map(x => x.columnInternals.groupIndex));
77369
78130
  this.tableValidator.validateColumnConfigurations(this.columns);
78131
+ this.tableValidator.validatePinnedColumnConfigurations(this.columns);
77370
78132
  if (this.dataHierarchyManager) {
77371
78133
  this.validateWithData(this.dataHierarchyManager.getAllRecords());
77372
78134
  }
@@ -77639,12 +78401,21 @@ focus outline in that case.
77639
78401
  __decorate([
77640
78402
  volatile
77641
78403
  ], Table$1.prototype, "collapseButtonVisibility", null);
78404
+ __decorate([
78405
+ volatile
78406
+ ], Table$1.prototype, "pinnedColumnOffset", null);
78407
+ __decorate([
78408
+ volatile
78409
+ ], Table$1.prototype, "pinnedColumnsGridTemplateColumns", null);
77642
78410
  __decorate([
77643
78411
  observable
77644
78412
  ], Table$1.prototype, "firstSortedColumn", void 0);
77645
78413
  __decorate([
77646
78414
  observable
77647
78415
  ], Table$1.prototype, "visibleColumns", void 0);
78416
+ __decorate([
78417
+ observable
78418
+ ], Table$1.prototype, "pinnedColumns", void 0);
77648
78419
  __decorate([
77649
78420
  observable
77650
78421
  ], Table$1.prototype, "tableScrollableMinWidth", void 0);
@@ -78943,6 +79714,23 @@ focus outline in that case.
78943
79714
 
78944
79715
  const template$c = html `${template$g}<slot ${slotted('mappings')} name="mapping"></slot>`;
78945
79716
 
79717
+ // As the returned class is internal to the function, we can't write a signature that uses is directly, so rely on inference
79718
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type
79719
+ function mixinPinnableColumnAPI(base) {
79720
+ /**
79721
+ * The Mixin that provides a concrete column with the API to allow pinning
79722
+ * a fixed-width column within a table.
79723
+ */
79724
+ class PinnableColumn extends base {
79725
+ /** @internal */
79726
+ pinLocationChanged() {
79727
+ this.columnInternals.pinLocation = this.pinLocation;
79728
+ }
79729
+ }
79730
+ attr({ attribute: 'pin-location' })(PinnableColumn.prototype, 'pinLocation');
79731
+ return PinnableColumn;
79732
+ }
79733
+
78946
79734
  const enumBaseValidityFlagNames = [
78947
79735
  'invalidMappingKeyValueForType',
78948
79736
  'duplicateMappingKey',
@@ -79331,7 +80119,7 @@ focus outline in that case.
79331
80119
  * Table column that maps number, boolean, or string values to an icon, a spinner,
79332
80120
  * text, or an icon/spinner with text.
79333
80121
  */
79334
- class TableColumnMapping extends mixinGroupableColumnAPI(mixinFractionalWidthColumnAPI(mixinSortableColumnAPI((TableColumnEnumBase)))) {
80122
+ class TableColumnMapping extends mixinGroupableColumnAPI(mixinFractionalWidthColumnAPI(mixinPinnableColumnAPI(mixinSortableColumnAPI((TableColumnEnumBase))))) {
79335
80123
  minPixelWidthChanged() {
79336
80124
  if (this.widthMode !== TableColumnMappingWidthMode.iconSize) {
79337
80125
  this.columnInternals.minPixelWidth = this.getConfiguredMinPixelWidth();