@nectary/components 5.31.2 → 5.31.4

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.
package/bundle.js CHANGED
@@ -1418,7 +1418,7 @@ class RichTextareaChip extends NectaryElement {
1418
1418
  };
1419
1419
  }
1420
1420
  defineCustomElement("sinch-rich-textarea-chip", RichTextareaChip);
1421
- const regLinebreak = /(?:<br>\n|<br>|\n)/;
1421
+ const regLinebreak = /(?:<br>\n|<br>| {2,}\n|\n)/;
1422
1422
  const regParagraph = /\n{2,}/;
1423
1423
  const regEm3Star = new RegExp("(?<!\\\\)\\*\\*\\*(?<em3>.+?)(?<!\\\\)\\*\\*\\*");
1424
1424
  const regEm2Star = new RegExp("(?<!\\\\)\\*\\*(?<em2>.+?)(?<!\\\\)\\*\\*");
@@ -4059,6 +4059,7 @@ class Tooltip extends NectaryElement {
4059
4059
  this.#schedulePlacement();
4060
4060
  });
4061
4061
  this.#resizeObserver.observe(this.#$content);
4062
+ window.addEventListener("resize", this.#onWindowResize, options);
4062
4063
  updateAttribute(this.#$pop, "orientation", getPopOrientation$1(this.orientation));
4063
4064
  updateBooleanAttribute(this.#$pop, "hide-outside-viewport", !this.showOutsideViewport);
4064
4065
  updateBooleanAttribute(this.#$pop, "disable-focus-restore", true);
@@ -4524,6 +4525,14 @@ class Tooltip extends NectaryElement {
4524
4525
  this.#$pop.style.removeProperty("--sinch-pop-offset-x");
4525
4526
  this.#$pop.style.removeProperty("--sinch-pop-offset-y");
4526
4527
  }
4528
+ #onWindowResize = () => {
4529
+ if (!this.#isOpen()) {
4530
+ return;
4531
+ }
4532
+ requestAnimationFrame(() => {
4533
+ this.#schedulePlacement();
4534
+ });
4535
+ };
4527
4536
  #schedulePlacement(resetZeroDimensionRetries = true) {
4528
4537
  if (!this.#isOpen() || this.#placementScheduled) {
4529
4538
  return;
@@ -11357,7 +11366,6 @@ const MD_EM1_STAR_TOKEN = "*";
11357
11366
  const MD_EM3_UNDERSCORE_TOKEN = "___";
11358
11367
  const MD_EM2_UNDERSCORE_TOKEN = "__";
11359
11368
  const MD_EM1_UNDERSCORE_TOKEN = "_";
11360
- const MD_LINEBREAK_TOKEN = " \n";
11361
11369
  const MD_CODETAG_TOKEN = "`";
11362
11370
  const MD_ULISTITEM_TOKEN = "*";
11363
11371
  const MD_OLISTITEM_TOKEN = "1.";
@@ -11484,11 +11492,7 @@ const serializeRoot = ($root, range) => {
11484
11492
  };
11485
11493
  const flushParagraphChunks = () => {
11486
11494
  if (paragraphChunks.length > 0) {
11487
- chunks.push(
11488
- paragraphChunks.reduce((a, b) => {
11489
- return b.length > 0 ? a.concat(MD_LINEBREAK_TOKEN, b) : a.concat("<br>");
11490
- })
11491
- );
11495
+ chunks.push(...paragraphChunks);
11492
11496
  paragraphChunks.length = 0;
11493
11497
  }
11494
11498
  };
@@ -12971,7 +12975,6 @@ defineCustomElement("sinch-select-menu-option", SelectMenuOption);
12971
12975
  const isSelectMenuOption = (el) => el.localName === "sinch-select-menu-option";
12972
12976
  const templateHTML$h = '<style>:host{display:block;outline:0}#listbox{overflow-y:auto;max-height:var(--sinch-comp-select-menu-font-max-height)}#search{display:none;margin:10px}#search.active{display:block}#search-clear:not(.active){display:none}#not-found{display:flex;align-items:center;justify-content:center;width:100%;height:30px;margin-bottom:10px;pointer-events:none;user-select:none;--sinch-comp-text-font:var(--sinch-comp-select-menu-font-not-found-text);--sinch-global-color-text:var(--sinch-comp-select-menu-color-default-not-found-text-initial)}#not-found:not(.active){display:none}::slotted(.hidden){display:none}::slotted(sinch-title){padding:8px 16px;--sinch-global-color-text:var(--sinch-comp-select-menu-color-default-title-initial)}</style><sinch-input id="search" size="s" placeholder="Search"><sinch-icon icons-version="2" name="magnifying-glass" id="icon-search" slot="icon"></sinch-icon><sinch-button id="search-clear" slot="right"><sinch-icon icons-version="2" name="fa-xmark" slot="icon"></sinch-icon></sinch-button></sinch-input><div id="not-found"><sinch-text type="m">No results</sinch-text></div><div id="listbox" role="presentation"><slot></slot></div>';
12973
12977
  const ITEM_HEIGHT = 40;
12974
- const NUM_ITEMS_SEARCH = 7;
12975
12978
  const template$h = document.createElement("template");
12976
12979
  template$h.innerHTML = templateHTML$h;
12977
12980
  class SelectMenu extends NectaryElement {
@@ -13072,6 +13075,7 @@ class SelectMenu extends NectaryElement {
13072
13075
  "value",
13073
13076
  "rows",
13074
13077
  "multiple",
13078
+ "searchable",
13075
13079
  "search-value",
13076
13080
  "search-placeholder",
13077
13081
  "search-autocomplete"
@@ -13089,6 +13093,10 @@ class SelectMenu extends NectaryElement {
13089
13093
  this.#internals.ariaMultiSelectable = isAttrTrue(newVal).toString();
13090
13094
  break;
13091
13095
  }
13096
+ case "searchable": {
13097
+ this.#onOptionSlotChange();
13098
+ break;
13099
+ }
13092
13100
  case "search-autocomplete": {
13093
13101
  updateAttribute(this.#$search, "autocomplete", newVal);
13094
13102
  break;
@@ -13098,13 +13106,7 @@ class SelectMenu extends NectaryElement {
13098
13106
  break;
13099
13107
  }
13100
13108
  case "rows": {
13101
- const numberOfItems = this.#$optionSlot.assignedElements().length;
13102
- const maxNumberOfRows = parseInt(newVal ?? "0", 10);
13103
- this.#$listbox.style.maxHeight = attrValueToPixels(newVal, {
13104
- min: 2,
13105
- itemSizeMultiplier: ITEM_HEIGHT,
13106
- addExtraSpace: numberOfItems > maxNumberOfRows
13107
- });
13109
+ this.#updateListboxMaxHeight();
13108
13110
  break;
13109
13111
  }
13110
13112
  case "search-placeholder": {
@@ -13144,7 +13146,13 @@ class SelectMenu extends NectaryElement {
13144
13146
  return getBooleanAttribute(this, "multiple");
13145
13147
  }
13146
13148
  set searchable(isSearchable) {
13147
- updateBooleanAttribute(this, "searchable", isSearchable);
13149
+ if (isSearchable === false) {
13150
+ this.setAttribute("searchable", "false");
13151
+ } else if (isSearchable === true) {
13152
+ updateBooleanAttribute(this, "searchable", true);
13153
+ } else {
13154
+ this.removeAttribute("searchable");
13155
+ }
13148
13156
  }
13149
13157
  get searchable() {
13150
13158
  const searchableAttribute = this.getAttribute("searchable");
@@ -13230,7 +13238,7 @@ class SelectMenu extends NectaryElement {
13230
13238
  someFound ||= !isHidden;
13231
13239
  setClass($opt, "hidden", isHidden);
13232
13240
  }
13233
- setClass(this.#$notFound, "active", !someFound);
13241
+ setClass(this.#$notFound, "active", searchValue.length > 0 && !someFound);
13234
13242
  this.#selectOption(null);
13235
13243
  };
13236
13244
  #onContextKeyDown = (e) => {
@@ -13278,16 +13286,27 @@ class SelectMenu extends NectaryElement {
13278
13286
  }
13279
13287
  };
13280
13288
  #onOptionSlotChange = () => {
13289
+ if (this.hasAttribute("rows")) {
13290
+ this.#updateListboxMaxHeight();
13291
+ }
13281
13292
  const searchable = this.searchable;
13282
- const options = this.#getOptionElements();
13283
- const isEnoughOptions = options.length >= NUM_ITEMS_SEARCH;
13284
- const isSearchActive = isEnoughOptions && searchable !== false || Boolean(searchable);
13293
+ const isSearchActive = searchable !== false;
13285
13294
  if (!isSearchActive) {
13286
13295
  updateAttribute(this.#$search, "value", null);
13287
13296
  }
13288
13297
  setClass(this.#$search, "active", isSearchActive);
13289
13298
  this.#onValueChange(this.value);
13290
13299
  };
13300
+ #updateListboxMaxHeight = () => {
13301
+ const rowsAttr = this.getAttribute("rows");
13302
+ const numberOfItems = this.#$optionSlot.assignedElements().length;
13303
+ const maxNumberOfRows = parseInt(rowsAttr ?? "0", 10);
13304
+ this.#$listbox.style.maxHeight = attrValueToPixels(rowsAttr, {
13305
+ min: 2,
13306
+ itemSizeMultiplier: ITEM_HEIGHT,
13307
+ addExtraSpace: numberOfItems > maxNumberOfRows
13308
+ });
13309
+ };
13291
13310
  #onValueChange(csv) {
13292
13311
  if (this.multiple) {
13293
13312
  const values = unpackCsv(csv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nectary/components",
3
- "version": "5.31.2",
3
+ "version": "5.31.4",
4
4
  "files": [
5
5
  "**/*/*.css",
6
6
  "**/*/*.json",
@@ -1571,7 +1571,6 @@ const MD_EM1_STAR_TOKEN = "*";
1571
1571
  const MD_EM3_UNDERSCORE_TOKEN = "___";
1572
1572
  const MD_EM2_UNDERSCORE_TOKEN = "__";
1573
1573
  const MD_EM1_UNDERSCORE_TOKEN = "_";
1574
- const MD_LINEBREAK_TOKEN = " \n";
1575
1574
  const MD_CODETAG_TOKEN = "`";
1576
1575
  const MD_ULISTITEM_TOKEN = "*";
1577
1576
  const MD_OLISTITEM_TOKEN = "1.";
@@ -1698,11 +1697,7 @@ const serializeRoot = ($root, range) => {
1698
1697
  };
1699
1698
  const flushParagraphChunks = () => {
1700
1699
  if (paragraphChunks.length > 0) {
1701
- chunks.push(
1702
- paragraphChunks.reduce((a, b) => {
1703
- return b.length > 0 ? a.concat(MD_LINEBREAK_TOKEN, b) : a.concat("<br>");
1704
- })
1705
- );
1700
+ chunks.push(...paragraphChunks);
1706
1701
  paragraphChunks.length = 0;
1707
1702
  }
1708
1703
  };
@@ -22,8 +22,8 @@ export declare class SelectMenu extends NectaryElement {
22
22
  get rows(): number | null;
23
23
  set multiple(isMultiple: boolean);
24
24
  get multiple(): boolean;
25
- set searchable(isSearchable: boolean | null);
26
- get searchable(): boolean | null;
25
+ set searchable(isSearchable: boolean | null | undefined);
26
+ get searchable(): boolean | null | undefined;
27
27
  set 'search-autocomplete'(autocomplete: string);
28
28
  get 'search-autocomplete'(): string;
29
29
  set 'search-placeholder'(placeholder: string);
@@ -4,7 +4,7 @@ import "../text/index.js";
4
4
  import { isSelectMenuOption } from "../select-menu-option/utils.js";
5
5
  import { subscribeContext } from "../utils/context.js";
6
6
  import { unpackCsv, getFirstCsvValue, updateCsv } from "../utils/csv.js";
7
- import { getBooleanAttribute, updateAttribute, attrValueToPixels, updateExplicitBooleanAttribute, isAttrTrue, getAttribute, updateIntegerAttribute, getIntegerAttribute, updateBooleanAttribute, hasClass, setClass } from "../utils/dom.js";
7
+ import { getBooleanAttribute, updateAttribute, updateExplicitBooleanAttribute, isAttrTrue, getAttribute, updateIntegerAttribute, getIntegerAttribute, updateBooleanAttribute, hasClass, setClass, attrValueToPixels } from "../utils/dom.js";
8
8
  import { defineCustomElement, NectaryElement } from "../utils/element.js";
9
9
  import { debounceTimeout } from "../utils/debounce.js";
10
10
  import { getReactEventHandler } from "../utils/get-react-event-handler.js";
@@ -12,7 +12,6 @@ import { isTargetEqual } from "../utils/event-target.js";
12
12
  import { setFormValue, CSVToFormData } from "../utils/form.js";
13
13
  const templateHTML = '<style>:host{display:block;outline:0}#listbox{overflow-y:auto;max-height:var(--sinch-comp-select-menu-font-max-height)}#search{display:none;margin:10px}#search.active{display:block}#search-clear:not(.active){display:none}#not-found{display:flex;align-items:center;justify-content:center;width:100%;height:30px;margin-bottom:10px;pointer-events:none;user-select:none;--sinch-comp-text-font:var(--sinch-comp-select-menu-font-not-found-text);--sinch-global-color-text:var(--sinch-comp-select-menu-color-default-not-found-text-initial)}#not-found:not(.active){display:none}::slotted(.hidden){display:none}::slotted(sinch-title){padding:8px 16px;--sinch-global-color-text:var(--sinch-comp-select-menu-color-default-title-initial)}</style><sinch-input id="search" size="s" placeholder="Search"><sinch-icon icons-version="2" name="magnifying-glass" id="icon-search" slot="icon"></sinch-icon><sinch-button id="search-clear" slot="right"><sinch-icon icons-version="2" name="fa-xmark" slot="icon"></sinch-icon></sinch-button></sinch-input><div id="not-found"><sinch-text type="m">No results</sinch-text></div><div id="listbox" role="presentation"><slot></slot></div>';
14
14
  const ITEM_HEIGHT = 40;
15
- const NUM_ITEMS_SEARCH = 7;
16
15
  const template = document.createElement("template");
17
16
  template.innerHTML = templateHTML;
18
17
  class SelectMenu extends NectaryElement {
@@ -113,6 +112,7 @@ class SelectMenu extends NectaryElement {
113
112
  "value",
114
113
  "rows",
115
114
  "multiple",
115
+ "searchable",
116
116
  "search-value",
117
117
  "search-placeholder",
118
118
  "search-autocomplete"
@@ -130,6 +130,10 @@ class SelectMenu extends NectaryElement {
130
130
  this.#internals.ariaMultiSelectable = isAttrTrue(newVal).toString();
131
131
  break;
132
132
  }
133
+ case "searchable": {
134
+ this.#onOptionSlotChange();
135
+ break;
136
+ }
133
137
  case "search-autocomplete": {
134
138
  updateAttribute(this.#$search, "autocomplete", newVal);
135
139
  break;
@@ -139,13 +143,7 @@ class SelectMenu extends NectaryElement {
139
143
  break;
140
144
  }
141
145
  case "rows": {
142
- const numberOfItems = this.#$optionSlot.assignedElements().length;
143
- const maxNumberOfRows = parseInt(newVal ?? "0", 10);
144
- this.#$listbox.style.maxHeight = attrValueToPixels(newVal, {
145
- min: 2,
146
- itemSizeMultiplier: ITEM_HEIGHT,
147
- addExtraSpace: numberOfItems > maxNumberOfRows
148
- });
146
+ this.#updateListboxMaxHeight();
149
147
  break;
150
148
  }
151
149
  case "search-placeholder": {
@@ -185,7 +183,13 @@ class SelectMenu extends NectaryElement {
185
183
  return getBooleanAttribute(this, "multiple");
186
184
  }
187
185
  set searchable(isSearchable) {
188
- updateBooleanAttribute(this, "searchable", isSearchable);
186
+ if (isSearchable === false) {
187
+ this.setAttribute("searchable", "false");
188
+ } else if (isSearchable === true) {
189
+ updateBooleanAttribute(this, "searchable", true);
190
+ } else {
191
+ this.removeAttribute("searchable");
192
+ }
189
193
  }
190
194
  get searchable() {
191
195
  const searchableAttribute = this.getAttribute("searchable");
@@ -271,7 +275,7 @@ class SelectMenu extends NectaryElement {
271
275
  someFound ||= !isHidden;
272
276
  setClass($opt, "hidden", isHidden);
273
277
  }
274
- setClass(this.#$notFound, "active", !someFound);
278
+ setClass(this.#$notFound, "active", searchValue.length > 0 && !someFound);
275
279
  this.#selectOption(null);
276
280
  };
277
281
  #onContextKeyDown = (e) => {
@@ -319,16 +323,27 @@ class SelectMenu extends NectaryElement {
319
323
  }
320
324
  };
321
325
  #onOptionSlotChange = () => {
326
+ if (this.hasAttribute("rows")) {
327
+ this.#updateListboxMaxHeight();
328
+ }
322
329
  const searchable = this.searchable;
323
- const options = this.#getOptionElements();
324
- const isEnoughOptions = options.length >= NUM_ITEMS_SEARCH;
325
- const isSearchActive = isEnoughOptions && searchable !== false || Boolean(searchable);
330
+ const isSearchActive = searchable !== false;
326
331
  if (!isSearchActive) {
327
332
  updateAttribute(this.#$search, "value", null);
328
333
  }
329
334
  setClass(this.#$search, "active", isSearchActive);
330
335
  this.#onValueChange(this.value);
331
336
  };
337
+ #updateListboxMaxHeight = () => {
338
+ const rowsAttr = this.getAttribute("rows");
339
+ const numberOfItems = this.#$optionSlot.assignedElements().length;
340
+ const maxNumberOfRows = parseInt(rowsAttr ?? "0", 10);
341
+ this.#$listbox.style.maxHeight = attrValueToPixels(rowsAttr, {
342
+ min: 2,
343
+ itemSizeMultiplier: ITEM_HEIGHT,
344
+ addExtraSpace: numberOfItems > maxNumberOfRows
345
+ });
346
+ };
332
347
  #onValueChange(csv) {
333
348
  if (this.multiple) {
334
349
  const values = unpackCsv(csv);
@@ -8,7 +8,7 @@ export type TSinchSelectMenuProps = {
8
8
  rows?: number;
9
9
  /** Allows multiple selection */
10
10
  multiple?: boolean;
11
- /** Enforce the search bar appearing, by default it appears above a certain number of options */
11
+ /** Show the search bar, shown by default unless explicitly set to false */
12
12
  searchable?: boolean | null;
13
13
  /** Value for the search input */
14
14
  'search-value'?: string;
package/tooltip/index.js CHANGED
@@ -83,6 +83,7 @@ class Tooltip extends NectaryElement {
83
83
  this.#schedulePlacement();
84
84
  });
85
85
  this.#resizeObserver.observe(this.#$content);
86
+ window.addEventListener("resize", this.#onWindowResize, options);
86
87
  updateAttribute(this.#$pop, "orientation", getPopOrientation(this.orientation));
87
88
  updateBooleanAttribute(this.#$pop, "hide-outside-viewport", !this.showOutsideViewport);
88
89
  updateBooleanAttribute(this.#$pop, "disable-focus-restore", true);
@@ -548,6 +549,14 @@ class Tooltip extends NectaryElement {
548
549
  this.#$pop.style.removeProperty("--sinch-pop-offset-x");
549
550
  this.#$pop.style.removeProperty("--sinch-pop-offset-y");
550
551
  }
552
+ #onWindowResize = () => {
553
+ if (!this.#isOpen()) {
554
+ return;
555
+ }
556
+ requestAnimationFrame(() => {
557
+ this.#schedulePlacement();
558
+ });
559
+ };
551
560
  #schedulePlacement(resetZeroDimensionRetries = true) {
552
561
  if (!this.#isOpen() || this.#placementScheduled) {
553
562
  return;
package/utils/markdown.js CHANGED
@@ -1,4 +1,4 @@
1
- const regLinebreak = /(?:<br>\n|<br>|\n)/;
1
+ const regLinebreak = /(?:<br>\n|<br>| {2,}\n|\n)/;
2
2
  const regParagraph = /\n{2,}/;
3
3
  const regEm3Star = new RegExp("(?<!\\\\)\\*\\*\\*(?<em3>.+?)(?<!\\\\)\\*\\*\\*");
4
4
  const regEm2Star = new RegExp("(?<!\\\\)\\*\\*(?<em2>.+?)(?<!\\\\)\\*\\*");