@vertexvis/ui 0.1.0-canary.13 → 0.1.0-canary.15

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 (43) hide show
  1. package/dist/cjs/{icon-88af577f.js → icon-b6383789.js} +1 -1
  2. package/dist/cjs/{icon-button-7b2ff7b0.js → icon-button-f32c3cc8.js} +1 -1
  3. package/dist/cjs/{icon-helper-af9f8c10.js → icon-helper-0e14d7cc.js} +5 -0
  4. package/dist/cjs/index.cjs.js +4 -4
  5. package/dist/cjs/{search-bar-91cbcd07.js → search-bar-2e7ee35a.js} +130 -24
  6. package/dist/cjs/vertex-icon-button.cjs.entry.js +2 -2
  7. package/dist/cjs/vertex-icon.cjs.entry.js +2 -2
  8. package/dist/cjs/vertex-search-bar.cjs.entry.js +1 -1
  9. package/dist/collection/components/icon/icon-helper.js +3 -0
  10. package/dist/collection/components/icon/icon.js +1 -1
  11. package/dist/collection/components/icon/icons/views.js +2 -0
  12. package/dist/collection/components/icon-button/icon-button.js +1 -1
  13. package/dist/collection/components/search-bar/dom.js +17 -0
  14. package/dist/collection/components/search-bar/lib.js +45 -4
  15. package/dist/collection/components/search-bar/search-bar.js +76 -23
  16. package/dist/collection/types/icon.js +1 -0
  17. package/dist/components/components.esm.js +1 -1
  18. package/dist/components/index.esm.js +1 -1
  19. package/dist/components/{p-a50d42cc.js → p-213670fa.js} +1 -1
  20. package/dist/components/{p-04449a31.js → p-438990ec.js} +1 -1
  21. package/dist/components/p-6a49c365.entry.js +1 -0
  22. package/dist/components/p-6b6c2260.js +1 -0
  23. package/dist/components/p-8567289c.entry.js +1 -0
  24. package/dist/components/{p-b11a0f6b.js → p-d51b8fb1.js} +1 -1
  25. package/dist/components/p-f100f918.entry.js +1 -0
  26. package/dist/esm/{icon-788d26c9.js → icon-74bf5afb.js} +1 -1
  27. package/dist/esm/{icon-button-4820c5f8.js → icon-button-d15ffd10.js} +1 -1
  28. package/dist/esm/{icon-helper-091fab53.js → icon-helper-805b317d.js} +5 -0
  29. package/dist/esm/index.js +4 -4
  30. package/dist/esm/{search-bar-f12a3599.js → search-bar-8d18626e.js} +130 -24
  31. package/dist/esm/vertex-icon-button.entry.js +2 -2
  32. package/dist/esm/vertex-icon.entry.js +2 -2
  33. package/dist/esm/vertex-search-bar.entry.js +1 -1
  34. package/dist/types/components/icon/icons/views.d.ts +3 -0
  35. package/dist/types/components/search-bar/dom.d.ts +5 -0
  36. package/dist/types/components/search-bar/lib.d.ts +9 -2
  37. package/dist/types/components/search-bar/search-bar.d.ts +1 -0
  38. package/dist/types/types/icon.d.ts +1 -0
  39. package/package.json +2 -2
  40. package/dist/components/p-b1da3f7e.entry.js +0 -1
  41. package/dist/components/p-b3548cdf.entry.js +0 -1
  42. package/dist/components/p-cfe369bf.entry.js +0 -1
  43. package/dist/components/p-db34f10c.js +0 -1
@@ -53,12 +53,24 @@ const getWindowSelection = () => {
53
53
  }
54
54
  return undefined;
55
55
  };
56
+ const nodeHasChildNodes = (node) => {
57
+ return node.hasChildNodes();
58
+ };
56
59
  const createDocumentRange = () => {
57
60
  return document.createRange();
58
61
  };
59
62
  const createTextNode = (text) => {
60
63
  return new Text(text);
61
64
  };
65
+ const createBreak = () => {
66
+ return document.createElement('br');
67
+ };
68
+ const isHtmlElement = (node) => {
69
+ return node instanceof HTMLElement;
70
+ };
71
+ const isBrElement = (node) => {
72
+ return node instanceof HTMLBRElement;
73
+ };
62
74
 
63
75
  const createResultUri = (result) => {
64
76
  return `${result.type}:${result.id}`;
@@ -69,15 +81,56 @@ const createSearchResultReplacement = (result, before, after) => {
69
81
  before: createTextNode(before),
70
82
  beforeSpace: createTextNode(createHairSpace()),
71
83
  result: createTextNode(urn),
72
- afterSpace: after != null ? createTextNode(createNoBreakSpace()) : undefined,
84
+ afterSpace: after != null
85
+ ? createTextNode(createNoBreakSpace())
86
+ : createTextNode(createHairSpace()),
73
87
  after: after != null ? createTextNode(after) : undefined,
74
88
  };
75
89
  };
76
- const getNodesForSearchResultReplacement = (replacement) => {
90
+ /**
91
+ * Newline characters and spaces are represented slightly differently within a
92
+ * content editable element between browsers. This method standardizes the
93
+ * representation of those characters to avoid having to write branching logic
94
+ * to support each individual browser.
95
+ */
96
+ const standardizeNewlinesAndSpaces = (node) => {
97
+ const content = node.textContent;
98
+ if (content === '\n') {
99
+ return [createBreak()];
100
+ }
101
+ else if (content != null && content.includes('\n')) {
102
+ const split = content.split('\n');
103
+ return split.reduce((res, substr, i) => {
104
+ const previous = split[i - 1];
105
+ // Ignore the empty string if the prior element was converted
106
+ // to a breaking element to prevent duplication of newlines.
107
+ if (substr === '' && previous !== '') {
108
+ return res;
109
+ }
110
+ return [
111
+ ...res,
112
+ // Standard spaces are not always respected with in `Text`
113
+ // elements when appended to a contenteditable element. This
114
+ // conversion preserves that spacing.
115
+ createTextNode(substr.replace(/ /g, createNoBreakSpace())),
116
+ createBreak(),
117
+ ];
118
+ }, []);
119
+ }
120
+ return [node];
121
+ };
122
+ const getNodesForSearchResultReplacement = (replacement, isBreaking = false) => {
77
123
  const keys = Object.keys(replacement);
78
- return keys
124
+ const replacementElements = keys
79
125
  .map((key) => replacement[key])
80
126
  .filter((node) => node != null);
127
+ // If the element is intended to replace a breaking element such
128
+ // as a `<div>` wrapper, a newline is required alongside the standard
129
+ // replacement elements.
130
+ if (isBreaking) {
131
+ return [createTextNode('\n'), ...replacementElements];
132
+ }
133
+ return replacementElements;
81
134
  };
82
135
  /**
83
136
  * We leverage a couple unique spaces to represent mentions, allowing for
@@ -112,13 +165,34 @@ const SearchBar = class {
112
165
  this.inputFocus = createEvent(this, "inputFocus", 7);
113
166
  this.inputBlur = createEvent(this, "inputBlur", 7);
114
167
  this.rawElements = [];
168
+ this.attemptReplaceElement = (child, other, replacement, isBreaking = false) => {
169
+ // In the case that the child we're evaluating has its own children
170
+ // (often a wrapper `<div>`), we want to evaluate whether any of its
171
+ // children is the target to replace.
172
+ if (nodeHasChildNodes(child) &&
173
+ Array.from(child.childNodes).some((c) => nodeHasChildNodes(c) || this.isIdenticalElement(c, other))) {
174
+ return Array.from(child.childNodes).reduce((res, c) => [
175
+ ...res,
176
+ ...this.attemptReplaceElement(c, other, replacement,
177
+ // If the element we're evaluating is a wrapper, we want to
178
+ // consider it a breaking element and add a newline to the
179
+ // replaced element only if the previous node is a `Text` node.
180
+ !isHtmlElement(child.previousSibling)),
181
+ ], []);
182
+ }
183
+ else {
184
+ return this.isIdenticalElement(child, other)
185
+ ? getNodesForSearchResultReplacement(replacement, isBreaking)
186
+ : [child];
187
+ }
188
+ };
115
189
  this.isIdenticalElement = (child, other) => {
116
190
  return (child === this.triggeredElement ||
117
191
  this.getTextContent(child) === this.getTextContent(other));
118
192
  };
119
193
  this.getTextContent = (node) => {
120
194
  var _a;
121
- if (node instanceof HTMLElement) {
195
+ if (isHtmlElement(node)) {
122
196
  return node.innerText;
123
197
  }
124
198
  return (_a = node.textContent) !== null && _a !== void 0 ? _a : '';
@@ -195,21 +269,54 @@ const SearchBar = class {
195
269
  selection.addRange(range);
196
270
  }
197
271
  };
198
- this.getContentAsString = () => {
199
- if (this.contentEl != null) {
200
- return trimNonstandardSpaces(Array.from(this.contentEl.childNodes).reduce((res, n) => {
272
+ this.getContentAsString = (element) => {
273
+ if (element != null) {
274
+ const res = trimNonstandardSpaces(Array.from(element.childNodes).reduce((res, n) => {
201
275
  var _a;
202
- if (n instanceof HTMLElement &&
203
- n.getAttribute('data-replaced') === 'true') {
276
+ const previousSiblingIsBlock = n.previousSibling == null || isHtmlElement(n.previousSibling);
277
+ if (isHtmlElement(n) && n.getAttribute('data-replaced') === 'true') {
278
+ /**
279
+ * If an element has been replaced visually, append the original
280
+ * value prior to being replaced.
281
+ */
204
282
  return `${res}${n.getAttribute('data-original')}`;
205
283
  }
206
- else if (n instanceof HTMLElement) {
207
- return `${res}${n.innerText}`;
284
+ else if (isHtmlElement(n) && n.childElementCount > 0) {
285
+ /**
286
+ * If an element is a wrapper, we want to treat it as a block element,
287
+ * ensuring newlines before and after the content.
288
+ * Additionally, we want to evaluate each of its children independently.
289
+ * Some browsers will conditionally wrap content in additional wrapper
290
+ * elements we need to unravel.
291
+ */
292
+ return `${res}${previousSiblingIsBlock ? '' : '\n'}${this.getContentAsString(n)}`;
293
+ }
294
+ else if (isBrElement(n)) {
295
+ /**
296
+ * If an element is a `<br>` element, we want to simply represent
297
+ * it as a newline in the returned string.
298
+ */
299
+ return `${res}\n`;
300
+ }
301
+ else if (isHtmlElement(n)) {
302
+ /**
303
+ * If an element is a wrapper, we want to treat it as a block element,
304
+ * ensuring newlines before and after the content.
305
+ * If the prior element is also to be treated as a block format, we
306
+ * will omit the newline before the content to avoid duplicating the
307
+ * behavior.
308
+ */
309
+ return `${res}${previousSiblingIsBlock ? '' : '\n'}${n.innerText}\n`;
208
310
  }
209
311
  else {
312
+ /**
313
+ * If a node is simply a `Text` node, we just want to append the text
314
+ * if defined.
315
+ */
210
316
  return `${res}${(_a = n.textContent) !== null && _a !== void 0 ? _a : ''}`;
211
317
  }
212
318
  }, ''));
319
+ return res;
213
320
  }
214
321
  return '';
215
322
  };
@@ -285,12 +392,13 @@ const SearchBar = class {
285
392
  replacement.before,
286
393
  replacement.beforeSpace,
287
394
  replacement.result,
395
+ replacement.afterSpace,
288
396
  ];
289
397
  }
290
398
  return res;
291
399
  }, [])
292
400
  : [];
293
- this.rawElements = [...parts, createTextNode(nextSubstr)];
401
+ this.rawElements = [...parts, createTextNode(nextSubstr)].reduce((res, p) => [...res, ...standardizeNewlinesAndSpaces(p)], []);
294
402
  this.updateContent(this.replacements);
295
403
  }
296
404
  }
@@ -298,7 +406,7 @@ const SearchBar = class {
298
406
  if (this.contentEl != null && !fastDeepEqual(newValue, oldValue)) {
299
407
  this.contentEl.innerHTML = '';
300
408
  this.displayedElements = this.rawElements.map((el) => {
301
- const raw = el instanceof HTMLElement ? el.innerText : el.textContent;
409
+ const raw = isHtmlElement(el) ? el.innerText : el.textContent;
302
410
  const replacement = this.replacements.find((r) => raw === null || raw === void 0 ? void 0 : raw.includes(createResultUri(r)));
303
411
  if (raw != null && replacement != null) {
304
412
  const replacementElement = this.createReplacedElement(raw, replacement);
@@ -313,7 +421,7 @@ const SearchBar = class {
313
421
  if (this.lastReplacedSpace != null) {
314
422
  this.moveCursorToNodeEnd(this.lastReplacedSpace);
315
423
  }
316
- this.inputChanged.emit(this.getContentAsString());
424
+ this.inputChanged.emit(this.getContentAsString(this.contentEl));
317
425
  }
318
426
  }
319
427
  render() {
@@ -325,7 +433,7 @@ const SearchBar = class {
325
433
  blank: this.variant === 'blank',
326
434
  disabled: this.disabled,
327
435
  });
328
- return (h(Host, null, h("div", { class: classes }, h("span", { class: "content-input", role: "textbox", contentEditable: "true", "aria-multiline": "true", "data-placeholder": this.placeholder, ref: (el) => (this.contentEl = el), onKeyDown: this.handleKeyDown, onKeyUp: this.handleCursorPositionUpdate, onClick: this.handleCursorPositionUpdate, onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur })), h("vertex-result-list", { position: this.cursorPosition, placement: this.placement, open: this.hasTriggered &&
436
+ return (h(Host, null, h("div", { class: classes }, h("span", { class: "content-input", role: "textbox", contentEditable: "true", "aria-multiline": "true", "data-placeholder": this.placeholder, ref: (el) => (this.contentEl = el), onKeyDown: this.handleKeyDown, onKeyUp: this.handleKeyUp, onClick: this.handleCursorPositionUpdate, onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur })), h("vertex-result-list", { position: this.cursorPosition, placement: this.placement, open: this.hasTriggered &&
329
437
  this.resultItems != null &&
330
438
  this.resultItems.length > 0, items: (_a = this.resultItems) !== null && _a !== void 0 ? _a : [], onEnterPressed: this.handleResultClick, onResultClick: this.handleResultClick }, h("slot", { name: "results" })), h("slot", { name: "replaced" })));
331
439
  }
@@ -341,13 +449,13 @@ const SearchBar = class {
341
449
  this.cursorPosition = this.getCursorPosition();
342
450
  }
343
451
  async handleInput() {
344
- this.inputChanged.emit(this.getContentAsString());
452
+ this.inputChanged.emit(this.getContentAsString(this.contentEl));
345
453
  }
346
454
  handleClick() {
347
455
  this.handleCursorPositionUpdate();
348
456
  }
349
457
  handleWindowClick(event) {
350
- if (event.target instanceof HTMLElement &&
458
+ if (isHtmlElement(event.target) &&
351
459
  event.target.getAttribute('data-replaced') === 'true' &&
352
460
  event.target.nextSibling != null) {
353
461
  this.moveCursorToNodeEnd(event.target.nextSibling, true);
@@ -364,7 +472,7 @@ const SearchBar = class {
364
472
  var _a;
365
473
  const triggeredRange = this.triggeredRange;
366
474
  const triggeredElement = this.triggeredElement;
367
- const value = triggeredElement instanceof HTMLElement
475
+ const value = isHtmlElement(triggeredElement)
368
476
  ? triggeredElement.innerText
369
477
  : triggeredElement === null || triggeredElement === void 0 ? void 0 : triggeredElement.textContent;
370
478
  if (this.contentEl != null &&
@@ -378,12 +486,10 @@ const SearchBar = class {
378
486
  const replacement = createSearchResultReplacement(event.detail, before, after);
379
487
  this.lastReplacedSpace = replacement.afterSpace;
380
488
  this.rawElements = Array.from(this.contentEl.childNodes).reduce((re, e) => {
381
- if (this.isIdenticalElement(e, triggeredElement)) {
382
- return [...re, ...getNodesForSearchResultReplacement(replacement)];
383
- }
384
- else {
385
- return [...re, e];
386
- }
489
+ return [
490
+ ...re,
491
+ ...this.attemptReplaceElement(e, triggeredElement, replacement),
492
+ ];
387
493
  }, []);
388
494
  this.hasTriggered = false;
389
495
  this.resultReplaced.emit(event.detail);
@@ -1,4 +1,4 @@
1
- export { I as vertex_icon_button } from './icon-button-4820c5f8.js';
1
+ export { I as vertex_icon_button } from './icon-button-d15ffd10.js';
2
2
  import './index-72f28b71.js';
3
3
  import './index-9c609209.js';
4
- import './icon-helper-091fab53.js';
4
+ import './icon-helper-805b317d.js';
@@ -1,4 +1,4 @@
1
- export { I as vertex_icon } from './icon-788d26c9.js';
1
+ export { I as vertex_icon } from './icon-74bf5afb.js';
2
2
  import './index-72f28b71.js';
3
3
  import './index-9c609209.js';
4
- import './icon-helper-091fab53.js';
4
+ import './icon-helper-805b317d.js';
@@ -1,4 +1,4 @@
1
- export { S as vertex_search_bar } from './search-bar-f12a3599.js';
1
+ export { S as vertex_search_bar } from './search-bar-8d18626e.js';
2
2
  import './index-72f28b71.js';
3
3
  import './index-9c609209.js';
4
4
  import './templates-797420bf.js';
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { h } from '../../../stencil-public-runtime';
3
+ export declare const Views: () => h.JSX.IntrinsicElements;
@@ -1,3 +1,8 @@
1
1
  export declare const getWindowSelection: () => Selection | undefined | null;
2
+ export declare const nodeHasChildNodes: (node: Node) => boolean;
2
3
  export declare const createDocumentRange: () => Range;
3
4
  export declare const createTextNode: (text: string) => Text;
5
+ export declare const createBreak: () => HTMLBRElement;
6
+ export declare const createWrappingDiv: (nodes: Node[]) => HTMLDivElement;
7
+ export declare const isHtmlElement: (node?: Node | EventTarget | null) => node is HTMLElement;
8
+ export declare const isBrElement: (node: Node) => node is HTMLBRElement;
@@ -3,12 +3,19 @@ export interface SearchResultReplacement {
3
3
  before: Text;
4
4
  beforeSpace: Text;
5
5
  result: Text;
6
- afterSpace?: Text;
6
+ afterSpace: Text;
7
7
  after?: Text;
8
8
  }
9
9
  export declare const createResultUri: (result: Result) => string;
10
10
  export declare const createSearchResultReplacement: (result: Result, before: string, after?: string) => SearchResultReplacement;
11
- export declare const getNodesForSearchResultReplacement: (replacement: SearchResultReplacement) => Text[];
11
+ /**
12
+ * Newline characters and spaces are represented slightly differently within a
13
+ * content editable element between browsers. This method standardizes the
14
+ * representation of those characters to avoid having to write branching logic
15
+ * to support each individual browser.
16
+ */
17
+ export declare const standardizeNewlinesAndSpaces: (node: ChildNode) => ChildNode[];
18
+ export declare const getNodesForSearchResultReplacement: (replacement: SearchResultReplacement, isBreaking?: boolean) => Text[];
12
19
  /**
13
20
  * We leverage a couple unique spaces to represent mentions, allowing for
14
21
  * correct cursor movement when using arrow keys. As these characters are
@@ -121,6 +121,7 @@ export declare class SearchBar {
121
121
  private handleFocus;
122
122
  private handleBlur;
123
123
  private handleResultClick;
124
+ private attemptReplaceElement;
124
125
  private isIdenticalElement;
125
126
  private getTextContent;
126
127
  private getCursorPosition;
@@ -105,6 +105,7 @@ export declare enum IconNames {
105
105
  'teleport' = "teleport",
106
106
  'turtle' = "turtle",
107
107
  'version-history' = "version-history",
108
+ 'views' = "views",
108
109
  'visibility-hidden' = "visibility-hidden",
109
110
  'visibility-partial' = "visibility-partial",
110
111
  'visibility-visible' = "visibility-visible",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertexvis/ui",
3
- "version": "0.1.0-canary.13",
3
+ "version": "0.1.0-canary.15",
4
4
  "description": "The Vertex UI component library.",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",
@@ -87,5 +87,5 @@
87
87
  "@vertexvis/utils": "^0.21.0",
88
88
  "fast-deep-equal": "^3.1.3"
89
89
  },
90
- "gitHead": "53757193daeb9741ba4bbd83f922c2f1b2952a86"
90
+ "gitHead": "41506ac171f4e6645cc68412d714621a28c1bb29"
91
91
  }
@@ -1 +0,0 @@
1
- export{I as vertex_icon_button}from"./p-b11a0f6b.js";import"./p-6834631c.js";import"./p-fe062eb0.js";import"./p-a50d42cc.js";
@@ -1 +0,0 @@
1
- export{I as vertex_icon}from"./p-04449a31.js";import"./p-6834631c.js";import"./p-fe062eb0.js";import"./p-a50d42cc.js";
@@ -1 +0,0 @@
1
- export{S as vertex_search_bar}from"./p-db34f10c.js";import"./p-6834631c.js";import"./p-fe062eb0.js";import"./p-1356f525.js";import"./p-59032668.js";
@@ -1 +0,0 @@
1
- import{r as e,e as t,h as r,H as i,g as s}from"./p-6834631c.js";import{c as a}from"./p-fe062eb0.js";import{g as n}from"./p-1356f525.js";var l=function e(t,r){if(t===r)return!0;if(t&&r&&"object"==typeof t&&"object"==typeof r){if(t.constructor!==r.constructor)return!1;var i,s,a;if(Array.isArray(t)){if((i=t.length)!=r.length)return!1;for(s=i;0!=s--;)if(!e(t[s],r[s]))return!1;return!0}if(t.constructor===RegExp)return t.source===r.source&&t.flags===r.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===r.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===r.toString();if((i=(a=Object.keys(t)).length)!==Object.keys(r).length)return!1;for(s=i;0!=s--;)if(!Object.prototype.hasOwnProperty.call(r,a[s]))return!1;for(s=i;0!=s--;){var n=a[s];if(!e(t[n],r[n]))return!1}return!0}return t!=t&&r!=r};const o=()=>{if("undefined"!=typeof window)return window.getSelection()},h=e=>new Text(e),c=e=>`${e.type}:${e.id}`,d=(e,t,r)=>{const i=c(e);return{before:h(t),beforeSpace:h(v()),result:h(i),afterSpace:null!=r?h(b()):void 0,after:null!=r?h(r):void 0}},u=e=>Object.keys(e).map((t=>e[t])).filter((e=>null!=e)),v=()=>String.fromCharCode(8202),b=()=>String.fromCharCode(160),x=class{constructor(r){e(this,r),this.searchChanged=t(this,"searchChanged",7),this.inputChanged=t(this,"inputChanged",7),this.resultReplaced=t(this,"resultReplaced",7),this.inputFocus=t(this,"inputFocus",7),this.inputBlur=t(this,"inputBlur",7),this.rawElements=[],this.isIdenticalElement=(e,t)=>e===this.triggeredElement||this.getTextContent(e)===this.getTextContent(t),this.getTextContent=e=>{var t;return e instanceof HTMLElement?e.innerText:null!==(t=e.textContent)&&void 0!==t?t:""},this.handleCursorPositionUpdate=()=>{var e,t;const r=null===(e=o())||void 0===e?void 0:e.getRangeAt(0);if(null!=r){const e=this.readTriggerValue(null!==(t=r.commonAncestorContainer.textContent)&&void 0!==t?t:"",r.startOffset);this.hasTriggered||null==e?this.hasTriggered&&null!=e?(this.triggeredRange=r,this.triggeredElement=r.commonAncestorContainer,this.searchChanged.emit(e.replace(this.triggerCharacter,""))):(this.hasTriggered=!1,this.triggeredRange=void 0,this.triggeredElement=void 0):(this.hasTriggered=!0,this.triggeredRange=r,this.triggeredElement=r.commonAncestorContainer,this.searchChanged.emit(e.replace(this.triggerCharacter,"")))}this.cursorPosition=this.getCursorPosition()},this.readTriggerValue=(e,t)=>{const r=e.replace(String.fromCharCode(160)," "),i=r.substring(0,t),s=r.substring(t),a=`${i.includes(this.triggerCharacter)?i.substring(i.lastIndexOf(this.triggerCharacter)):""}${s.substring(0,this.firstIndexOfBreakCharacter(s))}`;return a.includes(this.triggerCharacter)&&!this.includesBreakCharacter(a)?a:void 0},this.includesBreakCharacter=e=>this.breakCharacters.some((t=>e.includes(t))),this.firstIndexOfBreakCharacter=e=>{const t=this.breakCharacters.map((t=>e.indexOf(t))).filter((e=>e>=0));return t.length>0?Math.min(...t):e.length},this.moveCursorToNodeEnd=(e,t=!1)=>{const r=o();if(null!=r){const i=document.createRange();i.selectNodeContents(e),i.collapse(t),r.removeAllRanges(),r.addRange(i)}},this.getContentAsString=()=>null!=this.contentEl?Array.from(this.contentEl.childNodes).reduce(((e,t)=>{var r;return t instanceof HTMLElement&&"true"===t.getAttribute("data-replaced")?`${e}${t.getAttribute("data-original")}`:t instanceof HTMLElement?`${e}${t.innerText}`:`${e}${null!==(r=t.textContent)&&void 0!==r?r:""}`}),"").replace(/[\u200A]/g,"").replace(/[\u00A0]/g," "):"",this.createReplacedElement=(e,t)=>{const r=this.hostEl.querySelector('template[slot="replaced"]');if(null!=r){const i=n(r);return i.bindings.bind(t),i.element.id=t.id,i.element.style.display="inline-block",i.element.contentEditable="false",i.element.tabIndex=-1,i.element.setAttribute("data-replaced","true"),i.element.setAttribute("data-original",e),i.element}throw new Error("Replaced template not defined.")},this.variant="standard",this.disabled=!1,this.triggerCharacter="@",this.breakCharacters=[" ","\n"],this.resultItems=void 0,this.placement="bottom-start",this.value=void 0,this.placeholder=void 0,this.replacements=[],this.replacementUriType="user",this.cursorPosition=void 0,this.displayedElements=[],this.hasTriggered=!1,this.handleKeyDown=this.handleKeyDown.bind(this),this.handleKeyUp=this.handleKeyUp.bind(this),this.handleResultClick=this.handleResultClick.bind(this),this.handleClick=this.handleClick.bind(this),this.handleWindowClick=this.handleWindowClick.bind(this),this.handleInput=this.handleInput.bind(this),this.handleBlur=this.handleBlur.bind(this),this.handleFocus=this.handleFocus.bind(this),this.handleCursorPositionUpdate=this.handleCursorPositionUpdate.bind(this),this.updateContent=this.updateContent.bind(this),this.replaceContent=this.replaceContent.bind(this)}componentDidLoad(){this.replaceContent(this.value)}connectedCallback(){window.addEventListener("click",this.handleWindowClick)}disconnectedCallback(){window.removeEventListener("click",this.handleWindowClick)}replaceContent(e,t){if(null!=e&&e!==t){const t=e.match(new RegExp(`${this.replacementUriType}:[0-9a-z-]{36}`,"g")),r=this.replacements.reduce(((e,t)=>Object.assign(Object.assign({},e),{[c(t)]:t})),{});let i=e;const s=null!=t?null==t?void 0:t.reduce(((e,t)=>{if(null!=r[t]){const s=c(r[t]),a=i.indexOf(s),n=i.substring(0,a),l=i.substring(a+s.length),o=d(r[t],n);return i=l,[...e,o.before,o.beforeSpace,o.result]}return e}),[]):[];this.rawElements=[...s,h(i)],this.updateContent(this.replacements)}}updateContent(e,t){null==this.contentEl||l(e,t)||(this.contentEl.innerHTML="",this.displayedElements=this.rawElements.map((e=>{const t=e instanceof HTMLElement?e.innerText:e.textContent,r=this.replacements.find((e=>null==t?void 0:t.includes(c(e))));return null!=t&&null!=r?this.createReplacedElement(t,r):e})),this.displayedElements.forEach((e=>{var t;null===(t=this.contentEl)||void 0===t||t.appendChild("string"==typeof e?h(e):e)})),null!=this.lastReplacedSpace&&this.moveCursorToNodeEnd(this.lastReplacedSpace),this.inputChanged.emit(this.getContentAsString()))}render(){var e;const t=a("wrapper",{standard:"standard"===this.variant,filled:"filled"===this.variant,underlined:"underlined"===this.variant,blank:"blank"===this.variant,disabled:this.disabled});return r(i,null,r("div",{class:t},r("span",{class:"content-input",role:"textbox",contentEditable:"true","aria-multiline":"true","data-placeholder":this.placeholder,ref:e=>this.contentEl=e,onKeyDown:this.handleKeyDown,onKeyUp:this.handleCursorPositionUpdate,onClick:this.handleCursorPositionUpdate,onInput:this.handleInput,onFocus:this.handleFocus,onBlur:this.handleBlur})),r("vertex-result-list",{position:this.cursorPosition,placement:this.placement,open:this.hasTriggered&&null!=this.resultItems&&this.resultItems.length>0,items:null!==(e=this.resultItems)&&void 0!==e?e:[],onEnterPressed:this.handleResultClick,onResultClick:this.handleResultClick},r("slot",{name:"results"})),r("slot",{name:"replaced"}))}handleKeyDown(e){this.hasTriggered&&this.breakCharacters.includes(e.key)&&(this.hasTriggered=!1,this.triggeredRange=void 0,this.triggeredElement=void 0)}handleKeyUp(e){this.handleCursorPositionUpdate(),this.cursorPosition=this.getCursorPosition()}async handleInput(){this.inputChanged.emit(this.getContentAsString())}handleClick(){this.handleCursorPositionUpdate()}handleWindowClick(e){e.target instanceof HTMLElement&&"true"===e.target.getAttribute("data-replaced")&&null!=e.target.nextSibling&&this.moveCursorToNodeEnd(e.target.nextSibling,!0)}handleFocus(e){this.inputFocus.emit(e)}handleBlur(e){this.hasTriggered=!1,this.inputBlur.emit(e)}handleResultClick(e){var t;const r=this.triggeredRange,i=this.triggeredElement,s=i instanceof HTMLElement?i.innerText:null==i?void 0:i.textContent;if(null!=this.contentEl&&null!=r&&null!=i&&null!=s){const a=null!==(t=this.readTriggerValue(s,r.startOffset))&&void 0!==t?t:"",n=s.split(a),l=d(e.detail,n[0],n[1]);this.lastReplacedSpace=l.afterSpace,this.rawElements=Array.from(this.contentEl.childNodes).reduce(((e,t)=>this.isIdenticalElement(t,i)?[...e,...u(l)]:[...e,t]),[]),this.hasTriggered=!1,this.resultReplaced.emit(e.detail),this.replacements=[...this.replacements.filter((t=>t.id!==e.detail.id)),e.detail]}}getCursorPosition(){var e;const t=o();if(null!=t&&t.rangeCount>0){const r=t.getRangeAt(0).getBoundingClientRect(),i=null===(e=this.contentEl)||void 0===e?void 0:e.getBoundingClientRect(),s=r.bottom||(null==i?void 0:i.bottom)||0,a=r.top||(null==i?void 0:i.top)||0;return{x:r.left||(null==i?void 0:i.left)||0,y:this.placement.includes("top")?a:s}}throw new Error("Unable to retrieve window selection.")}get hostEl(){return s(this)}static get watchers(){return{value:["replaceContent"],replacements:["updateContent"]}}};x.style=".wrapper.sc-vertex-search-bar{display:flex;align-items:center;width:100%;box-sizing:border-box;background:none;border:1px solid transparent;border-radius:4px;font-family:var(--vertex-ui-font-family);font-size:0.875rem;line-height:1.4}.content-input.sc-vertex-search-bar{width:100%;box-sizing:border-box;padding:6px 0.5em 7px;border:1px solid transparent;background:none;font-family:var(--vertex-ui-font-family);font-weight:var(--vertex-ui-font-weight-base);font-size:0.875rem;line-height:1.4;white-space:pre-line}.content-input.sc-vertex-search-bar:focus{outline:none}.standard.sc-vertex-search-bar{border-color:var(--vertex-ui-neutral-400);color:var(--vertex-ui-neutral-800)}.standard.sc-vertex-search-bar .content-input.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-500)}.standard.sc-vertex-search-bar:hover:not(.disabled),.standard.sc-vertex-search-bar:focus{border-color:var(--vertex-ui-neutral-500)}.standard.disabled.sc-vertex-search-bar{border-color:var(--vertex-ui-neutral-200)}.standard.disabled.sc-vertex-search-bar,.standard.disabled.sc-vertex-search-bar .content-input.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-400)}.blank.sc-vertex-search-bar{color:var(--vertex-ui-neutral-800)}.blank.sc-vertex-search-bar:not(:hover) .content-input.sc-vertex-search-bar:focus{border-color:var(--vertex-ui-neutral-400);border-radius:4px}.blank.sc-vertex-search-bar .content-input.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-500)}.blank.sc-vertex-search-bar:hover:not(.disabled) .content-input.sc-vertex-search-bar{border-color:var(--vertex-ui-neutral-400);border-radius:4px}.blank.disabled.sc-vertex-search-bar{border-color:var(--vertex-ui-neutral-200)}.blank.disabled.sc-vertex-search-bar,.blank.disabled.sc-vertex-search-bar .content-input.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-400)}.filled.sc-vertex-search-bar{background-color:var(--vertex-ui-neutral-200);border-color:var(--vertex-ui-neutral-200);color:var(--vertex-ui-neutral-800)}.filled.disabled.sc-vertex-search-bar,.filled.disabled.sc-vertex-search-bar .content-input.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-400)}.filled.sc-vertex-search-bar .content-input.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-700)}.filled.sc-vertex-search-bar:hover:not(.disabled),.filled.sc-vertex-search-bar:focus{border-bottom-color:var(--vertex-ui-blue-600)}.filled.disabled.sc-vertex-search-bar{border-color:var(--vertex-ui-neutral-100)}.filled.disabled.sc-vertex-search-bar,.filled.disabled.sc-vertex-search-bar .content-input.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-400)}.underlined.sc-vertex-search-bar{background-color:var(--vertex-ui-white);border-color:var(--vertex-ui-white) var(--vertex-ui-white) var(--vertex-ui-neutral-400) var(--vertex-ui-white);color:var(--vertex-ui-neutral-800)}.underlined.disabled.sc-vertex-search-bar,.underlined.disabled.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-400)}.underlined.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-700)}.underlined.sc-vertex-search-bar:hover:not(.disabled),.underlined.sc-vertex-search-bar:focus{background-color:var(--vertex-ui-neutral-200);border-color:var(--vertex-ui-neutral-200);border-bottom-color:var(--vertex-ui-blue-600)}.underlined.disabled.sc-vertex-search-bar{border-bottom-color:var(--vertex-ui-neutral-200)}.underlined.disabled.sc-vertex-search-bar,.underlined.disabled.sc-vertex-search-bar .content-input.sc-vertex-search-bar:empty::before{content:attr(data-placeholder);color:var(--vertex-ui-neutral-400)}.underlined.has-error.sc-vertex-search-bar{border-bottom-color:var(--vertex-ui-red-600)}";export{x as S}