@ni/nimble-components 32.9.0 → 32.9.2

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 (37) hide show
  1. package/dist/all-components-bundle.js +296 -228
  2. package/dist/all-components-bundle.js.map +1 -1
  3. package/dist/all-components-bundle.min.js +3653 -3636
  4. package/dist/all-components-bundle.min.js.map +1 -1
  5. package/dist/esm/checkbox/index.d.ts +12 -4
  6. package/dist/esm/checkbox/index.js +2 -11
  7. package/dist/esm/checkbox/index.js.map +1 -1
  8. package/dist/esm/combobox/index.d.ts +12 -7
  9. package/dist/esm/combobox/index.js +2 -8
  10. package/dist/esm/combobox/index.js.map +1 -1
  11. package/dist/esm/number-field/index.d.ts +12 -11
  12. package/dist/esm/number-field/index.js +2 -8
  13. package/dist/esm/number-field/index.js.map +1 -1
  14. package/dist/esm/patterns/error/template.js +7 -1
  15. package/dist/esm/patterns/error/template.js.map +1 -1
  16. package/dist/esm/patterns/error/testing/error-pattern.pageobject.d.ts +14 -0
  17. package/dist/esm/patterns/error/testing/error-pattern.pageobject.js +46 -0
  18. package/dist/esm/patterns/error/testing/error-pattern.pageobject.js.map +1 -0
  19. package/dist/esm/patterns/error/types.d.ts +16 -5
  20. package/dist/esm/patterns/error/types.js +27 -1
  21. package/dist/esm/patterns/error/types.js.map +1 -1
  22. package/dist/esm/radio-group/index.d.ts +11 -4
  23. package/dist/esm/radio-group/index.js +2 -13
  24. package/dist/esm/radio-group/index.js.map +1 -1
  25. package/dist/esm/rich-text/editor/index.d.ts +12 -16
  26. package/dist/esm/rich-text/editor/index.js +2 -14
  27. package/dist/esm/rich-text/editor/index.js.map +1 -1
  28. package/dist/esm/select/index.d.ts +11 -11
  29. package/dist/esm/select/index.js +2 -8
  30. package/dist/esm/select/index.js.map +1 -1
  31. package/dist/esm/text-area/index.d.ts +12 -18
  32. package/dist/esm/text-area/index.js +2 -15
  33. package/dist/esm/text-area/index.js.map +1 -1
  34. package/dist/esm/text-field/index.d.ts +12 -11
  35. package/dist/esm/text-field/index.js +2 -8
  36. package/dist/esm/text-field/index.js.map +1 -1
  37. package/package.json +2 -3
@@ -20504,8 +20504,68 @@ so this becomes the fallback color for the slot */ ''}
20504
20504
  }
20505
20505
  `;
20506
20506
 
20507
+ /**
20508
+ * The runtime behavior for template overflow detection.
20509
+ * @public
20510
+ */
20511
+ class OverflowBehavior {
20512
+ /**
20513
+ * Creates an instance of OverflowBehavior.
20514
+ * @param target - The element to check for overflow.
20515
+ * @param propertyName - The name of the property to assign the overflow state to.
20516
+ */
20517
+ constructor(target, propertyName) {
20518
+ this.target = target;
20519
+ this.propertyName = propertyName;
20520
+ }
20521
+ /**
20522
+ * Bind this behavior to the source.
20523
+ * @param source - The source to bind to.
20524
+ * @param context - The execution context that the binding is operating within.
20525
+ */
20526
+ bind(source) {
20527
+ this.source = source;
20528
+ this.setSourceValue(false);
20529
+ this.mouseOverHandler = () => {
20530
+ const hasOverflow = this.target.offsetWidth < this.target.scrollWidth;
20531
+ this.setSourceValue(hasOverflow);
20532
+ };
20533
+ this.mouseOutHandler = () => {
20534
+ this.setSourceValue(false);
20535
+ };
20536
+ this.target.addEventListener('mouseover', this.mouseOverHandler);
20537
+ this.target.addEventListener('mouseout', this.mouseOutHandler);
20538
+ }
20539
+ /**
20540
+ * Unbinds this behavior from the source.
20541
+ * @param source - The source to unbind from.
20542
+ */
20543
+ unbind() {
20544
+ this.source = undefined;
20545
+ this.target.removeEventListener('mouseover', this.mouseOverHandler);
20546
+ this.target.removeEventListener('mouseout', this.mouseOutHandler);
20547
+ }
20548
+ setSourceValue(value) {
20549
+ // @ts-expect-error set property on source
20550
+ this.source[this.propertyName] = value;
20551
+ }
20552
+ }
20553
+ /**
20554
+ * A directive that observes if an element has overflow and sets a flag.
20555
+ * @param propertyName - The name of the property to assign the overflow flag.
20556
+ * @public
20557
+ */
20558
+ function overflow(propertyName) {
20559
+ return new AttachedBehaviorHTMLDirective('nimble-overflow', OverflowBehavior, propertyName);
20560
+ }
20561
+
20507
20562
  const errorTextTemplate = html `
20508
- <div class="error-text" title="${x => x.errorText}" aria-live="polite">
20563
+ <div
20564
+ class="error-text"
20565
+ ${overflow('errorHasOverflow')}
20566
+ title="${x => (x.errorHasOverflow && x.errorText ? x.errorText : null)}"
20567
+ aria-live="polite"
20568
+ >
20509
20569
  ${x => x.errorText}
20510
20570
  </div>
20511
20571
  `;
@@ -20550,14 +20610,37 @@ so this becomes the fallback color for the slot */ ''}
20550
20610
  </template>
20551
20611
  `;
20552
20612
 
20613
+ // As the returned class is internal to the function, we can't write a signature that uses is directly, so rely on inference
20614
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type
20615
+ function mixinErrorPattern(base) {
20616
+ /**
20617
+ * The Mixin that provides a concrete column with the API to support being resized
20618
+ * proportionally within a Table.
20619
+ */
20620
+ class ErrorPatternElement extends base {
20621
+ constructor() {
20622
+ super(...arguments);
20623
+ /*
20624
+ * Show the error appearance of the control
20625
+ */
20626
+ this.errorVisible = false;
20627
+ /* @internal
20628
+ * Indicates if the error text has overflowed its container. The value should not be
20629
+ * set directly. Instead, it is used with the `overflow` directive.
20630
+ */
20631
+ this.errorHasOverflow = false;
20632
+ }
20633
+ }
20634
+ attr({ attribute: 'error-text' })(ErrorPatternElement.prototype, 'errorText');
20635
+ attr({ attribute: 'error-visible', mode: 'boolean' })(ErrorPatternElement.prototype, 'errorVisible');
20636
+ observable(ErrorPatternElement.prototype, 'errorHasOverflow');
20637
+ return ErrorPatternElement;
20638
+ }
20639
+
20553
20640
  /**
20554
20641
  * A nimble-styled checkbox control.
20555
20642
  */
20556
- class Checkbox extends Checkbox$1 {
20557
- constructor() {
20558
- super(...arguments);
20559
- this.errorVisible = false;
20560
- }
20643
+ class Checkbox extends mixinErrorPattern(Checkbox$1) {
20561
20644
  /**
20562
20645
  * @internal
20563
20646
  */
@@ -20569,12 +20652,6 @@ so this becomes the fallback color for the slot */ ''}
20569
20652
  __decorate$1([
20570
20653
  attr({ attribute: 'tabindex', converter: nullableNumberConverter })
20571
20654
  ], Checkbox.prototype, "tabIndex", void 0);
20572
- __decorate$1([
20573
- attr({ attribute: 'error-text' })
20574
- ], Checkbox.prototype, "errorText", void 0);
20575
- __decorate$1([
20576
- attr({ attribute: 'error-visible', mode: 'boolean' })
20577
- ], Checkbox.prototype, "errorVisible", void 0);
20578
20655
  const nimbleCheckbox = Checkbox.compose({
20579
20656
  baseName: 'checkbox',
20580
20657
  baseClass: Checkbox$1,
@@ -21126,61 +21203,6 @@ so this becomes the fallback color for the slot */ ''}
21126
21203
  }
21127
21204
  `));
21128
21205
 
21129
- /**
21130
- * The runtime behavior for template overflow detection.
21131
- * @public
21132
- */
21133
- class OverflowBehavior {
21134
- /**
21135
- * Creates an instance of OverflowBehavior.
21136
- * @param target - The element to check for overflow.
21137
- * @param propertyName - The name of the property to assign the overflow state to.
21138
- */
21139
- constructor(target, propertyName) {
21140
- this.target = target;
21141
- this.propertyName = propertyName;
21142
- }
21143
- /**
21144
- * Bind this behavior to the source.
21145
- * @param source - The source to bind to.
21146
- * @param context - The execution context that the binding is operating within.
21147
- */
21148
- bind(source) {
21149
- this.source = source;
21150
- this.setSourceValue(false);
21151
- this.mouseOverHandler = () => {
21152
- const hasOverflow = this.target.offsetWidth < this.target.scrollWidth;
21153
- this.setSourceValue(hasOverflow);
21154
- };
21155
- this.mouseOutHandler = () => {
21156
- this.setSourceValue(false);
21157
- };
21158
- this.target.addEventListener('mouseover', this.mouseOverHandler);
21159
- this.target.addEventListener('mouseout', this.mouseOutHandler);
21160
- }
21161
- /**
21162
- * Unbinds this behavior from the source.
21163
- * @param source - The source to unbind from.
21164
- */
21165
- unbind() {
21166
- this.source = undefined;
21167
- this.target.removeEventListener('mouseover', this.mouseOverHandler);
21168
- this.target.removeEventListener('mouseout', this.mouseOutHandler);
21169
- }
21170
- setSourceValue(value) {
21171
- // @ts-expect-error set property on source
21172
- this.source[this.propertyName] = value;
21173
- }
21174
- }
21175
- /**
21176
- * A directive that observes if an element has overflow and sets a flag.
21177
- * @param propertyName - The name of the property to assign the overflow flag.
21178
- * @public
21179
- */
21180
- function overflow(propertyName) {
21181
- return new AttachedBehaviorHTMLDirective('nimble-overflow', OverflowBehavior, propertyName);
21182
- }
21183
-
21184
21206
  /* eslint-disable @typescript-eslint/indent */
21185
21207
  // prettier-ignore
21186
21208
  const template$z = (context, definition) => html `
@@ -21290,11 +21312,10 @@ so this becomes the fallback color for the slot */ ''}
21290
21312
  /**
21291
21313
  * A nimble-styed HTML combobox
21292
21314
  */
21293
- class Combobox extends FormAssociatedCombobox {
21315
+ class Combobox extends mixinErrorPattern(FormAssociatedCombobox) {
21294
21316
  constructor() {
21295
21317
  super(...arguments);
21296
21318
  this.appearance = DropdownAppearance.underline;
21297
- this.errorVisible = false;
21298
21319
  /**
21299
21320
  * The open attribute.
21300
21321
  */
@@ -21890,12 +21911,6 @@ so this becomes the fallback color for the slot */ ''}
21890
21911
  __decorate$1([
21891
21912
  attr
21892
21913
  ], Combobox.prototype, "appearance", void 0);
21893
- __decorate$1([
21894
- attr({ attribute: 'error-text' })
21895
- ], Combobox.prototype, "errorText", void 0);
21896
- __decorate$1([
21897
- attr({ attribute: 'error-visible', mode: 'boolean' })
21898
- ], Combobox.prototype, "errorVisible", void 0);
21899
21914
  __decorate$1([
21900
21915
  attr({ attribute: 'autocomplete', mode: 'fromView' })
21901
21916
  ], Combobox.prototype, "autocomplete", void 0);
@@ -26762,11 +26777,10 @@ so this becomes the fallback color for the slot */ ''}
26762
26777
  /**
26763
26778
  * A nimble-styled HTML number input
26764
26779
  */
26765
- class NumberField extends NumberField$1 {
26780
+ class NumberField extends mixinErrorPattern(NumberField$1) {
26766
26781
  constructor() {
26767
26782
  super(...arguments);
26768
26783
  this.appearance = NumberFieldAppearance.underline;
26769
- this.errorVisible = false;
26770
26784
  }
26771
26785
  connectedCallback() {
26772
26786
  super.connectedCallback();
@@ -26777,12 +26791,6 @@ so this becomes the fallback color for the slot */ ''}
26777
26791
  __decorate$1([
26778
26792
  attr
26779
26793
  ], NumberField.prototype, "appearance", void 0);
26780
- __decorate$1([
26781
- attr({ attribute: 'error-text' })
26782
- ], NumberField.prototype, "errorText", void 0);
26783
- __decorate$1([
26784
- attr({ attribute: 'error-visible', mode: 'boolean' })
26785
- ], NumberField.prototype, "errorVisible", void 0);
26786
26794
  /**
26787
26795
  * A function that returns a number-field registration for configuring the component with a DesignSystem.
26788
26796
  *
@@ -27018,18 +27026,8 @@ so this becomes the fallback color for the slot */ ''}
27018
27026
  /**
27019
27027
  * A nimble-styled grouping element for radio buttons
27020
27028
  */
27021
- class RadioGroup extends RadioGroup$1 {
27022
- constructor() {
27023
- super(...arguments);
27024
- this.errorVisible = false;
27025
- }
27029
+ class RadioGroup extends mixinErrorPattern(RadioGroup$1) {
27026
27030
  }
27027
- __decorate$1([
27028
- attr({ attribute: 'error-text' })
27029
- ], RadioGroup.prototype, "errorText", void 0);
27030
- __decorate$1([
27031
- attr({ attribute: 'error-visible', mode: 'boolean' })
27032
- ], RadioGroup.prototype, "errorVisible", void 0);
27033
27031
  const nimbleRadioGroup = RadioGroup.compose({
27034
27032
  baseName: 'radio-group',
27035
27033
  baseClass: RadioGroup$1,
@@ -29955,6 +29953,7 @@ so this becomes the fallback color for the slot */ ''}
29955
29953
  this.options = options;
29956
29954
  this.isOpen = isOpen;
29957
29955
  this.open = 0;
29956
+ this.localPreserveWS = false;
29958
29957
  let topNode = options.topNode, topContext;
29959
29958
  let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
29960
29959
  if (topNode)
@@ -29981,11 +29980,12 @@ so this becomes the fallback color for the slot */ ''}
29981
29980
  }
29982
29981
  addTextNode(dom, marks) {
29983
29982
  let value = dom.nodeValue;
29984
- let top = this.top;
29985
- if (top.options & OPT_PRESERVE_WS_FULL ||
29983
+ let top = this.top, preserveWS = (top.options & OPT_PRESERVE_WS_FULL) ? "full"
29984
+ : this.localPreserveWS || (top.options & OPT_PRESERVE_WS) > 0;
29985
+ if (preserveWS === "full" ||
29986
29986
  top.inlineContext(dom) ||
29987
29987
  /[^ \t\r\n\u000c]/.test(value)) {
29988
- if (!(top.options & OPT_PRESERVE_WS)) {
29988
+ if (!preserveWS) {
29989
29989
  value = value.replace(/[ \t\r\n\u000c]+/g, " ");
29990
29990
  // If this starts with whitespace, and there is no node before it, or
29991
29991
  // a hard break, or a text node that ends with whitespace, strip the
@@ -29999,7 +29999,7 @@ so this becomes the fallback color for the slot */ ''}
29999
29999
  value = value.slice(1);
30000
30000
  }
30001
30001
  }
30002
- else if (!(top.options & OPT_PRESERVE_WS_FULL)) {
30002
+ else if (preserveWS !== "full") {
30003
30003
  value = value.replace(/\r?\n|\r/g, " ");
30004
30004
  }
30005
30005
  else {
@@ -30016,12 +30016,15 @@ so this becomes the fallback color for the slot */ ''}
30016
30016
  // Try to find a handler for the given tag and use that to parse. If
30017
30017
  // none is found, the element's content nodes are added directly.
30018
30018
  addElement(dom, marks, matchAfter) {
30019
+ let outerWS = this.localPreserveWS, top = this.top;
30020
+ if (dom.tagName == "PRE" || /pre/.test(dom.style && dom.style.whiteSpace))
30021
+ this.localPreserveWS = true;
30019
30022
  let name = dom.nodeName.toLowerCase(), ruleID;
30020
30023
  if (listTags.hasOwnProperty(name) && this.parser.normalizeLists)
30021
30024
  normalizeList(dom);
30022
30025
  let rule = (this.options.ruleFromNode && this.options.ruleFromNode(dom)) ||
30023
30026
  (ruleID = this.parser.matchTag(dom, this, matchAfter));
30024
- if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
30027
+ out: if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
30025
30028
  this.findInside(dom);
30026
30029
  this.ignoreFallback(dom, marks);
30027
30030
  }
@@ -30030,7 +30033,7 @@ so this becomes the fallback color for the slot */ ''}
30030
30033
  this.open = Math.max(0, this.open - 1);
30031
30034
  else if (rule && rule.skip.nodeType)
30032
30035
  dom = rule.skip;
30033
- let sync, top = this.top, oldNeedsBlock = this.needsBlock;
30036
+ let sync, oldNeedsBlock = this.needsBlock;
30034
30037
  if (blockTags.hasOwnProperty(name)) {
30035
30038
  if (top.content.length && top.content[0].isInline && this.open) {
30036
30039
  this.open--;
@@ -30042,7 +30045,7 @@ so this becomes the fallback color for the slot */ ''}
30042
30045
  }
30043
30046
  else if (!dom.firstChild) {
30044
30047
  this.leafFallback(dom, marks);
30045
- return;
30048
+ break out;
30046
30049
  }
30047
30050
  let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks);
30048
30051
  if (innerMarks)
@@ -30056,6 +30059,7 @@ so this becomes the fallback color for the slot */ ''}
30056
30059
  if (innerMarks)
30057
30060
  this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : undefined);
30058
30061
  }
30062
+ this.localPreserveWS = outerWS;
30059
30063
  }
30060
30064
  // Called for leaf DOM nodes that would otherwise be ignored
30061
30065
  leafFallback(dom, marks) {
@@ -30246,14 +30250,18 @@ so this becomes the fallback color for the slot */ ''}
30246
30250
  finish() {
30247
30251
  this.open = 0;
30248
30252
  this.closeExtra(this.isOpen);
30249
- return this.nodes[0].finish(this.isOpen || this.options.topOpen);
30253
+ return this.nodes[0].finish(!!(this.isOpen || this.options.topOpen));
30250
30254
  }
30251
30255
  sync(to) {
30252
- for (let i = this.open; i >= 0; i--)
30256
+ for (let i = this.open; i >= 0; i--) {
30253
30257
  if (this.nodes[i] == to) {
30254
30258
  this.open = i;
30255
30259
  return true;
30256
30260
  }
30261
+ else if (this.localPreserveWS) {
30262
+ this.nodes[i].options |= OPT_PRESERVE_WS;
30263
+ }
30264
+ }
30257
30265
  return false;
30258
30266
  }
30259
30267
  get currentPos() {
@@ -34163,11 +34171,12 @@ so this becomes the fallback color for the slot */ ''}
34163
34171
  for (let cur = node, sawBlock = false;;) {
34164
34172
  if (cur == view.dom)
34165
34173
  break;
34166
- let desc = view.docView.nearestDesc(cur, true);
34174
+ let desc = view.docView.nearestDesc(cur, true), rect;
34167
34175
  if (!desc)
34168
34176
  return null;
34169
- if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM)) {
34170
- let rect = desc.dom.getBoundingClientRect();
34177
+ if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) &&
34178
+ // Ignore elements with zero-size bounding rectangles
34179
+ ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
34171
34180
  if (desc.node.isBlock && desc.parent) {
34172
34181
  // Only apply the horizontal test to the innermost block. Vertical for any parent.
34173
34182
  if (!sawBlock && rect.left > coords.left || rect.top > coords.top)
@@ -36809,7 +36818,7 @@ so this becomes the fallback color for the slot */ ''}
36809
36818
  this.lastIOSEnterFallbackTimeout = -1;
36810
36819
  this.lastFocus = 0;
36811
36820
  this.lastTouch = 0;
36812
- this.lastAndroidDelete = 0;
36821
+ this.lastChromeDelete = 0;
36813
36822
  this.composing = false;
36814
36823
  this.compositionNode = null;
36815
36824
  this.composingTimeout = -1;
@@ -38786,11 +38795,11 @@ so this becomes the fallback color for the slot */ ''}
38786
38795
  view.domObserver.suppressSelectionUpdates(); // #820
38787
38796
  return;
38788
38797
  }
38789
- // Chrome Android will occasionally, during composition, delete the
38798
+ // Chrome will occasionally, during composition, delete the
38790
38799
  // entire composition and then immediately insert it again. This is
38791
38800
  // used to detect that situation.
38792
- if (chrome && android && change.endB == change.start)
38793
- view.input.lastAndroidDelete = Date.now();
38801
+ if (chrome && change.endB == change.start)
38802
+ view.input.lastChromeDelete = Date.now();
38794
38803
  // This tries to detect Android virtual keyboard
38795
38804
  // enter-and-pick-suggestion action. That sometimes (see issue
38796
38805
  // #1059) first fires a DOM mutation, before moving the selection to
@@ -38841,13 +38850,13 @@ so this becomes the fallback color for the slot */ ''}
38841
38850
  tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from));
38842
38851
  if (parse.sel) {
38843
38852
  let sel = resolveSelection(view, tr.doc, parse.sel);
38844
- // Chrome Android will sometimes, during composition, report the
38853
+ // Chrome will sometimes, during composition, report the
38845
38854
  // selection in the wrong place. If it looks like that is
38846
38855
  // happening, don't update the selection.
38847
38856
  // Edge just doesn't move the cursor forward when you start typing
38848
38857
  // in an empty block or between br nodes.
38849
- if (sel && !(chrome && android && view.composing && sel.empty &&
38850
- (change.start != change.endB || view.input.lastAndroidDelete < Date.now() - 100) &&
38858
+ if (sel && !(chrome && view.composing && sel.empty &&
38859
+ (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) &&
38851
38860
  (sel.head == chFrom || sel.head == tr.mapping.map(chTo) - 1) ||
38852
38861
  ie$1 && sel.empty && sel.head == chFrom))
38853
38862
  tr.setSelection(sel);
@@ -40343,28 +40352,44 @@ so this becomes the fallback color for the slot */ ''}
40343
40352
  function wrapInList$1(listType, attrs = null) {
40344
40353
  return function (state, dispatch) {
40345
40354
  let { $from, $to } = state.selection;
40346
- let range = $from.blockRange($to), doJoin = false, outerRange = range;
40355
+ let range = $from.blockRange($to);
40347
40356
  if (!range)
40348
40357
  return false;
40349
- // This is at the top of an existing list item
40350
- if (range.depth >= 2 && $from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex == 0) {
40351
- // Don't do anything if this is the top of the list
40352
- if ($from.index(range.depth - 1) == 0)
40353
- return false;
40354
- let $insert = state.doc.resolve(range.start - 2);
40355
- outerRange = new NodeRange($insert, $insert, range.depth);
40356
- if (range.endIndex < range.parent.childCount)
40357
- range = new NodeRange($from, state.doc.resolve($to.end(range.depth)), range.depth);
40358
- doJoin = true;
40359
- }
40360
- let wrap = findWrapping(outerRange, listType, attrs, range);
40361
- if (!wrap)
40358
+ let tr = dispatch ? state.tr : null;
40359
+ if (!wrapRangeInList(tr, range, listType, attrs))
40362
40360
  return false;
40363
40361
  if (dispatch)
40364
- dispatch(doWrapInList(state.tr, range, wrap, doJoin, listType).scrollIntoView());
40362
+ dispatch(tr.scrollIntoView());
40365
40363
  return true;
40366
40364
  };
40367
40365
  }
40366
+ /**
40367
+ Try to wrap the given node range in a list of the given type.
40368
+ Return `true` when this is possible, `false` otherwise. When `tr`
40369
+ is non-null, the wrapping is added to that transaction. When it is
40370
+ `null`, the function only queries whether the wrapping is
40371
+ possible.
40372
+ */
40373
+ function wrapRangeInList(tr, range, listType, attrs = null) {
40374
+ let doJoin = false, outerRange = range, doc = range.$from.doc;
40375
+ // This is at the top of an existing list item
40376
+ if (range.depth >= 2 && range.$from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex == 0) {
40377
+ // Don't do anything if this is the top of the list
40378
+ if (range.$from.index(range.depth - 1) == 0)
40379
+ return false;
40380
+ let $insert = doc.resolve(range.start - 2);
40381
+ outerRange = new NodeRange($insert, $insert, range.depth);
40382
+ if (range.endIndex < range.parent.childCount)
40383
+ range = new NodeRange(range.$from, doc.resolve(range.$to.end(range.depth)), range.depth);
40384
+ doJoin = true;
40385
+ }
40386
+ let wrap = findWrapping(outerRange, listType, attrs, range);
40387
+ if (!wrap)
40388
+ return false;
40389
+ if (tr)
40390
+ doWrapInList(tr, range, wrap, doJoin, listType);
40391
+ return true;
40392
+ }
40368
40393
  function doWrapInList(tr, range, wrappers, joinBefore, listType) {
40369
40394
  let content = Fragment.empty;
40370
40395
  for (let i = wrappers.length - 1; i >= 0; i--)
@@ -41462,6 +41487,8 @@ so this becomes the fallback color for the slot */ ''}
41462
41487
  const success = handlers.every(handler => handler !== null);
41463
41488
  return success;
41464
41489
  }
41490
+ // When dragging across editors, must get another editor instance to delete selection content.
41491
+ let tiptapDragFromOtherEditor = null;
41465
41492
  const createClipboardPasteEvent = (text) => {
41466
41493
  var _a;
41467
41494
  const event = new ClipboardEvent('paste', {
@@ -41524,11 +41551,21 @@ so this becomes the fallback color for the slot */ ''}
41524
41551
  dragSourceElement = ((_a = view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.contains(event.target))
41525
41552
  ? view.dom.parentElement
41526
41553
  : null;
41554
+ if (dragSourceElement) {
41555
+ tiptapDragFromOtherEditor = editor;
41556
+ }
41557
+ };
41558
+ const handleDragend = () => {
41559
+ if (tiptapDragFromOtherEditor) {
41560
+ tiptapDragFromOtherEditor = null;
41561
+ }
41527
41562
  };
41528
41563
  window.addEventListener('dragstart', handleDragstart);
41564
+ window.addEventListener('dragend', handleDragend);
41529
41565
  return {
41530
41566
  destroy() {
41531
41567
  window.removeEventListener('dragstart', handleDragstart);
41568
+ window.removeEventListener('dragend', handleDragend);
41532
41569
  },
41533
41570
  };
41534
41571
  },
@@ -41537,6 +41574,18 @@ so this becomes the fallback color for the slot */ ''}
41537
41574
  drop: (view, event) => {
41538
41575
  isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement;
41539
41576
  dropEvent = event;
41577
+ if (!isDroppedFromProseMirror) {
41578
+ const dragFromOtherEditor = tiptapDragFromOtherEditor;
41579
+ if (dragFromOtherEditor) {
41580
+ // setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0
41581
+ setTimeout(() => {
41582
+ const selection = dragFromOtherEditor.state.selection;
41583
+ if (selection) {
41584
+ dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to });
41585
+ }
41586
+ }, 10);
41587
+ }
41588
+ }
41540
41589
  return false;
41541
41590
  },
41542
41591
  paste: (_view, event) => {
@@ -42295,30 +42344,13 @@ so this becomes the fallback color for the slot */ ''}
42295
42344
  return TextSelection.create(doc, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos));
42296
42345
  }
42297
42346
 
42298
- function isiOS() {
42299
- return [
42300
- 'iPad Simulator',
42301
- 'iPhone Simulator',
42302
- 'iPod Simulator',
42303
- 'iPad',
42304
- 'iPhone',
42305
- 'iPod',
42306
- ].includes(navigator.platform)
42307
- // iPad on iOS 13 detection
42308
- || (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
42309
- }
42310
-
42311
42347
  const focus = (position = null, options = {}) => ({ editor, view, tr, dispatch, }) => {
42312
42348
  options = {
42313
42349
  scrollIntoView: true,
42314
42350
  ...options,
42315
42351
  };
42316
42352
  const delayedFocus = () => {
42317
- // focus within `requestAnimationFrame` breaks focus on iOS
42318
- // so we have to call this
42319
- if (isiOS()) {
42320
- view.dom.focus();
42321
- }
42353
+ view.dom.focus();
42322
42354
  // For React we have to focus asynchronously. Otherwise wild things happen.
42323
42355
  // see: https://github.com/ueberdosis/tiptap/issues/1520
42324
42356
  requestAnimationFrame(() => {
@@ -42649,6 +42681,19 @@ so this becomes the fallback color for the slot */ ''}
42649
42681
  return joinTextblockForward$1(state, dispatch);
42650
42682
  };
42651
42683
 
42684
+ function isiOS() {
42685
+ return [
42686
+ 'iPad Simulator',
42687
+ 'iPhone Simulator',
42688
+ 'iPod Simulator',
42689
+ 'iPad',
42690
+ 'iPhone',
42691
+ 'iPod',
42692
+ ].includes(navigator.platform)
42693
+ // iPad on iOS 13 detection
42694
+ || (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
42695
+ }
42696
+
42652
42697
  function isMacOS() {
42653
42698
  return typeof navigator !== 'undefined'
42654
42699
  ? /Mac/.test(navigator.platform)
@@ -42859,11 +42904,12 @@ so this becomes the fallback color for the slot */ ''}
42859
42904
  return true;
42860
42905
  };
42861
42906
 
42862
- const selectAll = () => ({ tr, commands }) => {
42863
- return commands.setTextSelection({
42864
- from: 0,
42865
- to: tr.doc.content.size,
42866
- });
42907
+ const selectAll = () => ({ tr, dispatch }) => {
42908
+ if (dispatch) {
42909
+ const selection = new AllSelection(tr.doc);
42910
+ tr.setSelection(selection);
42911
+ }
42912
+ return true;
42867
42913
  };
42868
42914
 
42869
42915
  const selectNodeBackward = () => ({ state, dispatch }) => {
@@ -56145,8 +56191,8 @@ img.ProseMirror-separator {
56145
56191
  this.values = values;
56146
56192
  }
56147
56193
 
56148
- if ( RopeSequence ) Leaf.__proto__ = RopeSequence;
56149
- Leaf.prototype = Object.create( RopeSequence && RopeSequence.prototype );
56194
+ Leaf.__proto__ = RopeSequence;
56195
+ Leaf.prototype = Object.create( RopeSequence.prototype );
56150
56196
  Leaf.prototype.constructor = Leaf;
56151
56197
 
56152
56198
  var prototypeAccessors = { length: { configurable: true },depth: { configurable: true } };
@@ -56206,8 +56252,8 @@ img.ProseMirror-separator {
56206
56252
  this.depth = Math.max(left.depth, right.depth) + 1;
56207
56253
  }
56208
56254
 
56209
- if ( RopeSequence ) Append.__proto__ = RopeSequence;
56210
- Append.prototype = Object.create( RopeSequence && RopeSequence.prototype );
56255
+ Append.__proto__ = RopeSequence;
56256
+ Append.prototype = Object.create( RopeSequence.prototype );
56211
56257
  Append.prototype.constructor = Append;
56212
56258
 
56213
56259
  Append.prototype.flatten = function flatten () {
@@ -57167,6 +57213,8 @@ img.ProseMirror-separator {
57167
57213
  // A valid web domain token
57168
57214
  const WORD = 'WORD'; // only contains a-z
57169
57215
  const UWORD = 'UWORD'; // contains letters other than a-z, used for IDN
57216
+ const ASCIINUMERICAL = 'ASCIINUMERICAL'; // contains a-z, 0-9
57217
+ const ALPHANUMERICAL = 'ALPHANUMERICAL'; // contains numbers and letters other than a-z, used for IDN
57170
57218
 
57171
57219
  // Special case of word
57172
57220
  const LOCALHOST = 'LOCALHOST';
@@ -57194,7 +57242,7 @@ img.ProseMirror-separator {
57194
57242
  const WS = 'WS';
57195
57243
 
57196
57244
  // New line (unix style)
57197
- const NL$1 = 'NL'; // \n
57245
+ const NL = 'NL'; // \n
57198
57246
 
57199
57247
  // Opening/closing bracket classes
57200
57248
  // TODO: Rename OPEN -> LEFT and CLOSE -> RIGHT in v5 to fit with Unicode names
@@ -57254,6 +57302,8 @@ img.ProseMirror-separator {
57254
57302
  __proto__: null,
57255
57303
  WORD: WORD,
57256
57304
  UWORD: UWORD,
57305
+ ASCIINUMERICAL: ASCIINUMERICAL,
57306
+ ALPHANUMERICAL: ALPHANUMERICAL,
57257
57307
  LOCALHOST: LOCALHOST,
57258
57308
  TLD: TLD,
57259
57309
  UTLD: UTLD,
@@ -57261,7 +57311,7 @@ img.ProseMirror-separator {
57261
57311
  SLASH_SCHEME: SLASH_SCHEME,
57262
57312
  NUM: NUM,
57263
57313
  WS: WS,
57264
- NL: NL$1,
57314
+ NL: NL,
57265
57315
  OPENBRACE: OPENBRACE,
57266
57316
  CLOSEBRACE: CLOSEBRACE,
57267
57317
  OPENBRACKET: OPENBRACKET,
@@ -57318,9 +57368,11 @@ img.ProseMirror-separator {
57318
57368
  The scanner provides an interface that takes a string of text as input, and
57319
57369
  outputs an array of tokens instances that can be used for easy URL parsing.
57320
57370
  */
57321
- const NL = '\n'; // New line character
57371
+ const CR = '\r'; // carriage-return character
57372
+ const LF = '\n'; // line-feed character
57322
57373
  const EMOJI_VARIATION = '\ufe0f'; // Variation selector, follows heart and others
57323
57374
  const EMOJI_JOINER = '\u200d'; // zero-width joiner
57375
+ const OBJECT_REPLACEMENT = '\ufffc'; // whitespace placeholder that sometimes appears in rich text editors
57324
57376
 
57325
57377
  let tlds = null,
57326
57378
  utlds = null; // don't change so only have to be computed once
@@ -57406,49 +57458,73 @@ img.ProseMirror-separator {
57406
57458
  [numeric]: true
57407
57459
  });
57408
57460
  tr(Num, DIGIT, Num);
57461
+ const Asciinumeric = tr(Num, ASCII_LETTER, ASCIINUMERICAL, {
57462
+ [asciinumeric]: true
57463
+ });
57464
+ const Alphanumeric = tr(Num, LETTER, ALPHANUMERICAL, {
57465
+ [alphanumeric$1]: true
57466
+ });
57409
57467
 
57410
57468
  // State which emits a word token
57411
57469
  const Word = tr(Start, ASCII_LETTER, WORD, {
57412
57470
  [ascii]: true
57413
57471
  });
57472
+ tr(Word, DIGIT, Asciinumeric);
57414
57473
  tr(Word, ASCII_LETTER, Word);
57474
+ tr(Asciinumeric, DIGIT, Asciinumeric);
57475
+ tr(Asciinumeric, ASCII_LETTER, Asciinumeric);
57415
57476
 
57416
57477
  // Same as previous, but specific to non-fsm.ascii alphabet words
57417
57478
  const UWord = tr(Start, LETTER, UWORD, {
57418
57479
  [alpha]: true
57419
57480
  });
57420
57481
  tr(UWord, ASCII_LETTER); // Non-accepting
57482
+ tr(UWord, DIGIT, Alphanumeric);
57421
57483
  tr(UWord, LETTER, UWord);
57484
+ tr(Alphanumeric, DIGIT, Alphanumeric);
57485
+ tr(Alphanumeric, ASCII_LETTER); // Non-accepting
57486
+ tr(Alphanumeric, LETTER, Alphanumeric); // Non-accepting
57422
57487
 
57423
57488
  // Whitespace jumps
57424
57489
  // Tokens of only non-newline whitespace are arbitrarily long
57425
57490
  // If any whitespace except newline, more whitespace!
57426
- const Ws = tr(Start, SPACE, WS, {
57491
+ const Nl = tt(Start, LF, NL, {
57492
+ [whitespace]: true
57493
+ });
57494
+ const Cr = tt(Start, CR, WS, {
57427
57495
  [whitespace]: true
57428
57496
  });
57429
- tt(Start, NL, NL$1, {
57497
+ const Ws = tr(Start, SPACE, WS, {
57430
57498
  [whitespace]: true
57431
57499
  });
57432
- tt(Ws, NL); // non-accepting state to avoid mixing whitespaces
57500
+ tt(Start, OBJECT_REPLACEMENT, Ws);
57501
+ tt(Cr, LF, Nl); // \r\n
57502
+ tt(Cr, OBJECT_REPLACEMENT, Ws);
57503
+ tr(Cr, SPACE, Ws);
57504
+ tt(Ws, CR); // non-accepting state to avoid mixing whitespaces
57505
+ tt(Ws, LF); // non-accepting state to avoid mixing whitespaces
57433
57506
  tr(Ws, SPACE, Ws);
57507
+ tt(Ws, OBJECT_REPLACEMENT, Ws);
57434
57508
 
57435
57509
  // Emoji tokens. They are not grouped by the scanner except in cases where a
57436
57510
  // zero-width joiner is present
57437
57511
  const Emoji = tr(Start, EMOJI, EMOJI$1, {
57438
57512
  [emoji]: true
57439
57513
  });
57514
+ tt(Emoji, '#'); // no transition, emoji regex seems to match #
57440
57515
  tr(Emoji, EMOJI, Emoji);
57441
57516
  tt(Emoji, EMOJI_VARIATION, Emoji);
57442
57517
  // tt(Start, EMOJI_VARIATION, Emoji); // This one is sketchy
57443
57518
 
57444
57519
  const EmojiJoiner = tt(Emoji, EMOJI_JOINER);
57520
+ tt(EmojiJoiner, '#');
57445
57521
  tr(EmojiJoiner, EMOJI, Emoji);
57446
57522
  // tt(EmojiJoiner, EMOJI_VARIATION, Emoji); // also sketchy
57447
57523
 
57448
57524
  // Generates states for top-level domains
57449
57525
  // Note that this is most accurate when tlds are in alphabetical order
57450
- const wordjr = [[ASCII_LETTER, Word]];
57451
- const uwordjr = [[ASCII_LETTER, null], [LETTER, UWord]];
57526
+ const wordjr = [[ASCII_LETTER, Word], [DIGIT, Asciinumeric]];
57527
+ const uwordjr = [[ASCII_LETTER, null], [LETTER, UWord], [DIGIT, Alphanumeric]];
57452
57528
  for (let i = 0; i < tlds.length; i++) {
57453
57529
  fastts(Start, tlds[i], TLD, WORD, wordjr);
57454
57530
  }
@@ -58137,7 +58213,7 @@ img.ProseMirror-separator {
58137
58213
  // Types of tokens that can follow a URL and be part of the query string
58138
58214
  // but cannot be the very last characters
58139
58215
  // Characters that cannot appear in the URL at all should be excluded
58140
- const qsNonAccepting = [APOSTROPHE, COLON, COMMA, DOT, EXCLAMATION, QUERY, QUOTE, SEMI, OPENANGLEBRACKET, CLOSEANGLEBRACKET, OPENBRACE, CLOSEBRACE, CLOSEBRACKET, OPENBRACKET, OPENPAREN, CLOSEPAREN, FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN, LEFTCORNERBRACKET, RIGHTCORNERBRACKET, LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET, FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN];
58216
+ const qsNonAccepting = [COLON, COMMA, DOT, EXCLAMATION, PERCENT, QUERY, QUOTE, SEMI, OPENANGLEBRACKET, CLOSEANGLEBRACKET, OPENBRACE, CLOSEBRACE, CLOSEBRACKET, OPENBRACKET, OPENPAREN, CLOSEPAREN, FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN, LEFTCORNERBRACKET, RIGHTCORNERBRACKET, LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET, FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN];
58141
58217
 
58142
58218
  // For addresses without the mailto prefix
58143
58219
  // Tokens allowed in the localpart of the email
@@ -58182,6 +58258,7 @@ img.ProseMirror-separator {
58182
58258
 
58183
58259
  // Hyphen can jump back to a domain name
58184
58260
  const EmailDomainHyphen = tt(EmailDomain, HYPHEN); // parsed string starts with local email info + @ with a potential domain name
58261
+ tt(EmailDomainHyphen, HYPHEN, EmailDomainHyphen);
58185
58262
  ta(EmailDomainHyphen, groups.domain, EmailDomain);
58186
58263
  ta(Email$1, groups.domain, EmailDomain);
58187
58264
  tt(Email$1, DOT, EmailDomainDot);
@@ -58196,6 +58273,7 @@ img.ProseMirror-separator {
58196
58273
  // (but not TLDs)
58197
58274
  const DomainHyphen = tt(Domain, HYPHEN); // domain followed by hyphen
58198
58275
  const DomainDot = tt(Domain, DOT); // domain followed by DOT
58276
+ tt(DomainHyphen, HYPHEN, DomainHyphen);
58199
58277
  ta(DomainHyphen, groups.domain, Domain);
58200
58278
  ta(DomainDot, localpartAccepting, Localpart);
58201
58279
  ta(DomainDot, groups.domain, Domain);
@@ -58246,6 +58324,7 @@ img.ProseMirror-separator {
58246
58324
  // Force URL with scheme prefix followed by anything sane
58247
58325
  ta(SchemeColon, groups.domain, Url$1);
58248
58326
  tt(SchemeColon, SLASH, Url$1);
58327
+ tt(SchemeColon, QUERY, Url$1);
58249
58328
  ta(UriPrefix, groups.domain, Url$1);
58250
58329
  ta(UriPrefix, qsAccepting, Url$1);
58251
58330
  tt(UriPrefix, SLASH, Url$1);
@@ -58294,7 +58373,7 @@ img.ProseMirror-separator {
58294
58373
  tt(UrlOpenSyms, CLOSE, Url$1);
58295
58374
  }
58296
58375
  tt(Start, LOCALHOST, DomainDotTld); // localhost is a valid URL state
58297
- tt(Start, NL$1, Nl); // single new line
58376
+ tt(Start, NL, Nl); // single new line
58298
58377
 
58299
58378
  return {
58300
58379
  start: Start,
@@ -58449,7 +58528,7 @@ img.ProseMirror-separator {
58449
58528
  * Detect URLs with the following additional protocol. Anything with format
58450
58529
  * "protocol://..." will be considered a link. If `optionalSlashSlash` is set to
58451
58530
  * `true`, anything with format "protocol:..." will be considered a link.
58452
- * @param {string} protocol
58531
+ * @param {string} scheme
58453
58532
  * @param {boolean} [optionalSlashSlash]
58454
58533
  */
58455
58534
  function registerCustomProtocol(scheme, optionalSlashSlash = false) {
@@ -58843,9 +58922,25 @@ img.ProseMirror-separator {
58843
58922
  addCommands() {
58844
58923
  return {
58845
58924
  setLink: attributes => ({ chain }) => {
58925
+ const { href } = attributes;
58926
+ if (!this.options.isAllowedUri(href, {
58927
+ defaultValidate: url => !!isAllowedUri(url, this.options.protocols),
58928
+ protocols: this.options.protocols,
58929
+ defaultProtocol: this.options.defaultProtocol,
58930
+ })) {
58931
+ return false;
58932
+ }
58846
58933
  return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run();
58847
58934
  },
58848
58935
  toggleLink: attributes => ({ chain }) => {
58936
+ const { href } = attributes;
58937
+ if (!this.options.isAllowedUri(href, {
58938
+ defaultValidate: url => !!isAllowedUri(url, this.options.protocols),
58939
+ protocols: this.options.protocols,
58940
+ defaultProtocol: this.options.defaultProtocol,
58941
+ })) {
58942
+ return false;
58943
+ }
58849
58944
  return chain()
58850
58945
  .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })
58851
58946
  .setMeta('preventAutolink', true)
@@ -58961,13 +59056,15 @@ img.ProseMirror-separator {
58961
59056
 
58962
59057
  function findSuggestionMatch(config) {
58963
59058
  var _a;
58964
- const { char, allowSpaces, allowedPrefixes, startOfLine, $position, } = config;
59059
+ const { char, allowSpaces: allowSpacesOption, allowToIncludeChar, allowedPrefixes, startOfLine, $position, } = config;
59060
+ const allowSpaces = allowSpacesOption && !allowToIncludeChar;
58965
59061
  const escapedChar = escapeForRegEx(char);
58966
59062
  const suffix = new RegExp(`\\s${escapedChar}$`);
58967
59063
  const prefix = startOfLine ? '^' : '';
59064
+ const finalEscapedChar = allowToIncludeChar ? '' : escapedChar;
58968
59065
  const regexp = allowSpaces
58969
- ? new RegExp(`${prefix}${escapedChar}.*?(?=\\s${escapedChar}|$)`, 'gm')
58970
- : new RegExp(`${prefix}(?:^)?${escapedChar}[^\\s${escapedChar}]*`, 'gm');
59066
+ ? new RegExp(`${prefix}${escapedChar}.*?(?=\\s${finalEscapedChar}|$)`, 'gm')
59067
+ : new RegExp(`${prefix}(?:^)?${escapedChar}[^\\s${finalEscapedChar}]*`, 'gm');
58971
59068
  const text = ((_a = $position.nodeBefore) === null || _a === void 0 ? void 0 : _a.isText) && $position.nodeBefore.text;
58972
59069
  if (!text) {
58973
59070
  return null;
@@ -59012,7 +59109,7 @@ img.ProseMirror-separator {
59012
59109
  * This utility allows you to create suggestions.
59013
59110
  * @see https://tiptap.dev/api/utilities/suggestion
59014
59111
  */
59015
- function Suggestion({ pluginKey = SuggestionPluginKey, editor, char = '@', allowSpaces = false, allowedPrefixes = [' '], startOfLine = false, decorationTag = 'span', decorationClass = 'suggestion', command = () => null, items = () => [], render = () => ({}), allow = () => true, findSuggestionMatch: findSuggestionMatch$1 = findSuggestionMatch, }) {
59112
+ function Suggestion({ pluginKey = SuggestionPluginKey, editor, char = '@', allowSpaces = false, allowToIncludeChar = false, allowedPrefixes = [' '], startOfLine = false, decorationTag = 'span', decorationClass = 'suggestion', command = () => null, items = () => [], render = () => ({}), allow = () => true, findSuggestionMatch: findSuggestionMatch$1 = findSuggestionMatch, }) {
59016
59113
  let props;
59017
59114
  const renderer = render === null || render === void 0 ? void 0 : render();
59018
59115
  const plugin = new Plugin({
@@ -59129,6 +59226,7 @@ img.ProseMirror-separator {
59129
59226
  const match = findSuggestionMatch$1({
59130
59227
  char,
59131
59228
  allowSpaces,
59229
+ allowToIncludeChar,
59132
59230
  allowedPrefixes,
59133
59231
  startOfLine,
59134
59232
  $position: selection.$from,
@@ -59864,7 +59962,7 @@ img.ProseMirror-separator {
59864
59962
  /**
59865
59963
  * A nimble styled rich text editor
59866
59964
  */
59867
- class RichTextEditor extends RichText {
59965
+ class RichTextEditor extends mixinErrorPattern(RichText) {
59868
59966
  constructor() {
59869
59967
  super(...arguments);
59870
59968
  /**
@@ -59897,13 +59995,6 @@ img.ProseMirror-separator {
59897
59995
  * HTML Attribute: footer-hidden
59898
59996
  */
59899
59997
  this.footerHidden = false;
59900
- /**
59901
- * Whether to display the error state.
59902
- *
59903
- * @public
59904
- * HTML Attribute: error-visible
59905
- */
59906
- this.errorVisible = false;
59907
59998
  /**
59908
59999
  * The width of the vertical scrollbar, if displayed.
59909
60000
  * @internal
@@ -60374,12 +60465,6 @@ img.ProseMirror-separator {
60374
60465
  __decorate$1([
60375
60466
  attr({ attribute: 'footer-hidden', mode: 'boolean' })
60376
60467
  ], RichTextEditor.prototype, "footerHidden", void 0);
60377
- __decorate$1([
60378
- attr({ attribute: 'error-visible', mode: 'boolean' })
60379
- ], RichTextEditor.prototype, "errorVisible", void 0);
60380
- __decorate$1([
60381
- attr({ attribute: 'error-text' })
60382
- ], RichTextEditor.prototype, "errorText", void 0);
60383
60468
  __decorate$1([
60384
60469
  attr
60385
60470
  ], RichTextEditor.prototype, "placeholder", void 0);
@@ -61094,11 +61179,10 @@ img.ProseMirror-separator {
61094
61179
  /**
61095
61180
  * A nimble-styled HTML select.
61096
61181
  */
61097
- class Select extends FormAssociatedSelect {
61182
+ class Select extends mixinErrorPattern(FormAssociatedSelect) {
61098
61183
  constructor() {
61099
61184
  super(...arguments);
61100
61185
  this.appearance = DropdownAppearance.underline;
61101
- this.errorVisible = false;
61102
61186
  this.filterMode = FilterMode.none;
61103
61187
  this.clearable = false;
61104
61188
  this.loadingVisible = false;
@@ -62087,12 +62171,6 @@ img.ProseMirror-separator {
62087
62171
  __decorate$1([
62088
62172
  attr({ attribute: 'position' })
62089
62173
  ], Select.prototype, "positionAttribute", void 0);
62090
- __decorate$1([
62091
- attr({ attribute: 'error-text' })
62092
- ], Select.prototype, "errorText", void 0);
62093
- __decorate$1([
62094
- attr({ attribute: 'error-visible', mode: 'boolean' })
62095
- ], Select.prototype, "errorVisible", void 0);
62096
62174
  __decorate$1([
62097
62175
  attr({ attribute: 'filter-mode' })
62098
62176
  ], Select.prototype, "filterMode", void 0);
@@ -68312,20 +68390,12 @@ focus outline in that case.
68312
68390
  const size = this.getSize();
68313
68391
  const scrollOffset = this.getScrollOffset();
68314
68392
  if (align === "auto") {
68315
- if (toOffset <= scrollOffset) {
68316
- align = "start";
68317
- } else if (toOffset >= scrollOffset + size) {
68393
+ if (toOffset >= scrollOffset + size) {
68318
68394
  align = "end";
68319
- } else {
68320
- align = "start";
68321
68395
  }
68322
68396
  }
68323
- if (align === "start") {
68324
- toOffset = toOffset;
68325
- } else if (align === "end") {
68326
- toOffset = toOffset - size;
68327
- } else if (align === "center") {
68328
- toOffset = toOffset - size / 2;
68397
+ if (align === "end") {
68398
+ toOffset -= size;
68329
68399
  }
68330
68400
  const scrollSizeProp = this.options.horizontal ? "scrollWidth" : "scrollHeight";
68331
68401
  const scrollSize = this.scrollElement ? "document" in this.scrollElement ? this.scrollElement.document.documentElement[scrollSizeProp] : this.scrollElement[scrollSizeProp] : 0;
@@ -68349,8 +68419,27 @@ focus outline in that case.
68349
68419
  return [scrollOffset, align];
68350
68420
  }
68351
68421
  }
68352
- const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
68353
- return [this.getOffsetForAlignment(toOffset, align), align];
68422
+ const centerOffset = item.start - this.options.scrollPaddingStart + (item.size - size) / 2;
68423
+ switch (align) {
68424
+ case "center":
68425
+ return [this.getOffsetForAlignment(centerOffset, align), align];
68426
+ case "end":
68427
+ return [
68428
+ this.getOffsetForAlignment(
68429
+ item.end + this.options.scrollPaddingEnd,
68430
+ align
68431
+ ),
68432
+ align
68433
+ ];
68434
+ default:
68435
+ return [
68436
+ this.getOffsetForAlignment(
68437
+ item.start - this.options.scrollPaddingStart,
68438
+ align
68439
+ ),
68440
+ align
68441
+ ];
68442
+ }
68354
68443
  };
68355
68444
  this.isDynamicMode = () => this.elementsCache.size > 0;
68356
68445
  this.cancelScrollToIndex = () => {
@@ -74605,7 +74694,7 @@ focus outline in that case.
74605
74694
  /**
74606
74695
  * A nimble-styed HTML text area
74607
74696
  */
74608
- class TextArea extends TextArea$1 {
74697
+ class TextArea extends mixinErrorPattern(TextArea$1) {
74609
74698
  constructor() {
74610
74699
  super(...arguments);
74611
74700
  /**
@@ -74616,14 +74705,6 @@ focus outline in that case.
74616
74705
  * HTML Attribute: appearance
74617
74706
  */
74618
74707
  this.appearance = TextAreaAppearance.outline;
74619
- /**
74620
- * Whether to display the error state.
74621
- *
74622
- * @public
74623
- * @remarks
74624
- * HTML Attribute: error-visible
74625
- */
74626
- this.errorVisible = false;
74627
74708
  /**
74628
74709
  * The width of the vertical scrollbar, if displayed.
74629
74710
  * @internal
@@ -74694,12 +74775,6 @@ focus outline in that case.
74694
74775
  __decorate$1([
74695
74776
  attr
74696
74777
  ], TextArea.prototype, "appearance", void 0);
74697
- __decorate$1([
74698
- attr({ attribute: 'error-text' })
74699
- ], TextArea.prototype, "errorText", void 0);
74700
- __decorate$1([
74701
- attr({ attribute: 'error-visible', mode: 'boolean' })
74702
- ], TextArea.prototype, "errorVisible", void 0);
74703
74778
  __decorate$1([
74704
74779
  observable
74705
74780
  ], TextArea.prototype, "scrollbarWidth", void 0);
@@ -74966,7 +75041,7 @@ focus outline in that case.
74966
75041
  /**
74967
75042
  * A nimble-styed HTML text input
74968
75043
  */
74969
- class TextField extends TextField$1 {
75044
+ class TextField extends mixinErrorPattern(TextField$1) {
74970
75045
  constructor() {
74971
75046
  super(...arguments);
74972
75047
  /**
@@ -74977,19 +75052,12 @@ focus outline in that case.
74977
75052
  * HTML Attribute: appearance
74978
75053
  */
74979
75054
  this.appearance = TextFieldAppearance.underline;
74980
- this.errorVisible = false;
74981
75055
  this.fullBleed = false;
74982
75056
  }
74983
75057
  }
74984
75058
  __decorate$1([
74985
75059
  attr
74986
75060
  ], TextField.prototype, "appearance", void 0);
74987
- __decorate$1([
74988
- attr({ attribute: 'error-text' })
74989
- ], TextField.prototype, "errorText", void 0);
74990
- __decorate$1([
74991
- attr({ attribute: 'error-visible', mode: 'boolean' })
74992
- ], TextField.prototype, "errorVisible", void 0);
74993
75061
  __decorate$1([
74994
75062
  attr({ attribute: 'full-bleed', mode: 'boolean' })
74995
75063
  ], TextField.prototype, "fullBleed", void 0);