@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
@@ -2,7 +2,7 @@
2
2
 
3
3
  const index = require('./index-6a92256c.js');
4
4
  const index$1 = require('./index-e1b40fa6.js');
5
- const iconHelper = require('./icon-helper-af9f8c10.js');
5
+ const iconHelper = require('./icon-helper-0e14d7cc.js');
6
6
 
7
7
  const iconCss = ".container{display:flex;justify-content:center;align-items:center;width:100%;height:100%}.icon{display:flex;justify-content:center;align-items:center;fill:currentColor}.xs{height:var(--icon-size, 0.75rem);width:var(--icon-size, 0.75rem)}.sm{height:var(--icon-size, 1rem);width:var(--icon-size, 1rem)}.md{height:var(--icon-size, 1.5rem);width:var(--icon-size, 1.5rem)}.lg{height:var(--icon-size, 2rem);width:var(--icon-size, 2rem)}svg{position:relative;width:100%}";
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  const index = require('./index-6a92256c.js');
4
4
  const index$1 = require('./index-e1b40fa6.js');
5
- const iconHelper = require('./icon-helper-af9f8c10.js');
5
+ const iconHelper = require('./icon-helper-0e14d7cc.js');
6
6
 
7
7
  const iconButtonCss = "button{border:none;background-color:transparent;font-family:var(--vertex-ui-font-family);font-size:0.875rem;padding:0}:host{--enabled-cursor:pointer;--disabled-cursor:not-allowed;--hover-background-color:var(--vertex-ui-neutral-300);--active-background-color:var(--vertex-ui-neutral-400);--focus-background-color:var(--vertex-ui-neutral-400);--hover-box-shadow:0 2px 2px rgb(0 0 0 / 20%);--active-box-shadow:none;--focus-box-shadow:0 0 0 1px var(--vertex-ui-neutral-900);--icon-margin:0px}.container{display:flex;justify-content:center;align-items:center;outline:none;fill:currentColor;color:currentColor;cursor:var(--enabled-cursor)}.container:not(.plain){border-radius:4px;padding:0.25rem}.icon-button{display:flex;position:relative;justify-content:center;align-items:center;fill:currentColor;height:var(--icon-size, 1.5rem);width:var(--icon-size, 1.5rem)}.icon-button svg{width:100%;height:100%;margin:var(--icon-margin, 0px)}.badge{position:absolute;top:0px;right:4px;justify-content:flex-end;align-items:flex-end}.floating{background-color:var(--vertex-ui-neutral-100);box-shadow:var(--vertex-ui-overlay-shadow);color:var(--vertex-ui-neutral-700);fill:var(--vertex-ui-neutral-700);opacity:0.95}.floating.disabled{color:var(--vertex-ui-neutral-400);cursor:var(--disabled-cursor)}.container:not(.disabled):not(.plain):hover{background-color:var(--hover-background-color);box-shadow:var(--hover-box-shadow)}.container:not(.disabled):not(.plain):active{background-color:var(--active-background-color);box-shadow:var(--active-box-shadow)}.container:not(.disabled):not(.plain):focus-visible{background-color:var(--focus-background-color);box-shadow:var(--focus-box-shadow);color:var(--vertex-ui-neutral-900)}.container.disabled:not(.floating){cursor:var(--disabled-cursor);color:var(--vertex-ui-neutral-400)}.container.primary:not(.disabled){color:var(--vertex-ui-blue-700)}.container.secondary:not(.disabled){color:var(--vertex-ui-neutral-800)}.xs{height:var(--icon-size, 0.75rem);width:var(--icon-size, 0.75rem)}.sm{height:var(--icon-size, 1rem);width:var(--icon-size, 1rem)}.md{height:var(--icon-size, 1.5rem);width:var(--icon-size, 1.5rem)}.lg{height:var(--icon-size, 2rem);width:var(--icon-size, 2rem)}";
8
8
 
@@ -377,6 +377,9 @@ const Turtle = () => (index.h("svg", { xmlns: "http://www.w3.org/2000/svg", view
377
377
  const VersionHistory = () => (index.h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", "data-testid": "version-history" },
378
378
  index.h("path", { d: "M7.91,5.5a.5.5,0,0,0-.5.5V8.94l1.21,1.39a.5.5,0,0,0,.76-.66l-1-1.11V6A.5.5,0,0,0,7.91,5.5ZM8,1.5A6.5,6.5,0,0,0,1.5,8H0l2,3L4,8H2.5a5.5,5.5,0,1,1,2.23,4.42.5.5,0,0,0-.7.1.5.5,0,0,0,.1.7A6.42,6.42,0,0,0,8,14.5a6.5,6.5,0,0,0,0-13Z" })));
379
379
 
380
+ const Views = () => (index.h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", "data-testid": "views" },
381
+ index.h("path", { d: "M12.49 5.97v-.03c0-.07-.02-.13-.05-.19a.27.27 0 0 0-.07-.08.284.284 0 0 0-.1-.09c-.02-.01-.02-.03-.04-.04L8.27 3.56a.508.508 0 0 0-.45 0L3.9 5.51c-.11.03-.21.11-.28.22l-.02.02-.01.02c-.03.07-.05.13-.05.2 0 .01-.01.02-.01.04v4.63c0 .19.11.36.28.45l4 1.99h.01a.465.465 0 0 0 .42 0h.01l3.97-1.96a.5.5 0 0 0 .28-.45L12.48 6l.01-.03ZM8.04 4.55l2.84 1.42-2.83 1.45-2.88-1.44 2.87-1.43ZM4.53 6.78l3 1.5v3.52l-3-1.5V6.77v.01Zm4.01 5.02V8.29l2.96-1.51v3.55L8.54 11.8ZM1.5 5c-.28 0-.5-.22-.5-.5V1h3.5c.28 0 .5.22.5.5s-.22.5-.5.5H2v2.5c0 .28-.22.5-.5.5Zm0 5.99c-.28 0-.5.22-.5.5v3.5h3.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5H2v-2.5c0-.28-.22-.5-.5-.5ZM14.5 5c.28 0 .5-.22.5-.5V1h-3.5c-.28 0-.5.22-.5.5s.22.5.5.5H14v2.5c0 .28.22.5.5.5Zm0 5.99c.28 0 .5.22.5.5v3.5h-3.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5H14v-2.5c0-.28.22-.5.5-.5Z" })));
382
+
380
383
  const VisibilityHidden = () => (index.h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", "data-testid": "visibility-hidden" },
381
384
  index.h("path", { d: "M13.35,2.65a.48.48,0,0,0-.7,0l-.78.77a8.71,8.71,0,0,0-8.52.41A6.57,6.57,0,0,0,.51,7.89v.22a6.58,6.58,0,0,0,2.71,4l-.57.58a.49.49,0,0,0,.7.7l10-10A.48.48,0,0,0,13.35,2.65ZM9.73,5.56A3,3,0,0,0,5.56,9.73L3.94,11.35l0,0A5.49,5.49,0,0,1,1.53,8,5.49,5.49,0,0,1,3.9,4.67,7.52,7.52,0,0,1,8,3.5a7.67,7.67,0,0,1,3.12.67Zm3.61-1.2-.72.72A5.45,5.45,0,0,1,14.47,8a5.49,5.49,0,0,1-2.37,3.33A7.52,7.52,0,0,1,8,12.5a8.15,8.15,0,0,1-2.41-.38l-.78.78A8.9,8.9,0,0,0,8,13.5a8.53,8.53,0,0,0,4.65-1.33,6.57,6.57,0,0,0,2.84-4.06V7.89A6.56,6.56,0,0,0,13.34,4.36Z" })));
382
385
 
@@ -611,6 +614,8 @@ function getSvg(name) {
611
614
  return index.h(Turtle, null);
612
615
  case 'version-history':
613
616
  return index.h(VersionHistory, null);
617
+ case 'views':
618
+ return index.h(Views, null);
614
619
  case 'visibility-hidden':
615
620
  return index.h(VisibilityHidden, null);
616
621
  case 'visibility-partial':
@@ -21,8 +21,8 @@ const draggablePopover = require('./draggable-popover-edf23d3a.js');
21
21
  const dropdownMenu = require('./dropdown-menu-5ae03a72.js');
22
22
  const expandable = require('./expandable-b1cd4f0b.js');
23
23
  const helpTooltip = require('./help-tooltip-f72eccc7.js');
24
- const icon = require('./icon-88af577f.js');
25
- const iconButton = require('./icon-button-7b2ff7b0.js');
24
+ const icon = require('./icon-b6383789.js');
25
+ const iconButton = require('./icon-button-f32c3cc8.js');
26
26
  const logoLoading = require('./logo-loading-4d49fedf.js');
27
27
  const menu = require('./menu-d1ecf43b.js');
28
28
  const menuDivider = require('./menu-divider-5bdebe5d.js');
@@ -32,7 +32,7 @@ const radio = require('./radio-bff991d2.js');
32
32
  const radioGroup = require('./radio-group-d628f631.js');
33
33
  const resizable = require('./resizable-e4248256.js');
34
34
  const resultList = require('./result-list-241ffe8d.js');
35
- const searchBar = require('./search-bar-91cbcd07.js');
35
+ const searchBar = require('./search-bar-2e7ee35a.js');
36
36
  const select = require('./select-5f8aecfe.js');
37
37
  const slider = require('./slider-13594e49.js');
38
38
  const spinner = require('./spinner-bb990a42.js');
@@ -45,7 +45,7 @@ const tooltip = require('./tooltip-9ac797a0.js');
45
45
  require('./index-6a92256c.js');
46
46
  require('./slots-fb5ac359.js');
47
47
  require('./index-e1b40fa6.js');
48
- require('./icon-helper-af9f8c10.js');
48
+ require('./icon-helper-0e14d7cc.js');
49
49
  require('./templates-e7b3ffbb.js');
50
50
  require('./tslib.es6-838fd860.js');
51
51
  require('./dom-b6c5fbf4.js');
@@ -55,12 +55,24 @@ const getWindowSelection = () => {
55
55
  }
56
56
  return undefined;
57
57
  };
58
+ const nodeHasChildNodes = (node) => {
59
+ return node.hasChildNodes();
60
+ };
58
61
  const createDocumentRange = () => {
59
62
  return document.createRange();
60
63
  };
61
64
  const createTextNode = (text) => {
62
65
  return new Text(text);
63
66
  };
67
+ const createBreak = () => {
68
+ return document.createElement('br');
69
+ };
70
+ const isHtmlElement = (node) => {
71
+ return node instanceof HTMLElement;
72
+ };
73
+ const isBrElement = (node) => {
74
+ return node instanceof HTMLBRElement;
75
+ };
64
76
 
65
77
  const createResultUri = (result) => {
66
78
  return `${result.type}:${result.id}`;
@@ -71,15 +83,56 @@ const createSearchResultReplacement = (result, before, after) => {
71
83
  before: createTextNode(before),
72
84
  beforeSpace: createTextNode(createHairSpace()),
73
85
  result: createTextNode(urn),
74
- afterSpace: after != null ? createTextNode(createNoBreakSpace()) : undefined,
86
+ afterSpace: after != null
87
+ ? createTextNode(createNoBreakSpace())
88
+ : createTextNode(createHairSpace()),
75
89
  after: after != null ? createTextNode(after) : undefined,
76
90
  };
77
91
  };
78
- const getNodesForSearchResultReplacement = (replacement) => {
92
+ /**
93
+ * Newline characters and spaces are represented slightly differently within a
94
+ * content editable element between browsers. This method standardizes the
95
+ * representation of those characters to avoid having to write branching logic
96
+ * to support each individual browser.
97
+ */
98
+ const standardizeNewlinesAndSpaces = (node) => {
99
+ const content = node.textContent;
100
+ if (content === '\n') {
101
+ return [createBreak()];
102
+ }
103
+ else if (content != null && content.includes('\n')) {
104
+ const split = content.split('\n');
105
+ return split.reduce((res, substr, i) => {
106
+ const previous = split[i - 1];
107
+ // Ignore the empty string if the prior element was converted
108
+ // to a breaking element to prevent duplication of newlines.
109
+ if (substr === '' && previous !== '') {
110
+ return res;
111
+ }
112
+ return [
113
+ ...res,
114
+ // Standard spaces are not always respected with in `Text`
115
+ // elements when appended to a contenteditable element. This
116
+ // conversion preserves that spacing.
117
+ createTextNode(substr.replace(/ /g, createNoBreakSpace())),
118
+ createBreak(),
119
+ ];
120
+ }, []);
121
+ }
122
+ return [node];
123
+ };
124
+ const getNodesForSearchResultReplacement = (replacement, isBreaking = false) => {
79
125
  const keys = Object.keys(replacement);
80
- return keys
126
+ const replacementElements = keys
81
127
  .map((key) => replacement[key])
82
128
  .filter((node) => node != null);
129
+ // If the element is intended to replace a breaking element such
130
+ // as a `<div>` wrapper, a newline is required alongside the standard
131
+ // replacement elements.
132
+ if (isBreaking) {
133
+ return [createTextNode('\n'), ...replacementElements];
134
+ }
135
+ return replacementElements;
83
136
  };
84
137
  /**
85
138
  * We leverage a couple unique spaces to represent mentions, allowing for
@@ -114,13 +167,34 @@ const SearchBar = class {
114
167
  this.inputFocus = index.createEvent(this, "inputFocus", 7);
115
168
  this.inputBlur = index.createEvent(this, "inputBlur", 7);
116
169
  this.rawElements = [];
170
+ this.attemptReplaceElement = (child, other, replacement, isBreaking = false) => {
171
+ // In the case that the child we're evaluating has its own children
172
+ // (often a wrapper `<div>`), we want to evaluate whether any of its
173
+ // children is the target to replace.
174
+ if (nodeHasChildNodes(child) &&
175
+ Array.from(child.childNodes).some((c) => nodeHasChildNodes(c) || this.isIdenticalElement(c, other))) {
176
+ return Array.from(child.childNodes).reduce((res, c) => [
177
+ ...res,
178
+ ...this.attemptReplaceElement(c, other, replacement,
179
+ // If the element we're evaluating is a wrapper, we want to
180
+ // consider it a breaking element and add a newline to the
181
+ // replaced element only if the previous node is a `Text` node.
182
+ !isHtmlElement(child.previousSibling)),
183
+ ], []);
184
+ }
185
+ else {
186
+ return this.isIdenticalElement(child, other)
187
+ ? getNodesForSearchResultReplacement(replacement, isBreaking)
188
+ : [child];
189
+ }
190
+ };
117
191
  this.isIdenticalElement = (child, other) => {
118
192
  return (child === this.triggeredElement ||
119
193
  this.getTextContent(child) === this.getTextContent(other));
120
194
  };
121
195
  this.getTextContent = (node) => {
122
196
  var _a;
123
- if (node instanceof HTMLElement) {
197
+ if (isHtmlElement(node)) {
124
198
  return node.innerText;
125
199
  }
126
200
  return (_a = node.textContent) !== null && _a !== void 0 ? _a : '';
@@ -197,21 +271,54 @@ const SearchBar = class {
197
271
  selection.addRange(range);
198
272
  }
199
273
  };
200
- this.getContentAsString = () => {
201
- if (this.contentEl != null) {
202
- return trimNonstandardSpaces(Array.from(this.contentEl.childNodes).reduce((res, n) => {
274
+ this.getContentAsString = (element) => {
275
+ if (element != null) {
276
+ const res = trimNonstandardSpaces(Array.from(element.childNodes).reduce((res, n) => {
203
277
  var _a;
204
- if (n instanceof HTMLElement &&
205
- n.getAttribute('data-replaced') === 'true') {
278
+ const previousSiblingIsBlock = n.previousSibling == null || isHtmlElement(n.previousSibling);
279
+ if (isHtmlElement(n) && n.getAttribute('data-replaced') === 'true') {
280
+ /**
281
+ * If an element has been replaced visually, append the original
282
+ * value prior to being replaced.
283
+ */
206
284
  return `${res}${n.getAttribute('data-original')}`;
207
285
  }
208
- else if (n instanceof HTMLElement) {
209
- return `${res}${n.innerText}`;
286
+ else if (isHtmlElement(n) && n.childElementCount > 0) {
287
+ /**
288
+ * If an element is a wrapper, we want to treat it as a block element,
289
+ * ensuring newlines before and after the content.
290
+ * Additionally, we want to evaluate each of its children independently.
291
+ * Some browsers will conditionally wrap content in additional wrapper
292
+ * elements we need to unravel.
293
+ */
294
+ return `${res}${previousSiblingIsBlock ? '' : '\n'}${this.getContentAsString(n)}`;
295
+ }
296
+ else if (isBrElement(n)) {
297
+ /**
298
+ * If an element is a `<br>` element, we want to simply represent
299
+ * it as a newline in the returned string.
300
+ */
301
+ return `${res}\n`;
302
+ }
303
+ else if (isHtmlElement(n)) {
304
+ /**
305
+ * If an element is a wrapper, we want to treat it as a block element,
306
+ * ensuring newlines before and after the content.
307
+ * If the prior element is also to be treated as a block format, we
308
+ * will omit the newline before the content to avoid duplicating the
309
+ * behavior.
310
+ */
311
+ return `${res}${previousSiblingIsBlock ? '' : '\n'}${n.innerText}\n`;
210
312
  }
211
313
  else {
314
+ /**
315
+ * If a node is simply a `Text` node, we just want to append the text
316
+ * if defined.
317
+ */
212
318
  return `${res}${(_a = n.textContent) !== null && _a !== void 0 ? _a : ''}`;
213
319
  }
214
320
  }, ''));
321
+ return res;
215
322
  }
216
323
  return '';
217
324
  };
@@ -287,12 +394,13 @@ const SearchBar = class {
287
394
  replacement.before,
288
395
  replacement.beforeSpace,
289
396
  replacement.result,
397
+ replacement.afterSpace,
290
398
  ];
291
399
  }
292
400
  return res;
293
401
  }, [])
294
402
  : [];
295
- this.rawElements = [...parts, createTextNode(nextSubstr)];
403
+ this.rawElements = [...parts, createTextNode(nextSubstr)].reduce((res, p) => [...res, ...standardizeNewlinesAndSpaces(p)], []);
296
404
  this.updateContent(this.replacements);
297
405
  }
298
406
  }
@@ -300,7 +408,7 @@ const SearchBar = class {
300
408
  if (this.contentEl != null && !fastDeepEqual(newValue, oldValue)) {
301
409
  this.contentEl.innerHTML = '';
302
410
  this.displayedElements = this.rawElements.map((el) => {
303
- const raw = el instanceof HTMLElement ? el.innerText : el.textContent;
411
+ const raw = isHtmlElement(el) ? el.innerText : el.textContent;
304
412
  const replacement = this.replacements.find((r) => raw === null || raw === void 0 ? void 0 : raw.includes(createResultUri(r)));
305
413
  if (raw != null && replacement != null) {
306
414
  const replacementElement = this.createReplacedElement(raw, replacement);
@@ -315,7 +423,7 @@ const SearchBar = class {
315
423
  if (this.lastReplacedSpace != null) {
316
424
  this.moveCursorToNodeEnd(this.lastReplacedSpace);
317
425
  }
318
- this.inputChanged.emit(this.getContentAsString());
426
+ this.inputChanged.emit(this.getContentAsString(this.contentEl));
319
427
  }
320
428
  }
321
429
  render() {
@@ -327,7 +435,7 @@ const SearchBar = class {
327
435
  blank: this.variant === 'blank',
328
436
  disabled: this.disabled,
329
437
  });
330
- return (index.h(index.Host, null, index.h("div", { class: classes }, index.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 })), index.h("vertex-result-list", { position: this.cursorPosition, placement: this.placement, open: this.hasTriggered &&
438
+ return (index.h(index.Host, null, index.h("div", { class: classes }, index.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 })), index.h("vertex-result-list", { position: this.cursorPosition, placement: this.placement, open: this.hasTriggered &&
331
439
  this.resultItems != null &&
332
440
  this.resultItems.length > 0, items: (_a = this.resultItems) !== null && _a !== void 0 ? _a : [], onEnterPressed: this.handleResultClick, onResultClick: this.handleResultClick }, index.h("slot", { name: "results" })), index.h("slot", { name: "replaced" })));
333
441
  }
@@ -343,13 +451,13 @@ const SearchBar = class {
343
451
  this.cursorPosition = this.getCursorPosition();
344
452
  }
345
453
  async handleInput() {
346
- this.inputChanged.emit(this.getContentAsString());
454
+ this.inputChanged.emit(this.getContentAsString(this.contentEl));
347
455
  }
348
456
  handleClick() {
349
457
  this.handleCursorPositionUpdate();
350
458
  }
351
459
  handleWindowClick(event) {
352
- if (event.target instanceof HTMLElement &&
460
+ if (isHtmlElement(event.target) &&
353
461
  event.target.getAttribute('data-replaced') === 'true' &&
354
462
  event.target.nextSibling != null) {
355
463
  this.moveCursorToNodeEnd(event.target.nextSibling, true);
@@ -366,7 +474,7 @@ const SearchBar = class {
366
474
  var _a;
367
475
  const triggeredRange = this.triggeredRange;
368
476
  const triggeredElement = this.triggeredElement;
369
- const value = triggeredElement instanceof HTMLElement
477
+ const value = isHtmlElement(triggeredElement)
370
478
  ? triggeredElement.innerText
371
479
  : triggeredElement === null || triggeredElement === void 0 ? void 0 : triggeredElement.textContent;
372
480
  if (this.contentEl != null &&
@@ -380,12 +488,10 @@ const SearchBar = class {
380
488
  const replacement = createSearchResultReplacement(event.detail, before, after);
381
489
  this.lastReplacedSpace = replacement.afterSpace;
382
490
  this.rawElements = Array.from(this.contentEl.childNodes).reduce((re, e) => {
383
- if (this.isIdenticalElement(e, triggeredElement)) {
384
- return [...re, ...getNodesForSearchResultReplacement(replacement)];
385
- }
386
- else {
387
- return [...re, e];
388
- }
491
+ return [
492
+ ...re,
493
+ ...this.attemptReplaceElement(e, triggeredElement, replacement),
494
+ ];
389
495
  }, []);
390
496
  this.hasTriggered = false;
391
497
  this.resultReplaced.emit(event.detail);
@@ -2,10 +2,10 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const iconButton = require('./icon-button-7b2ff7b0.js');
5
+ const iconButton = require('./icon-button-f32c3cc8.js');
6
6
  require('./index-6a92256c.js');
7
7
  require('./index-e1b40fa6.js');
8
- require('./icon-helper-af9f8c10.js');
8
+ require('./icon-helper-0e14d7cc.js');
9
9
 
10
10
 
11
11
 
@@ -2,10 +2,10 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const icon = require('./icon-88af577f.js');
5
+ const icon = require('./icon-b6383789.js');
6
6
  require('./index-6a92256c.js');
7
7
  require('./index-e1b40fa6.js');
8
- require('./icon-helper-af9f8c10.js');
8
+ require('./icon-helper-0e14d7cc.js');
9
9
 
10
10
 
11
11
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const searchBar = require('./search-bar-91cbcd07.js');
5
+ const searchBar = require('./search-bar-2e7ee35a.js');
6
6
  require('./index-6a92256c.js');
7
7
  require('./index-e1b40fa6.js');
8
8
  require('./templates-e7b3ffbb.js');
@@ -105,6 +105,7 @@ import { TeleportAndAlign } from './icons/teleport-and-align';
105
105
  import { TeleportToward } from './icons/teleport-toward';
106
106
  import { Turtle } from './icons/turtle';
107
107
  import { VersionHistory } from './icons/version-history';
108
+ import { Views } from './icons/views';
108
109
  import { VisibilityHidden } from './icons/visibility-hidden';
109
110
  import { VisibilityPartial } from './icons/visibility-partial';
110
111
  import { VisibilityVisible } from './icons/visibility-visible';
@@ -323,6 +324,8 @@ export function getSvg(name) {
323
324
  return h(Turtle, null);
324
325
  case 'version-history':
325
326
  return h(VersionHistory, null);
327
+ case 'views':
328
+ return h(Views, null);
326
329
  case 'visibility-hidden':
327
330
  return h(VisibilityHidden, null);
328
331
  case 'visibility-partial':
@@ -33,7 +33,7 @@ export class Icon {
33
33
  "mutable": false,
34
34
  "complexType": {
35
35
  "original": "IconName",
36
- "resolved": "\"compare\" | \"help\" | \"open\" | \"info\" | \"copy\" | \"menu\" | \"ellipse\" | \"line\" | \"download\" | \"rotate\" | \"close\" | \"flip\" | \"reset\" | \"resize\" | \"search\" | \"caret-down\" | \"caret-up\" | \"adjustments\" | \"align-to-global\" | \"align-to-part\" | \"align-to-surface\" | \"align-view-to-plane\" | \"annotation\" | \"arrow-filled\" | \"arrow-line-left\" | \"arrow-line-right\" | \"arrow-partial\" | \"arrow-triangle-left\" | \"arrow-triangle-right\" | \"arrow-up-circled\" | \"attachment\" | \"axis-x\" | \"axis-y\" | \"axis-z\" | \"back\" | \"box-cursor\" | \"box-select\" | \"camera\" | \"caret-left\" | \"check\" | \"check-circle\" | \"caret-right\" | \"chevron-down\" | \"chevron-left\" | \"chevron-right\" | \"chevron-up\" | \"circle-outline\" | \"close-circle-fill\" | \"close-circle\" | \"collapse-all\" | \"columns\" | \"comment-add\" | \"comment-filled\" | \"comment-reopen\" | \"comment-resolve\" | \"comment-show\" | \"cross-section\" | \"cube-orthographic\" | \"cube-perspective\" | \"delete\" | \"drag-indicator\" | \"error-circle\" | \"expand-all\" | \"export\" | \"file\" | \"file-pdf\" | \"fit-all\" | \"fit-selected\" | \"folder-plus\" | \"forward\" | \"gear\" | \"invert\" | \"line-dot-left\" | \"line-dot-right\" | \"line-hash-left\" | \"line-hash-right\" | \"locate\" | \"markup\" | \"notification\" | \"open-window\" | \"pan\" | \"pencil\" | \"person-height\" | \"person-run\" | \"person-short\" | \"person-tall\" | \"person-walk\" | \"pin-fill\" | \"pin-line\" | \"pin-text\" | \"pin-text-fill\" | \"pin-text-square\" | \"plus\" | \"pmi\" | \"precise-measurement\" | \"rabbit\" | \"ruler\" | \"show-only-nearby\" | \"snapshots\" | \"star\" | \"tape-measure\" | \"teleport-and-align\" | \"teleport-toward\" | \"teleport\" | \"turtle\" | \"version-history\" | \"visibility-hidden\" | \"visibility-partial\" | \"visibility-visible\" | \"zoom\"",
36
+ "resolved": "\"compare\" | \"help\" | \"open\" | \"info\" | \"copy\" | \"menu\" | \"ellipse\" | \"line\" | \"download\" | \"rotate\" | \"close\" | \"flip\" | \"reset\" | \"resize\" | \"search\" | \"caret-down\" | \"caret-up\" | \"adjustments\" | \"align-to-global\" | \"align-to-part\" | \"align-to-surface\" | \"align-view-to-plane\" | \"annotation\" | \"arrow-filled\" | \"arrow-line-left\" | \"arrow-line-right\" | \"arrow-partial\" | \"arrow-triangle-left\" | \"arrow-triangle-right\" | \"arrow-up-circled\" | \"attachment\" | \"axis-x\" | \"axis-y\" | \"axis-z\" | \"back\" | \"box-cursor\" | \"box-select\" | \"camera\" | \"caret-left\" | \"check\" | \"check-circle\" | \"caret-right\" | \"chevron-down\" | \"chevron-left\" | \"chevron-right\" | \"chevron-up\" | \"circle-outline\" | \"close-circle-fill\" | \"close-circle\" | \"collapse-all\" | \"columns\" | \"comment-add\" | \"comment-filled\" | \"comment-reopen\" | \"comment-resolve\" | \"comment-show\" | \"cross-section\" | \"cube-orthographic\" | \"cube-perspective\" | \"delete\" | \"drag-indicator\" | \"error-circle\" | \"expand-all\" | \"export\" | \"file\" | \"file-pdf\" | \"fit-all\" | \"fit-selected\" | \"folder-plus\" | \"forward\" | \"gear\" | \"invert\" | \"line-dot-left\" | \"line-dot-right\" | \"line-hash-left\" | \"line-hash-right\" | \"locate\" | \"markup\" | \"notification\" | \"open-window\" | \"pan\" | \"pencil\" | \"person-height\" | \"person-run\" | \"person-short\" | \"person-tall\" | \"person-walk\" | \"pin-fill\" | \"pin-line\" | \"pin-text\" | \"pin-text-fill\" | \"pin-text-square\" | \"plus\" | \"pmi\" | \"precise-measurement\" | \"rabbit\" | \"ruler\" | \"show-only-nearby\" | \"snapshots\" | \"star\" | \"tape-measure\" | \"teleport-and-align\" | \"teleport-toward\" | \"teleport\" | \"turtle\" | \"version-history\" | \"views\" | \"visibility-hidden\" | \"visibility-partial\" | \"visibility-visible\" | \"zoom\"",
37
37
  "references": {
38
38
  "IconName": {
39
39
  "location": "import",
@@ -0,0 +1,2 @@
1
+ import { h } from '@stencil/core';
2
+ export const Views = () => (h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", "data-testid": "views" }, h("path", { d: "M12.49 5.97v-.03c0-.07-.02-.13-.05-.19a.27.27 0 0 0-.07-.08.284.284 0 0 0-.1-.09c-.02-.01-.02-.03-.04-.04L8.27 3.56a.508.508 0 0 0-.45 0L3.9 5.51c-.11.03-.21.11-.28.22l-.02.02-.01.02c-.03.07-.05.13-.05.2 0 .01-.01.02-.01.04v4.63c0 .19.11.36.28.45l4 1.99h.01a.465.465 0 0 0 .42 0h.01l3.97-1.96a.5.5 0 0 0 .28-.45L12.48 6l.01-.03ZM8.04 4.55l2.84 1.42-2.83 1.45-2.88-1.44 2.87-1.43ZM4.53 6.78l3 1.5v3.52l-3-1.5V6.77v.01Zm4.01 5.02V8.29l2.96-1.51v3.55L8.54 11.8ZM1.5 5c-.28 0-.5-.22-.5-.5V1h3.5c.28 0 .5.22.5.5s-.22.5-.5.5H2v2.5c0 .28-.22.5-.5.5Zm0 5.99c-.28 0-.5.22-.5.5v3.5h3.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5H2v-2.5c0-.28-.22-.5-.5-.5ZM14.5 5c.28 0 .5-.22.5-.5V1h-3.5c-.28 0-.5.22-.5.5s.22.5.5.5H14v2.5c0 .28.22.5.5.5Zm0 5.99c.28 0 .5.22.5.5v3.5h-3.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5H14v-2.5c0-.28.22-.5.5-.5Z" })));
@@ -50,7 +50,7 @@ export class IconButton {
50
50
  "mutable": false,
51
51
  "complexType": {
52
52
  "original": "IconName",
53
- "resolved": "\"compare\" | \"help\" | \"open\" | \"info\" | \"copy\" | \"menu\" | \"ellipse\" | \"line\" | \"download\" | \"rotate\" | \"close\" | \"flip\" | \"reset\" | \"resize\" | \"search\" | \"caret-down\" | \"caret-up\" | \"adjustments\" | \"align-to-global\" | \"align-to-part\" | \"align-to-surface\" | \"align-view-to-plane\" | \"annotation\" | \"arrow-filled\" | \"arrow-line-left\" | \"arrow-line-right\" | \"arrow-partial\" | \"arrow-triangle-left\" | \"arrow-triangle-right\" | \"arrow-up-circled\" | \"attachment\" | \"axis-x\" | \"axis-y\" | \"axis-z\" | \"back\" | \"box-cursor\" | \"box-select\" | \"camera\" | \"caret-left\" | \"check\" | \"check-circle\" | \"caret-right\" | \"chevron-down\" | \"chevron-left\" | \"chevron-right\" | \"chevron-up\" | \"circle-outline\" | \"close-circle-fill\" | \"close-circle\" | \"collapse-all\" | \"columns\" | \"comment-add\" | \"comment-filled\" | \"comment-reopen\" | \"comment-resolve\" | \"comment-show\" | \"cross-section\" | \"cube-orthographic\" | \"cube-perspective\" | \"delete\" | \"drag-indicator\" | \"error-circle\" | \"expand-all\" | \"export\" | \"file\" | \"file-pdf\" | \"fit-all\" | \"fit-selected\" | \"folder-plus\" | \"forward\" | \"gear\" | \"invert\" | \"line-dot-left\" | \"line-dot-right\" | \"line-hash-left\" | \"line-hash-right\" | \"locate\" | \"markup\" | \"notification\" | \"open-window\" | \"pan\" | \"pencil\" | \"person-height\" | \"person-run\" | \"person-short\" | \"person-tall\" | \"person-walk\" | \"pin-fill\" | \"pin-line\" | \"pin-text\" | \"pin-text-fill\" | \"pin-text-square\" | \"plus\" | \"pmi\" | \"precise-measurement\" | \"rabbit\" | \"ruler\" | \"show-only-nearby\" | \"snapshots\" | \"star\" | \"tape-measure\" | \"teleport-and-align\" | \"teleport-toward\" | \"teleport\" | \"turtle\" | \"version-history\" | \"visibility-hidden\" | \"visibility-partial\" | \"visibility-visible\" | \"zoom\"",
53
+ "resolved": "\"compare\" | \"help\" | \"open\" | \"info\" | \"copy\" | \"menu\" | \"ellipse\" | \"line\" | \"download\" | \"rotate\" | \"close\" | \"flip\" | \"reset\" | \"resize\" | \"search\" | \"caret-down\" | \"caret-up\" | \"adjustments\" | \"align-to-global\" | \"align-to-part\" | \"align-to-surface\" | \"align-view-to-plane\" | \"annotation\" | \"arrow-filled\" | \"arrow-line-left\" | \"arrow-line-right\" | \"arrow-partial\" | \"arrow-triangle-left\" | \"arrow-triangle-right\" | \"arrow-up-circled\" | \"attachment\" | \"axis-x\" | \"axis-y\" | \"axis-z\" | \"back\" | \"box-cursor\" | \"box-select\" | \"camera\" | \"caret-left\" | \"check\" | \"check-circle\" | \"caret-right\" | \"chevron-down\" | \"chevron-left\" | \"chevron-right\" | \"chevron-up\" | \"circle-outline\" | \"close-circle-fill\" | \"close-circle\" | \"collapse-all\" | \"columns\" | \"comment-add\" | \"comment-filled\" | \"comment-reopen\" | \"comment-resolve\" | \"comment-show\" | \"cross-section\" | \"cube-orthographic\" | \"cube-perspective\" | \"delete\" | \"drag-indicator\" | \"error-circle\" | \"expand-all\" | \"export\" | \"file\" | \"file-pdf\" | \"fit-all\" | \"fit-selected\" | \"folder-plus\" | \"forward\" | \"gear\" | \"invert\" | \"line-dot-left\" | \"line-dot-right\" | \"line-hash-left\" | \"line-hash-right\" | \"locate\" | \"markup\" | \"notification\" | \"open-window\" | \"pan\" | \"pencil\" | \"person-height\" | \"person-run\" | \"person-short\" | \"person-tall\" | \"person-walk\" | \"pin-fill\" | \"pin-line\" | \"pin-text\" | \"pin-text-fill\" | \"pin-text-square\" | \"plus\" | \"pmi\" | \"precise-measurement\" | \"rabbit\" | \"ruler\" | \"show-only-nearby\" | \"snapshots\" | \"star\" | \"tape-measure\" | \"teleport-and-align\" | \"teleport-toward\" | \"teleport\" | \"turtle\" | \"version-history\" | \"views\" | \"visibility-hidden\" | \"visibility-partial\" | \"visibility-visible\" | \"zoom\"",
54
54
  "references": {
55
55
  "IconName": {
56
56
  "location": "import",
@@ -4,9 +4,26 @@ export const getWindowSelection = () => {
4
4
  }
5
5
  return undefined;
6
6
  };
7
+ export const nodeHasChildNodes = (node) => {
8
+ return node.hasChildNodes();
9
+ };
7
10
  export const createDocumentRange = () => {
8
11
  return document.createRange();
9
12
  };
10
13
  export const createTextNode = (text) => {
11
14
  return new Text(text);
12
15
  };
16
+ export const createBreak = () => {
17
+ return document.createElement('br');
18
+ };
19
+ export const createWrappingDiv = (nodes) => {
20
+ const el = document.createElement('div');
21
+ el.append(...nodes);
22
+ return el;
23
+ };
24
+ export const isHtmlElement = (node) => {
25
+ return node instanceof HTMLElement;
26
+ };
27
+ export const isBrElement = (node) => {
28
+ return node instanceof HTMLBRElement;
29
+ };
@@ -1,4 +1,4 @@
1
- import { createTextNode } from './dom';
1
+ import { createBreak, createTextNode } from './dom';
2
2
  export const createResultUri = (result) => {
3
3
  return `${result.type}:${result.id}`;
4
4
  };
@@ -8,15 +8,56 @@ export const createSearchResultReplacement = (result, before, after) => {
8
8
  before: createTextNode(before),
9
9
  beforeSpace: createTextNode(createHairSpace()),
10
10
  result: createTextNode(urn),
11
- afterSpace: after != null ? createTextNode(createNoBreakSpace()) : undefined,
11
+ afterSpace: after != null
12
+ ? createTextNode(createNoBreakSpace())
13
+ : createTextNode(createHairSpace()),
12
14
  after: after != null ? createTextNode(after) : undefined,
13
15
  };
14
16
  };
15
- export const getNodesForSearchResultReplacement = (replacement) => {
17
+ /**
18
+ * Newline characters and spaces are represented slightly differently within a
19
+ * content editable element between browsers. This method standardizes the
20
+ * representation of those characters to avoid having to write branching logic
21
+ * to support each individual browser.
22
+ */
23
+ export const standardizeNewlinesAndSpaces = (node) => {
24
+ const content = node.textContent;
25
+ if (content === '\n') {
26
+ return [createBreak()];
27
+ }
28
+ else if (content != null && content.includes('\n')) {
29
+ const split = content.split('\n');
30
+ return split.reduce((res, substr, i) => {
31
+ const previous = split[i - 1];
32
+ // Ignore the empty string if the prior element was converted
33
+ // to a breaking element to prevent duplication of newlines.
34
+ if (substr === '' && previous !== '') {
35
+ return res;
36
+ }
37
+ return [
38
+ ...res,
39
+ // Standard spaces are not always respected with in `Text`
40
+ // elements when appended to a contenteditable element. This
41
+ // conversion preserves that spacing.
42
+ createTextNode(substr.replace(/ /g, createNoBreakSpace())),
43
+ createBreak(),
44
+ ];
45
+ }, []);
46
+ }
47
+ return [node];
48
+ };
49
+ export const getNodesForSearchResultReplacement = (replacement, isBreaking = false) => {
16
50
  const keys = Object.keys(replacement);
17
- return keys
51
+ const replacementElements = keys
18
52
  .map((key) => replacement[key])
19
53
  .filter((node) => node != null);
54
+ // If the element is intended to replace a breaking element such
55
+ // as a `<div>` wrapper, a newline is required alongside the standard
56
+ // replacement elements.
57
+ if (isBreaking) {
58
+ return [createTextNode('\n'), ...replacementElements];
59
+ }
60
+ return replacementElements;
20
61
  };
21
62
  /**
22
63
  * We leverage a couple unique spaces to represent mentions, allowing for