@salesforcedevs/dx-components 0.10.1-alpha.143 → 0.10.1-alpha.147

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dx-components",
3
- "version": "0.10.1-alpha.143",
3
+ "version": "0.10.1-alpha.147",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -1,11 +1,11 @@
1
- import { LightningElement, api, track } from "lwc";
1
+ import { LightningElement, api, wire, track } from "lwc";
2
2
  import { CodeBlockTheme, CodeBlockLanguage } from "typings/custom";
3
3
  import cx from "classnames";
4
- // import Prism from "utils/prismjs";
5
- // import {
6
- // getLocalStorageData,
7
- // setLocalStorageData
8
- // } from "@sfdocs-internal/wires";
4
+ import Prism from "utils/prismjs";
5
+ import {
6
+ getLocalStorageData,
7
+ setLocalStorageData
8
+ } from "@sfdocs-internal/wires";
9
9
  import { track as gtmTrack } from "dx/instrumentation";
10
10
 
11
11
  // Used por remove enclosing <pre> tag's (if occurs)
@@ -13,8 +13,8 @@ const preTagRegexp: RegExp = /^<pre.*?>(.*)<\/pre>$/is;
13
13
 
14
14
  const LIGHT = "light";
15
15
  const DARK = "dark";
16
- // const themes: CodeBlockTheme[] = [LIGHT, DARK];
17
- // const LOCAL_STORAGE_KEY = "dx-codeblock-theme";
16
+ const themes: CodeBlockTheme[] = [LIGHT, DARK];
17
+ const LOCAL_STORAGE_KEY = "dx-codeblock-theme";
18
18
 
19
19
  export default class CodeBlock extends LightningElement {
20
20
  @api defaultTheme: CodeBlockTheme = LIGHT;
@@ -69,17 +69,17 @@ export default class CodeBlock extends LightningElement {
69
69
 
70
70
  @track private theme: CodeBlockTheme | null = null;
71
71
 
72
- // @wire(getLocalStorageData, { key: "dx-codeblock-theme" })
73
- // updateThemeForCodeblock(value: any) {
74
- // if (themes.includes(value)) {
75
- // this.theme = value;
76
- // } else {
77
- // setLocalStorageData(
78
- // LOCAL_STORAGE_KEY,
79
- // this.theme || this.defaultTheme
80
- // );
81
- // }
82
- // }
72
+ @wire(getLocalStorageData, { key: "dx-codeblock-theme" })
73
+ updateThemeForCodeblock(value: any) {
74
+ if (themes.includes(value)) {
75
+ this.theme = value;
76
+ } else {
77
+ setLocalStorageData(
78
+ LOCAL_STORAGE_KEY,
79
+ this.theme || this.defaultTheme
80
+ );
81
+ }
82
+ }
83
83
 
84
84
  get updateThemeBtnText(): string {
85
85
  return `Switch to ${this.theme === DARK ? "Light" : "Dark"} mode`;
@@ -134,7 +134,7 @@ export default class CodeBlock extends LightningElement {
134
134
  // eslint-disable-next-line
135
135
  codeBlockEl.innerHTML = "";
136
136
  codeBlockEl.appendChild(codeEl);
137
- // Prism.highlightAllUnder(codeBlockEl);
137
+ Prism.highlightAllUnder(codeBlockEl);
138
138
  });
139
139
 
140
140
  if (divEl) {
@@ -192,7 +192,7 @@ export default class CodeBlock extends LightningElement {
192
192
 
193
193
  updateTheme(event: any) {
194
194
  this.theme = this.theme === DARK ? LIGHT : DARK;
195
- // setLocalStorageData(LOCAL_STORAGE_KEY, this.theme);
195
+ setLocalStorageData(LOCAL_STORAGE_KEY, this.theme);
196
196
 
197
197
  gtmTrack(event.target, "custEv_codeBlock", {
198
198
  codeBlockAction: this.theme === DARK ? "darkmode" : "lightmode"
@@ -5,6 +5,7 @@ import Sidebar from "dx/sidebar";
5
5
  import Tree from "dx/tree";
6
6
  import { createMediaMock } from "utils/jest";
7
7
  import { createRenderComponent } from "utils/tests";
8
+ import { coveoXMLDocsConfig } from "utils/coveo";
8
9
  import { SAMPLE_TREES } from "./mockProps";
9
10
 
10
11
  jest.mock("dx/instrumentation");
@@ -28,38 +29,31 @@ describe(TAG, () => {
28
29
  const expectedTitle = "Super cool title";
29
30
  const component = renderComponent({
30
31
  header: expectedTitle,
31
- trees: SAMPLE_TREES
32
+ trees: SAMPLE_TREES,
33
+ ...coveoXMLDocsConfig
32
34
  });
33
35
 
34
- expect(component.trees).toEqual(SAMPLE_TREES);
35
-
36
- const container: HTMLElement = component.shadowRoot.querySelector(
37
- ".container"
38
- );
36
+ const container: HTMLElement =
37
+ component.shadowRoot.querySelector(".container");
39
38
  expect(container).not.toBeNull();
40
39
  expect(container.classList).not.toContain(COLLAPSED_CLASS);
41
40
 
42
- const headerTitle: HTMLElement = component.shadowRoot.querySelector(
43
- ".header h2"
44
- );
41
+ const headerTitle: HTMLElement =
42
+ component.shadowRoot.querySelector(".header h2");
45
43
  expect(headerTitle).not.toBeNull();
46
44
  expect(headerTitle.textContent).toBe(expectedTitle);
47
45
 
48
- const collapseButton: Button = component.shadowRoot.querySelector(
49
- "dx-button"
50
- );
46
+ const collapseButton: Button =
47
+ component.shadowRoot.querySelector("dx-button");
51
48
  expect(collapseButton).not.toBeNull();
52
49
  expect(collapseButton.iconSymbol).toBe("close_panel");
53
50
 
54
- const searchBox: Input = component.shadowRoot.querySelector(
55
- "dx-input"
56
- );
57
- expect(searchBox).not.toBeNull();
58
- expect(searchBox.value).toBe("");
51
+ const search: Input =
52
+ component.shadowRoot.querySelector("dx-sidebar-search");
53
+ expect(search).not.toBeNull();
59
54
 
60
- const trees: Array<Tree> = component.shadowRoot.querySelectorAll(
61
- "dx-tree"
62
- );
55
+ const trees: Array<Tree> =
56
+ component.shadowRoot.querySelectorAll("dx-tree");
63
57
  expect(trees).toHaveLength(SAMPLE_TREES.length);
64
58
  trees.forEach((tree, index) =>
65
59
  expect(tree.treeRoot).toHaveProperty(
@@ -89,38 +83,31 @@ describe(TAG, () => {
89
83
  const expectedTitle = "Other super cool title";
90
84
  const component = renderComponent({
91
85
  header: expectedTitle,
92
- trees: JSON.stringify(SAMPLE_TREES)
86
+ trees: JSON.stringify(SAMPLE_TREES),
87
+ ...coveoXMLDocsConfig
93
88
  });
94
89
 
95
- expect(component.trees).toEqual(SAMPLE_TREES);
96
-
97
- const container: HTMLElement = component.shadowRoot.querySelector(
98
- ".container"
99
- );
90
+ const container: HTMLElement =
91
+ component.shadowRoot.querySelector(".container");
100
92
  expect(container).not.toBeNull();
101
93
  expect(container.classList).not.toContain(COLLAPSED_CLASS);
102
94
 
103
- const headerTitle: HTMLElement = component.shadowRoot.querySelector(
104
- ".header h2"
105
- );
95
+ const headerTitle: HTMLElement =
96
+ component.shadowRoot.querySelector(".header h2");
106
97
  expect(headerTitle).not.toBeNull();
107
98
  expect(headerTitle.textContent).toBe(expectedTitle);
108
99
 
109
- const collapseButton: Button = component.shadowRoot.querySelector(
110
- "dx-button"
111
- );
100
+ const collapseButton: Button =
101
+ component.shadowRoot.querySelector("dx-button");
112
102
  expect(collapseButton).not.toBeNull();
113
103
  expect(collapseButton.iconSymbol).toBe("close_panel");
114
104
 
115
- const searchBox: Input = component.shadowRoot.querySelector(
116
- "dx-input"
117
- );
118
- expect(searchBox).not.toBeNull();
119
- expect(searchBox.value).toBe("");
105
+ const search: Input =
106
+ component.shadowRoot.querySelector("dx-sidebar-search");
107
+ expect(search).not.toBeNull();
120
108
 
121
- const trees: Array<Tree> = component.shadowRoot.querySelectorAll(
122
- "dx-tree"
123
- );
109
+ const trees: Array<Tree> =
110
+ component.shadowRoot.querySelectorAll("dx-tree");
124
111
  expect(trees).toHaveLength(SAMPLE_TREES.length);
125
112
  trees.forEach((tree, index) =>
126
113
  expect(tree.treeRoot).toHaveProperty(
@@ -138,12 +125,12 @@ describe(TAG, () => {
138
125
  const component = renderComponent({
139
126
  header: "Non visible title",
140
127
  trees: SAMPLE_TREES,
141
- value: testValue
128
+ value: testValue,
129
+ ...coveoXMLDocsConfig
142
130
  });
143
131
 
144
- const trees: Array<Tree> = component.shadowRoot.querySelectorAll(
145
- "dx-tree"
146
- );
132
+ const trees: Array<Tree> =
133
+ component.shadowRoot.querySelectorAll("dx-tree");
147
134
 
148
135
  expect(trees).toHaveLength(SAMPLE_TREES.length);
149
136
  trees.forEach((tree) => expect(tree.value).toBe(testValue));
@@ -156,15 +143,14 @@ describe(TAG, () => {
156
143
  it("should expand/collapse sidebar when toggle button is clicked", () => {
157
144
  const component = renderComponent({
158
145
  header: "Cool Title",
159
- trees: SAMPLE_TREES
146
+ trees: SAMPLE_TREES,
147
+ ...coveoXMLDocsConfig
160
148
  });
161
149
 
162
- const container: HTMLElement = component.shadowRoot.querySelector(
163
- ".container"
164
- );
165
- const toggleButton: HTMLElement = component.shadowRoot.querySelector(
166
- "dx-button"
167
- );
150
+ const container: HTMLElement =
151
+ component.shadowRoot.querySelector(".container");
152
+ const toggleButton: HTMLElement =
153
+ component.shadowRoot.querySelector("dx-button");
168
154
  toggleButton.click();
169
155
 
170
156
  expect(track).toBeCalledTimes(1);
@@ -177,26 +163,10 @@ describe(TAG, () => {
177
163
  .then(() => {
178
164
  expect(container.classList).toContain(COLLAPSED_CLASS);
179
165
 
180
- const headerTitle: HTMLElement = component.shadowRoot.querySelector(
181
- ".header h2"
182
- );
183
- expect(headerTitle).toBeNull();
184
-
185
- const expandButton: Button = component.shadowRoot.querySelector(
186
- "dx-button"
187
- );
166
+ const expandButton: Button =
167
+ component.shadowRoot.querySelector("dx-button");
188
168
  expect(expandButton).not.toBeNull();
189
169
 
190
- const searchBox: Input = component.shadowRoot.querySelector(
191
- "dx-input"
192
- );
193
- expect(searchBox).toBeNull();
194
-
195
- const trees: Tree = component.shadowRoot.querySelector(
196
- "dx-tree"
197
- );
198
- expect(trees).toBeNull();
199
-
200
170
  toggleButton.click();
201
171
 
202
172
  expect(track).toBeCalledTimes(2);
@@ -214,21 +184,6 @@ describe(TAG, () => {
214
184
  COLLAPSED_CLASS
215
185
  );
216
186
 
217
- const headerTitle: HTMLElement = component.shadowRoot.querySelector(
218
- ".header h2"
219
- );
220
- expect(headerTitle).not.toBeNull();
221
-
222
- const searchBox: Input = component.shadowRoot.querySelector(
223
- "dx-input"
224
- );
225
- expect(searchBox).not.toBeNull();
226
-
227
- const trees: Tree = component.shadowRoot.querySelector(
228
- "dx-tree"
229
- );
230
- expect(trees).not.toBeNull();
231
-
232
187
  return expect(component).toBeAccessible();
233
188
  });
234
189
  });
@@ -236,15 +191,14 @@ describe(TAG, () => {
236
191
  it("should make hover effect on toggle button hover", () => {
237
192
  const component = renderComponent({
238
193
  header: "Cool Title",
239
- trees: SAMPLE_TREES
194
+ trees: SAMPLE_TREES,
195
+ ...coveoXMLDocsConfig
240
196
  });
241
197
 
242
- const container: HTMLElement = component.shadowRoot.querySelector(
243
- ".container"
244
- );
245
- const toggleButton: Button = component.shadowRoot.querySelector(
246
- "dx-button"
247
- );
198
+ const container: HTMLElement =
199
+ component.shadowRoot.querySelector(".container");
200
+ const toggleButton: Button =
201
+ component.shadowRoot.querySelector("dx-button");
248
202
 
249
203
  expect(container.classList).not.toContain(
250
204
  "container-border-active"
@@ -283,42 +237,14 @@ describe(TAG, () => {
283
237
 
284
238
  describe("render", () => {
285
239
  it("should render as collapsed", () => {
286
- const expectedTitle = SAMPLE_TREES[0].label;
287
240
  const component = renderComponent({
288
- trees: SAMPLE_TREES
241
+ trees: SAMPLE_TREES,
242
+ ...coveoXMLDocsConfig
289
243
  });
290
244
 
291
- const headerTitle: HTMLElement = component.shadowRoot.querySelector(
292
- ".header span.header-title"
293
- );
294
- expect(headerTitle).not.toBeNull();
295
- expect(headerTitle.textContent).toBe(expectedTitle);
296
-
297
- const headerIcon = component.shadowRoot.querySelector(
298
- ".header .header-toggle-icon dx-icon"
299
- );
300
- expect(headerIcon).not.toBeNull();
301
-
302
- const searchBox: Input = component.shadowRoot.querySelector(
303
- "dx-input"
304
- );
305
- expect(searchBox).toBeNull();
306
-
307
- const trees: Tree = component.shadowRoot.querySelector(
308
- "dx-tree"
309
- );
310
- expect(trees).toBeNull();
311
-
312
- // Desktop specific elements should not render
313
- const headerTitleDesktop = component.shadowRoot.querySelector(
314
- ".header h2.header-title"
315
- );
316
- expect(headerTitleDesktop).toBeNull();
317
-
318
- const toggleButtonDesktop = component.shadowRoot.querySelector(
319
- "dx-button.header-toggle-button"
320
- );
321
- expect(toggleButtonDesktop).toBeNull();
245
+ const container: HTMLElement =
246
+ component.shadowRoot.querySelector(".container");
247
+ expect(container.classList).toContain(COLLAPSED_CLASS);
322
248
 
323
249
  expect(window.matchMedia).toBeCalledTimes(1);
324
250
  expect(window.matchMedia).toBeCalledWith(EXPECTED_QUERY);
@@ -329,17 +255,18 @@ describe(TAG, () => {
329
255
  it("should ignore null values for trees api", () => {
330
256
  const component = renderComponent({
331
257
  header: "Cool Title",
332
- trees: null
258
+ trees: null,
259
+ ...coveoXMLDocsConfig
333
260
  });
334
261
 
335
- const tree: Tree = component.shadowRoot.querySelector(
336
- "dx-tree"
337
- );
262
+ const tree: Tree =
263
+ component.shadowRoot.querySelector("dx-tree");
338
264
  expect(tree).toBeNull();
339
265
 
340
- const headerTitle: HTMLElement = component.shadowRoot.querySelector(
341
- ".header span.header-title"
342
- );
266
+ const headerTitle: HTMLElement =
267
+ component.shadowRoot.querySelector(
268
+ ".header span.header-title"
269
+ );
343
270
  expect(headerTitle).not.toBeNull();
344
271
  expect(headerTitle.textContent).toBe("");
345
272
  });
@@ -349,15 +276,14 @@ describe(TAG, () => {
349
276
  it("should expand/collapse sidebar when mobile toggle is clicked", () => {
350
277
  const expectedTitle = SAMPLE_TREES[0].label;
351
278
  const component = renderComponent({
352
- trees: SAMPLE_TREES
279
+ trees: SAMPLE_TREES,
280
+ ...coveoXMLDocsConfig
353
281
  });
354
282
 
355
- const container: HTMLElement = component.shadowRoot.querySelector(
356
- ".container"
357
- );
358
- const toggleDiv: HTMLElement = component.shadowRoot.querySelector(
359
- "div.header"
360
- );
283
+ const container: HTMLElement =
284
+ component.shadowRoot.querySelector(".container");
285
+ const toggleDiv: HTMLElement =
286
+ component.shadowRoot.querySelector("div.header");
361
287
  toggleDiv.click();
362
288
 
363
289
  expect(track).toBeCalledTimes(1);
@@ -371,9 +297,10 @@ describe(TAG, () => {
371
297
  expect(container.classList).not.toContain(
372
298
  COLLAPSED_CLASS
373
299
  );
374
- const headerTitle: HTMLElement = component.shadowRoot.querySelector(
375
- ".header span.header-title"
376
- );
300
+ const headerTitle: HTMLElement =
301
+ component.shadowRoot.querySelector(
302
+ ".header span.header-title"
303
+ );
377
304
  expect(headerTitle).not.toBeNull();
378
305
  expect(headerTitle.textContent).toBe(expectedTitle);
379
306
 
@@ -382,15 +309,14 @@ describe(TAG, () => {
382
309
  );
383
310
  expect(headerIcon).not.toBeNull();
384
311
 
385
- const searchBox: Input = component.shadowRoot.querySelector(
386
- "dx-input"
387
- );
388
- expect(searchBox).not.toBeNull();
389
- expect(searchBox.value).toBe("");
312
+ const search: HTMLElement =
313
+ component.shadowRoot.querySelector(
314
+ "dx-sidebar-search"
315
+ );
316
+ expect(search).not.toBeNull();
390
317
 
391
- const trees: Array<Tree> = component.shadowRoot.querySelectorAll(
392
- "dx-tree"
393
- );
318
+ const trees: Array<Tree> =
319
+ component.shadowRoot.querySelectorAll("dx-tree");
394
320
  expect(trees).toHaveLength(SAMPLE_TREES.length);
395
321
  trees.forEach((tree, index) =>
396
322
  expect(tree.treeRoot).toHaveProperty(
@@ -400,14 +326,16 @@ describe(TAG, () => {
400
326
  );
401
327
 
402
328
  // Desktop specific elements should not render
403
- const headerTitleDesktop = component.shadowRoot.querySelector(
404
- ".header h2.header-title"
405
- );
329
+ const headerTitleDesktop =
330
+ component.shadowRoot.querySelector(
331
+ ".header h2.header-title"
332
+ );
406
333
  expect(headerTitleDesktop).toBeNull();
407
334
 
408
- const toggleButtonDesktop = component.shadowRoot.querySelector(
409
- "dx-button.header-toggle-button"
410
- );
335
+ const toggleButtonDesktop =
336
+ component.shadowRoot.querySelector(
337
+ "dx-button.header-toggle-button"
338
+ );
411
339
  expect(toggleButtonDesktop).toBeNull();
412
340
 
413
341
  toggleDiv.click();
@@ -433,12 +361,12 @@ describe(TAG, () => {
433
361
  const defaultTitle = SAMPLE_TREES[0].label;
434
362
  const itemToSelect = SAMPLE_TREES[0].children![2];
435
363
  const component = renderComponent({
436
- trees: SAMPLE_TREES
364
+ trees: SAMPLE_TREES,
365
+ ...coveoXMLDocsConfig
437
366
  });
438
367
 
439
- const toggleDiv: HTMLElement = component.shadowRoot.querySelector(
440
- "div.header"
441
- );
368
+ const toggleDiv: HTMLElement =
369
+ component.shadowRoot.querySelector("div.header");
442
370
  const headerTitle: HTMLElement = toggleDiv.querySelector(
443
371
  ".header span.header-title"
444
372
  )!;
@@ -450,9 +378,8 @@ describe(TAG, () => {
450
378
  expect(headerTitle).not.toBeNull();
451
379
  expect(headerTitle.textContent).toBe(defaultTitle);
452
380
 
453
- const tree: Tree = component.shadowRoot.querySelector(
454
- "dx-tree"
455
- );
381
+ const tree: Tree =
382
+ component.shadowRoot.querySelector("dx-tree");
456
383
  tree.dispatchEvent(
457
384
  new CustomEvent("select", {
458
385
  detail: { name: itemToSelect.name }
@@ -475,12 +402,12 @@ describe(TAG, () => {
475
402
  const [expectedTree] = SAMPLE_TREES;
476
403
  const component = renderComponent({
477
404
  header: "Cool Title",
478
- trees: expectedTree
405
+ trees: expectedTree,
406
+ ...coveoXMLDocsConfig
479
407
  });
480
408
 
481
- const trees: Array<Tree> = component.shadowRoot.querySelectorAll(
482
- "dx-tree"
483
- );
409
+ const trees: Array<Tree> =
410
+ component.shadowRoot.querySelectorAll("dx-tree");
484
411
  expect(trees).toHaveLength(1);
485
412
 
486
413
  const [singleTree] = trees;
@@ -498,14 +425,14 @@ describe(TAG, () => {
498
425
 
499
426
  const component = renderComponent({
500
427
  header: "Cool Title",
501
- trees: SAMPLE_TREES
428
+ trees: SAMPLE_TREES,
429
+ ...coveoXMLDocsConfig
502
430
  });
503
431
 
504
432
  component.addEventListener("select", mockSelect);
505
433
 
506
- const tree: Tree = component.shadowRoot.querySelector(
507
- "dx-tree"
508
- );
434
+ const tree: Tree =
435
+ component.shadowRoot.querySelector("dx-tree");
509
436
  expect(tree).not.toBeNull();
510
437
  expect(tree.value).toBeUndefined();
511
438
 
@@ -520,11 +447,8 @@ describe(TAG, () => {
520
447
  return Promise.resolve().then(() => {
521
448
  expect(tree.value).toBe(expectedName);
522
449
  expect(mockSelect).toBeCalledTimes(1);
523
- const {
524
- detail,
525
- composed,
526
- bubbles
527
- } = mockSelect.mock.calls[0][0];
450
+ const { detail, composed, bubbles } =
451
+ mockSelect.mock.calls[0][0];
528
452
  expect(detail).toEqual({
529
453
  name: expectedName
530
454
  });
@@ -48,7 +48,7 @@ export default class Sidebar extends LightningElement {
48
48
  setInputValue(searchTerm: string) {
49
49
  this.template
50
50
  .querySelector("dx-sidebar-search")
51
- .setInputValue(searchTerm);
51
+ ?.setInputValue(searchTerm);
52
52
  }
53
53
 
54
54
  private expanded: boolean = true;
@@ -187,6 +187,7 @@ export default class Sidebar extends LightningElement {
187
187
  }
188
188
 
189
189
  private onSearchChange(e: CustomEvent) {
190
+ console.log(e)
190
191
  this.requestedFetchMoreResults = false;
191
192
  this.searchResults = e.detail.results;
192
193
  this.searchValue = e.detail.value;
@@ -50,7 +50,7 @@ export default class SidebarSearch extends LightningElement {
50
50
  // set adnvanced filters needs access to the latest coveoAdvancedQueryConfig
51
51
  this.dispatchOnLoading(true);
52
52
  this.setAdvancedFilters(this.engine);
53
- this.submitSearch();
53
+ this.submitSearch(true);
54
54
  }
55
55
  }
56
56
 
@@ -65,6 +65,7 @@ export default class SidebarSearch extends LightningElement {
65
65
  @api
66
66
  setInputValue(searchTerm: string) {
67
67
  this.value = searchTerm || "";
68
+ this.handleValueChange(true);
68
69
  }
69
70
 
70
71
  private _coveoAdvancedQueryConfig!: { [key: string]: any };
@@ -154,10 +155,6 @@ export default class SidebarSearch extends LightningElement {
154
155
  );
155
156
  const hasSameQuery = json?.state?.query?.q === this.value;
156
157
  if (hasSameConfig && hasSameQuery) {
157
- console.log(
158
- "valid session storage found for value =",
159
- this.value
160
- );
161
158
  this.preloadedState = json?.state;
162
159
  } else {
163
160
  window.sessionStorage.removeItem(SESSION_KEY);
@@ -231,16 +228,10 @@ export default class SidebarSearch extends LightningElement {
231
228
 
232
229
  if ((!firstSearchExecuted && !isLoading) || !this.value) {
233
230
  // coveo search is firing off some unwanted payloads on startup
234
- console.log(
235
- "returning in results list change",
236
- this.value,
237
- !firstSearchExecuted && !isLoading
238
- );
239
231
  return;
240
232
  }
241
233
 
242
234
  if (!isLoading) {
243
- console.log("dispatching on change event");
244
235
  this.dispatchOnChangeEvent(results);
245
236
  }
246
237
 
@@ -254,7 +245,6 @@ export default class SidebarSearch extends LightningElement {
254
245
  };
255
246
 
256
247
  private setAdvancedFilters(engine: SearchEngine) {
257
- console.log("setting advanced filters");
258
248
  const aq = Object.entries(this.coveoAdvancedQueryConfig).reduce(
259
249
  (result, [key, value]) =>
260
250
  `${result}(@${key}=="${normalizeCoveoAdvancedQueryValue(
@@ -281,9 +271,14 @@ export default class SidebarSearch extends LightningElement {
281
271
  titleHighlights,
282
272
  uniqueId
283
273
  }: Result) => {
274
+ // discussion about this normalization here: https://salesforce-internal.slack.com/archives/C020S6784JX/p1639506238376600
275
+ const extension =
276
+ this.coveoAdvancedQueryConfig.path_segment_4 === "references"
277
+ ? ""
278
+ : ".html";
284
279
  const pathname = sfhtml_url__c
285
280
  ? `/docs/${sfhtml_url__c}`
286
- : `${new URL(clickUri).pathname}.html`;
281
+ : `${new URL(clickUri).pathname}${extension}`;
287
282
  const href = `${pathname}?q=${this.value}`;
288
283
 
289
284
  return {
@@ -320,7 +315,6 @@ export default class SidebarSearch extends LightningElement {
320
315
  }
321
316
 
322
317
  private dispatchOnLoading(loading: boolean) {
323
- console.log("dispatching onloading", loading);
324
318
  this.dispatchEvent(new CustomEvent("loading", { detail: loading }));
325
319
  }
326
320
 
@@ -352,11 +346,16 @@ export default class SidebarSearch extends LightningElement {
352
346
  );
353
347
  }
354
348
 
355
- private submitSearch = debounce(() => {
349
+ private submitSearch = debounce((isSyncingSearchValue = false) => {
356
350
  if (this.searchBox) {
357
351
  UserRecentSearches.add(this.value);
358
352
  this.updateRecentSearches();
359
- this.dispatchSidebarSearchChange(this.value);
353
+
354
+ // When `isSyncingSearchValue` is true, we are submitting in a case
355
+ // where the search box is already synced correctly.
356
+ if (!isSyncingSearchValue) {
357
+ this.dispatchSidebarSearchChange(this.value);
358
+ }
360
359
 
361
360
  this.searchBox.updateText(this.value || "");
362
361
  this.searchBox.submit();
@@ -366,7 +365,7 @@ export default class SidebarSearch extends LightningElement {
366
365
  private onClickRecentSearch(e: CustomEvent) {
367
366
  this.value = e.detail;
368
367
  this.dispatchSidebarSearchChange(this.value);
369
- this.submitSearch();
368
+ this.submitSearch(true);
370
369
  }
371
370
 
372
371
  private onDropdownRequestClose(e: CustomEvent) {
@@ -383,26 +382,32 @@ export default class SidebarSearch extends LightningElement {
383
382
  private onInputChange(e: CustomEvent) {
384
383
  this.value = e.detail;
385
384
 
385
+ this.handleValueChange(false);
386
+ this.dispatchHighlightedTermChange();
387
+ }
388
+
389
+ private onInputFocus() {
390
+ this.dropdownRequestedOpen = true;
391
+ }
392
+
393
+ private onInputClear() {
394
+ this.dropdownRequestedOpen = false;
395
+ }
396
+
397
+ private handleValueChange(isSyncingSearchValue = false) {
386
398
  if (this.value) {
387
399
  this.dispatchOnLoading(true);
388
400
  if (this.searchBox) {
389
- this.submitSearch();
401
+ this.submitSearch(isSyncingSearchValue);
390
402
  }
391
403
  } else {
392
404
  // coveo's reaction to an empty value triggers a return of results
393
405
  // bootlegging our own ux here`
394
406
  this.dispatchOnLoading(false);
395
407
  this.dispatchOnChangeEvent([]);
408
+ // Empty search values are not submitted for search, so we need to manually
409
+ // trigger a search change on our own here
410
+ this.dispatchSidebarSearchChange(this.value);
396
411
  }
397
-
398
- this.dispatchHighlightedTermChange();
399
- }
400
-
401
- private onInputFocus() {
402
- this.dropdownRequestedOpen = true;
403
- }
404
-
405
- private onInputClear() {
406
- this.dropdownRequestedOpen = false;
407
412
  }
408
413
  }
@@ -6,7 +6,6 @@ import { TreeHandler } from "./treeHandler";
6
6
  export default class Tree extends LightningElement {
7
7
  @api
8
8
  get treeRoot() {
9
- console.log(this._treeRoot!);
10
9
  return this._treeRoot!;
11
10
  }
12
11
 
@@ -24,23 +24,20 @@ describe(TAG, () => {
24
24
  describe("render", () => {
25
25
  it("should render as a leaf tile", () => {
26
26
  const component = render({ treeNode: SINGLE_NODE, href: "/test" });
27
- const tileAnchor: HTMLElement = component.shadowRoot.querySelector(
28
- "a.tile"
29
- );
27
+ const tileAnchor: HTMLElement =
28
+ component.shadowRoot.querySelector("a.tile");
30
29
 
31
30
  expect(tileAnchor.getAttribute("href")).toBe("/test");
32
- expect(tileAnchor.classList).toHaveLength(1);
31
+ expect(tileAnchor.classList).toHaveLength(2);
33
32
  expect(tileAnchor).not.toBeNull();
34
33
  assertLevelAndLabel(tileAnchor);
35
34
 
36
- const arrowIcon: Icon = component.shadowRoot.querySelector(
37
- "dx-icon"
38
- );
35
+ const arrowIcon: Icon =
36
+ component.shadowRoot.querySelector("dx-icon");
39
37
  expect(arrowIcon).toBeNull();
40
38
 
41
- const typeBadge = component.shadowRoot.querySelector(
42
- "dx-type-badge"
43
- );
39
+ const typeBadge =
40
+ component.shadowRoot.querySelector("dx-type-badge");
44
41
  expect(typeBadge).toBeNull();
45
42
 
46
43
  return expect(component).toBeAccessible();
@@ -52,23 +49,20 @@ describe(TAG, () => {
52
49
  isRoot: true,
53
50
  hasChildren: true
54
51
  });
55
- const tileAnchor: HTMLElement = component.shadowRoot.querySelector(
56
- "a.tile.tile-root"
57
- );
52
+ const tileAnchor: HTMLElement =
53
+ component.shadowRoot.querySelector("a.tile.tile-root");
58
54
  expect(tileAnchor).not.toBeNull();
59
- expect(tileAnchor.classList).toHaveLength(2);
55
+ expect(tileAnchor.classList).toHaveLength(3);
60
56
  assertLevelAndLabel(tileAnchor);
61
57
 
62
- const arrowIcon: Icon = component.shadowRoot.querySelector(
63
- "dx-icon"
64
- )!;
58
+ const arrowIcon: Icon =
59
+ component.shadowRoot.querySelector("dx-icon")!;
65
60
  expect(arrowIcon).not.toBeNull();
66
61
  expect(arrowIcon.getAttribute("aria-expanded")).toBe("false");
67
62
  expect(arrowIcon.size).toBe("small");
68
63
 
69
- const typeBadge = component.shadowRoot.querySelector(
70
- "dx-type-badge"
71
- );
64
+ const typeBadge =
65
+ component.shadowRoot.querySelector("dx-type-badge");
72
66
  expect(typeBadge).toBeNull();
73
67
 
74
68
  return expect(component).toBeAccessible();
@@ -85,19 +79,17 @@ describe(TAG, () => {
85
79
  );
86
80
 
87
81
  expect(tileAnchor).not.toBeNull();
88
- expect(tileAnchor.classList).toHaveLength(2);
82
+ expect(tileAnchor.classList).toHaveLength(3);
89
83
  assertLevelAndLabel(tileAnchor);
90
84
 
91
- const arrowIcon: Icon = component.shadowRoot.querySelector(
92
- "dx-icon"
93
- );
85
+ const arrowIcon: Icon =
86
+ component.shadowRoot.querySelector("dx-icon");
94
87
  expect(arrowIcon).not.toBeNull();
95
88
  expect(arrowIcon.getAttribute("aria-expanded")).toBe("true");
96
89
  expect(arrowIcon.size).toBe("xsmall");
97
90
 
98
- const typeBadge = component.shadowRoot.querySelector(
99
- "dx-type-badge"
100
- );
91
+ const typeBadge =
92
+ component.shadowRoot.querySelector("dx-type-badge");
101
93
  expect(typeBadge).toBeNull();
102
94
 
103
95
  return expect(component).toBeAccessible();
@@ -112,16 +104,15 @@ describe(TAG, () => {
112
104
  "a.tile.sidebar-item-selected"
113
105
  );
114
106
  expect(tileAnchor).not.toBeNull();
115
- expect(tileAnchor.classList).toHaveLength(2);
107
+ expect(tileAnchor.classList).toHaveLength(3);
116
108
 
117
109
  return expect(component).toBeAccessible();
118
110
  });
119
111
 
120
112
  it("should render a leaf tile with a valid brand method", () => {
121
113
  const component = render({ treeNode: SINGLE_NODE_WITH_METHOD });
122
- const typeBadge = component.shadowRoot.querySelector(
123
- "dx-type-badge"
124
- );
114
+ const typeBadge =
115
+ component.shadowRoot.querySelector("dx-type-badge");
125
116
 
126
117
  expect(typeBadge).not.toBeNull();
127
118
  expect(typeBadge.classList).toHaveLength(3);
@@ -140,9 +131,8 @@ describe(TAG, () => {
140
131
  const component = render({
141
132
  treeNode: { ...SINGLE_NODE_WITH_METHOD, method }
142
133
  });
143
- const typeBadge = component.shadowRoot.querySelector(
144
- "dx-type-badge"
145
- );
134
+ const typeBadge =
135
+ component.shadowRoot.querySelector("dx-type-badge");
146
136
 
147
137
  expect(typeBadge).not.toBeNull();
148
138
  expect(typeBadge.classList).toHaveLength(3);
@@ -163,9 +153,8 @@ describe(TAG, () => {
163
153
  isExpanded: true
164
154
  });
165
155
 
166
- const arrowIcon: HTMLElement = component.shadowRoot.querySelector(
167
- "dx-icon"
168
- );
156
+ const arrowIcon: HTMLElement =
157
+ component.shadowRoot.querySelector("dx-icon");
169
158
 
170
159
  const mockIconClick = jest.fn();
171
160
  component.addEventListener("iconclick", mockIconClick);