@salesforcedevs/dx-components 1.3.53-alpha → 1.3.53

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 (66) hide show
  1. package/lwc.config.json +2 -0
  2. package/package.json +7 -3
  3. package/src/assets/icons/salesforcebrand-sprite/svg/symbols.svg +125 -7
  4. package/src/assets/svg/privacyicon.png +0 -0
  5. package/src/modules/dx/banner/banner.ts +1 -1
  6. package/src/modules/dx/cardBlogPost/cardBlogPost.html +1 -3
  7. package/src/modules/dx/cardBlogPost/cardBlogPost.ts +1 -3
  8. package/src/modules/dx/cardContent/cardContent.css +5 -0
  9. package/src/modules/dx/cardContent/cardContent.html +10 -6
  10. package/src/modules/dx/cardContent/cardContent.ts +22 -7
  11. package/src/modules/dx/cardExpanded/cardExpanded.css +15 -5
  12. package/src/modules/dx/cardExpanded/cardExpanded.html +9 -5
  13. package/src/modules/dx/cardExpanded/cardExpanded.ts +24 -8
  14. package/src/modules/dx/cardNews/cardNews.css +14 -0
  15. package/src/modules/dx/cardNews/cardNews.ts +2 -1
  16. package/src/modules/dx/cardTrial/cardTrial.html +2 -0
  17. package/src/modules/dx/cardTrial/cardTrial.ts +32 -1
  18. package/src/modules/dx/cardTrialExpanded/cardTrialExpanded.css +5 -0
  19. package/src/modules/dx/cardTrialExpanded/cardTrialExpanded.html +1 -0
  20. package/src/modules/dx/cardTrialExpanded/cardTrialExpanded.ts +13 -0
  21. package/src/modules/dx/codeBlock/codeBlock.ts +6 -1
  22. package/src/modules/dx/codeBlock/darkTheme.css +8 -1
  23. package/src/modules/dx/codeBlock/lightTheme.css +8 -2
  24. package/src/modules/dx/dropdownOption/dropdownOption.html +2 -2
  25. package/src/modules/dx/featuredContentHeader/featuredContentHeader.css +18 -10
  26. package/src/modules/dx/featuredContentHeader/featuredContentHeader.html +109 -107
  27. package/src/modules/dx/featuredContentHeader/featuredContentHeader.ts +17 -9
  28. package/src/modules/dx/footer/footer.css +9 -0
  29. package/src/modules/dx/footer/footer.html +6 -0
  30. package/src/modules/dx/footer/footer.ts +5 -2
  31. package/src/modules/dx/footer/links.ts +11 -0
  32. package/src/modules/dx/formattedDateTime/formattedDateTime.ts +3 -3
  33. package/src/modules/dx/header/header.html +2 -2
  34. package/src/modules/dx/header/header.ts +4 -0
  35. package/src/modules/dx/headerSearch/headerSearch.html +0 -2
  36. package/src/modules/dx/headerSearch/headerSearch.ts +0 -1
  37. package/src/modules/dx/hr/hr.css +0 -3
  38. package/src/modules/dx/hr/hr.ts +7 -1
  39. package/src/modules/dx/input/input.ts +0 -2
  40. package/src/modules/dx/mainContentHeader/mainContentHeader.css +102 -0
  41. package/src/modules/dx/mainContentHeader/mainContentHeader.html +23 -0
  42. package/src/modules/dx/mainContentHeader/mainContentHeader.ts +35 -0
  43. package/src/modules/dx/scrollManager/scrollManager.html +1 -0
  44. package/src/modules/dx/scrollManager/scrollManager.ts +110 -0
  45. package/src/modules/dx/searchResults/searchResults.css +2 -2
  46. package/src/modules/dx/section/section.css +9 -0
  47. package/src/modules/dx/section/section.html +10 -0
  48. package/src/modules/dx/section/section.ts +5 -0
  49. package/src/modules/dx/sidebar/sidebar.css +4 -0
  50. package/src/modules/dx/sidebar/sidebar.html +1 -0
  51. package/src/modules/dx/sidebar/sidebar.ts +8 -0
  52. package/src/modules/dx/sidebarOld/sidebarOld.ts +2 -0
  53. package/src/modules/dx/sidebarSearch/sidebarSearch.html +0 -1
  54. package/src/modules/dx/sidebarSearch/sidebarSearch.ts +5 -1
  55. package/src/modules/dx/tbidAvatarButton/tbidAvatarButton.css +2 -2
  56. package/src/modules/dx/tbidAvatarButton/tbidAvatarButton.ts +3 -2
  57. package/src/modules/dx/toc/toc.ts +13 -0
  58. package/src/modules/dx/treeItem/treeItem.html +3 -2
  59. package/src/modules/dx/treeItem/treeItem.ts +18 -8
  60. package/src/modules/dx/typeBadge/typeBadge.ts +2 -2
  61. package/src/modules/dxBaseElements/headerBase/headerBase.ts +18 -8
  62. package/src/modules/dxHelpers/card/card.css +4 -0
  63. package/src/modules/dxHelpers/table/table.css +1 -10
  64. package/src/modules/dxUtils/dates/dates.ts +22 -1
  65. package/src/modules/dxUtils/normalizers/normalizers.ts +1 -3
  66. package/src/modules/dxUtils/prismjs/prismjs.ts +132 -14
@@ -1,4 +1,5 @@
1
1
  import { LightningElement, api } from "lwc";
2
+ import { convertForDaylightSavings } from "dxUtils/dates";
2
3
  import {
3
4
  formattedDateDay,
4
5
  formattedDateHour,
@@ -27,7 +28,7 @@ export default class FormattedDateTime extends LightningElement {
27
28
  return;
28
29
  }
29
30
 
30
- this._unformattedDate = new Date(value);
31
+ this._unformattedDate = convertForDaylightSavings(value).toJSDate();
31
32
 
32
33
  if (this._unformattedDate.toString() === "Invalid Date") {
33
34
  // this is a fix for Safari since it doesn't support date strings with 'yyyy/mm/dd' patterns
@@ -62,7 +63,7 @@ export default class FormattedDateTime extends LightningElement {
62
63
  }
63
64
 
64
65
  getOptions() {
65
- const options = {
66
+ return {
66
67
  weekday: this.weekday || undefined,
67
68
  year: this.year || undefined,
68
69
  month: this.month || undefined,
@@ -72,6 +73,5 @@ export default class FormattedDateTime extends LightningElement {
72
73
  second: this.second,
73
74
  timeZoneName: this.timeZoneName || undefined
74
75
  };
75
- return options;
76
76
  }
77
77
  }
@@ -3,7 +3,7 @@
3
3
  <header class={className}>
4
4
  <dx-skip-nav-link></dx-skip-nav-link>
5
5
  <dx-banner
6
- if:true={bannerMarkup}
6
+ if:true={showBanner}
7
7
  banner-markup={bannerMarkup}
8
8
  ></dx-banner>
9
9
  <div class="header_l1">
@@ -39,7 +39,7 @@
39
39
  </div>
40
40
  <div class="header_l2">
41
41
  <div class="header_l2_group header_l2_group-title">
42
- <a href="/" class="home-link">
42
+ <a href="/" class="home-link" if:true={isValidSubtitle}>
43
43
  <dx-icon
44
44
  class="brand-icon"
45
45
  if:true={isValidBrand}
@@ -14,4 +14,8 @@ export default class Header extends HeaderBase {
14
14
  protected mobileBreakpoint(): string {
15
15
  return "768px";
16
16
  }
17
+
18
+ get isValidSubtitle() {
19
+ return this.isValidBrand || this.subtitle;
20
+ }
17
21
  }
@@ -20,7 +20,6 @@
20
20
  onclear={onInputEscape}
21
21
  onsubmit={onInputSubmit}
22
22
  onfocus={openDropdown}
23
- onblur={onDropdownRequestClose}
24
23
  placeholder="Search"
25
24
  size="override"
26
25
  type="search"
@@ -52,7 +51,6 @@
52
51
  onclear={onInputEscape}
53
52
  onsubmit={onInputSubmit}
54
53
  onfocus={openDropdown}
55
- onblur={onDropdownRequestClose}
56
54
  placeholder="Search"
57
55
  shortcut-key="k"
58
56
  size="small"
@@ -69,7 +69,6 @@ export default class HeaderSearch extends LightningElement {
69
69
  switch (e.detail as PopoverRequestCloseType) {
70
70
  case "interact-outside":
71
71
  case "keypress-escape":
72
- case "input-blur":
73
72
  this.closeDropdown();
74
73
  break;
75
74
  default:
@@ -9,7 +9,6 @@ p,
9
9
  h2 {
10
10
  display: flex;
11
11
  flex-direction: row;
12
- padding: 0 var(--dx-c-hr-padding-horizontal);
13
12
  font-family: var(--dx-g-font-display);
14
13
  font-size: var(--dx-g-text-sm);
15
14
  color: var(--dx-g-blue-vibrant-20);
@@ -42,14 +41,12 @@ dx-button {
42
41
  display: flex;
43
42
  width: 100%;
44
43
  text-transform: capitalize;
45
- padding: 0 var(--dx-c-hr-padding-horizontal);
46
44
  }
47
45
 
48
46
  dx-button::before {
49
47
  content: "";
50
48
  border-bottom: 2px solid var(--dx-g-gray-95);
51
49
  flex: 1 1;
52
- transform: translateY(-2px); /* offset for display font ghost padding */
53
50
  margin: auto;
54
51
  margin-right: var(--dx-g-spacing-md);
55
52
  }
@@ -7,6 +7,7 @@ export default class Hr extends LightningElement {
7
7
  @api href?: string | null;
8
8
  @api target: string | null = "_top";
9
9
  @api spacing: string | null = "2xl";
10
+ @api noPadding: boolean = false;
10
11
  @api variant: HrVariant | null = null;
11
12
 
12
13
  private get ariaRole() {
@@ -14,9 +15,14 @@ export default class Hr extends LightningElement {
14
15
  }
15
16
 
16
17
  private get style() {
17
- return this.spacing
18
+ const spacing = this.spacing
18
19
  ? `margin: var(--dx-g-spacing-${this.spacing}) 0;`
19
20
  : "";
21
+ const padding = this.noPadding
22
+ ? ""
23
+ : "padding: 0 var(--dx-c-hr-padding-horizontal);";
24
+
25
+ return `${spacing}${padding}`;
20
26
  }
21
27
 
22
28
  private get isButtonVariant() {
@@ -186,8 +186,6 @@ export default class Input extends LightningElement {
186
186
  if (this.validityOnBlur) {
187
187
  this.reportValidity();
188
188
  }
189
-
190
- this.dispatchEvent(new CustomEvent("blur", { detail: "input-blur" }));
191
189
  }
192
190
 
193
191
  onInputChange(e: InputEvent) {
@@ -0,0 +1,102 @@
1
+ @import "dxHelpers/reset";
2
+ @import "dxHelpers/text";
3
+
4
+ .container {
5
+ display: flex;
6
+ flex-direction: row;
7
+ padding: 0 var(--dx-g-page-padding-horizontal);
8
+ overflow: hidden;
9
+ }
10
+
11
+ .container > * {
12
+ width: 50%;
13
+ }
14
+
15
+ .text-container {
16
+ display: flex;
17
+ flex-direction: column;
18
+ justify-content: center;
19
+ align-items: flex-start;
20
+ padding: var(--dx-g-spacing-lg) 0;
21
+ min-height: 460px;
22
+ text-align: left;
23
+ background-position: center;
24
+ background-size: cover;
25
+ background-repeat: no-repeat;
26
+ }
27
+
28
+ .image-container {
29
+ display: flex;
30
+ flex-direction: row;
31
+ justify-content: flex-start;
32
+ overflow: visible;
33
+ }
34
+
35
+ img {
36
+ width: 100%;
37
+ }
38
+
39
+ img.desktop {
40
+ min-width: 876px;
41
+ margin-left: var(--dx-g-spacing-lg);
42
+ }
43
+
44
+ img.mobile {
45
+ display: none;
46
+ min-width: 1024px;
47
+ }
48
+
49
+ .text-container > *:not(:last-child) {
50
+ margin-bottom: var(--dx-g-spacing-smd);
51
+ }
52
+
53
+ dx-button {
54
+ margin-top: var(--dx-g-spacing-smd);
55
+ }
56
+
57
+ @media screen and (max-width: 1024px) {
58
+ .container {
59
+ flex-direction: column;
60
+ }
61
+
62
+ .container > * {
63
+ width: 100%;
64
+ }
65
+
66
+ .text-container {
67
+ align-items: center;
68
+ text-align: center;
69
+ padding-top: var(--dx-g-spacing-4xl);
70
+ padding-bottom: 0;
71
+ min-height: unset;
72
+ }
73
+
74
+ .text-container > * {
75
+ max-width: 700px;
76
+ }
77
+
78
+ .image-container {
79
+ justify-content: center;
80
+ }
81
+
82
+ img.desktop {
83
+ display: none;
84
+ }
85
+
86
+ img.mobile {
87
+ display: block;
88
+ }
89
+ }
90
+
91
+ @media screen and (max-width: 768px) {
92
+ .body,
93
+ .subtitle {
94
+ font-size: var(--dx-g-text-base);
95
+ line-height: var(--dx-g-text-xl);
96
+ }
97
+
98
+ .heading {
99
+ font-size: var(--dx-g-text-3xl);
100
+ line-height: var(--dx-g-text-4xl);
101
+ }
102
+ }
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <div class="container" style={style}>
3
+ <div class="text-container">
4
+ <h1 class="heading dx-text-heading-2">{title}</h1>
5
+ <span class="body dx-text-body-1">{body}</span>
6
+ <span if:true={subtitle} class="subtitle dx-text-heading-4b">
7
+ {subtitle}
8
+ </span>
9
+ <dx-button
10
+ onclick={onCtaClick}
11
+ href={ctaHref}
12
+ target={ctaTarget}
13
+ size="large"
14
+ >
15
+ {ctaLabel}
16
+ </dx-button>
17
+ </div>
18
+ <div class="image-container">
19
+ <img class="desktop" src={imgSrc} />
20
+ <img class="mobile" src={imgSrcMobile} />
21
+ </div>
22
+ </div>
23
+ </template>
@@ -0,0 +1,35 @@
1
+ import { LightningElement, api } from "lwc";
2
+ import cx from "classnames";
3
+ import { track } from "dxUtils/analytics";
4
+
5
+ export default class MainContentHeader extends LightningElement {
6
+ @api title!: string;
7
+ @api subtitle?: string;
8
+ @api body!: string;
9
+ @api ctaLabel!: string;
10
+ @api ctaHref!: string;
11
+ @api imgSrc!: string;
12
+ @api imgSrcMobile!: string;
13
+ @api ctaTarget?: string | null = null;
14
+ @api backgroundGradientColor?: string;
15
+
16
+ private get style() {
17
+ return cx(
18
+ this.backgroundGradientColor &&
19
+ `background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #ffff 100%), var(--dx-g-${this.backgroundGradientColor});`
20
+ );
21
+ }
22
+
23
+ private onCtaClick(e: Event) {
24
+ if (e.currentTarget) {
25
+ track(e.currentTarget, "custEv_ctaButtonClick", {
26
+ clickText: this.ctaLabel,
27
+ itemTitle: this.title,
28
+ clickUrl: this.ctaHref,
29
+ elementType: "button",
30
+ destinationType: "internal",
31
+ ctaClick: true
32
+ });
33
+ }
34
+ }
35
+ }
@@ -0,0 +1 @@
1
+ <template></template>
@@ -0,0 +1,110 @@
1
+ import { LightningElement } from "lwc";
2
+ import { throttle } from "throttle-debounce";
3
+
4
+ const RESTORE_SCROLL_EVENT_NAME = "restore-scroll";
5
+ const LOAD_TIME_SCROLL_RESTORE_DELAY = 750;
6
+
7
+ declare module globalThis {
8
+ let singletonScrollManagerRendered: boolean;
9
+ let singletonScrollManagerConnected: boolean;
10
+ }
11
+ // mostly components shouldn't be using this, but there are a few exceptions such as amfReference
12
+
13
+ let scrollUnlocked: boolean = false;
14
+
15
+ export const restoreScroll = () => {
16
+ if (scrollUnlocked) {
17
+ return;
18
+ }
19
+ document.body.scrollTop = document.documentElement.scrollTop =
20
+ window.history.state?.scroll.value;
21
+ };
22
+
23
+ export default class ScrollManager extends LightningElement {
24
+ /*
25
+ WARNING: Dark Magic(TM) follows. This code is likely to be unreliable if:
26
+ - Our load times significantly change (in this case, LOAD_TIME_SCROLL_RESTORE_DELAY may need to be adjusted)
27
+ - Any other components attempt to manipulate the body scroll (including #a links) before LOAD_TIME_SCROLL_RESTORE_DELAY has expired
28
+
29
+ This Dark Magic(TM) was required because of the following super annoying race condition occuring while trying to restore scroll position:
30
+ 1. Load a page on our site (reproducible consistently at time of writing at https://developer.salesforce.com)
31
+ 2. Scroll down somewhere (remember where)
32
+ 3. Navigate to another page
33
+ 4. Navigate back/forward/back, using the browser forward/back buttons (sometimes it takes a few tries to reproduce the race condition)
34
+ 5. If the page you're on takes long enough for its components to finish rendering asynchronously, sometimes your scroll position will be incorrect
35
+ (until the second scroll restore is called. To see the really bad behavior, simply remove the window.setTimeout bit)
36
+ This is because basically it scrolls you down a bit, then a component gets bigger above you as it finishes rendering
37
+ This pushes your whole view down, so unless we do this Dark Magic(TM) where we attempt to restore scroll _again_
38
+ after some reasonable interval, your window will be in the wrong spot when everything finishes rendering
39
+ */
40
+
41
+ protected scrollCount = 0; // this is for dark magic, basically we lock the user out of scrolling in the first quarter second, unless they really mean it. We do this because load timings mean that the scroll can get messed up in that period
42
+
43
+ renderedCallback() {
44
+ scrollUnlocked = window.location.hash !== ""; // if we have anchor links, skip the entire scroll restore
45
+ if (!globalThis.singletonScrollManagerRendered && !scrollUnlocked) {
46
+ globalThis.singletonScrollManagerRendered = true;
47
+ if (
48
+ window.history.state?.scroll?.docSize ===
49
+ document.body.scrollHeight
50
+ ) {
51
+ // only do this if loading is complete and the scrollHeight matches expectations
52
+ // otherwise, we're likely still loading, so just chill to avoid jumping around so much
53
+ restoreScroll();
54
+ } else {
55
+ window.setTimeout(() => {
56
+ // sometimes loading is slow, so we may want to reset the scroll to
57
+ // the correct position after loading is complete, to avoid weird behavior
58
+ // but only if the user hasn't scrolled around in the meantime
59
+ restoreScroll();
60
+ scrollUnlocked = true;
61
+ }, LOAD_TIME_SCROLL_RESTORE_DELAY);
62
+ }
63
+ } else {
64
+ console.error(
65
+ "Multiple <dx-scroll-manager>s detected, this should never be the case."
66
+ );
67
+ }
68
+ }
69
+
70
+ connectedCallback(): void {
71
+ if (!globalThis.singletonScrollManagerConnected) {
72
+ globalThis.singletonScrollManagerConnected = true;
73
+ window.addEventListener(RESTORE_SCROLL_EVENT_NAME, restoreScroll);
74
+
75
+ document.body.addEventListener("scroll", this.manualScrollListener);
76
+ } else {
77
+ console.error(
78
+ "Multiple <dx-scroll-manager>s detected, this should never be the case."
79
+ );
80
+ }
81
+ }
82
+
83
+ saveScroll = throttle(100, () => {
84
+ window.history.replaceState(
85
+ {
86
+ scroll: {
87
+ value: document.body.scrollTop,
88
+ docSize: document.body.scrollHeight
89
+ }
90
+ },
91
+ "",
92
+ window.location.href
93
+ );
94
+ });
95
+
96
+ manualScrollListener = () => {
97
+ if (this.scrollCount < 5) {
98
+ this.scrollCount++;
99
+ } else {
100
+ this.scrollUnlocked = true;
101
+ }
102
+ if (this.scrollUnlocked) {
103
+ this.saveScroll();
104
+ }
105
+ };
106
+
107
+ disconnectedCallback(): void {
108
+ window.removeEventListener(RESTORE_SCROLL_EVENT_NAME, restoreScroll);
109
+ }
110
+ }
@@ -197,8 +197,8 @@ li.coveo-dynamic-facet-breadcrumb-value-list-item {
197
197
 
198
198
  .CoveoSort.coveo-selected,
199
199
  .CoveoSort.coveo-selected:hover {
200
- color: var(--dx-g-blue-vibrant-50);
201
- border-bottom-color: var(--dx-g-blue-vibrant-50);
200
+ color: var(--dx-g-blue-vibrant-40);
201
+ border-bottom-color: var(--dx-g-blue-vibrant-40);
202
202
  }
203
203
 
204
204
  .CoveoBreadcrumb {
@@ -9,6 +9,8 @@
9
9
  --dx-c-section-padding-top: var(--dx-c-section-padding-vertical);
10
10
  --dx-c-section-padding-bottom: var(--dx-c-section-padding-vertical);
11
11
  --dx-c-section-heading-margin-bottom: var(--dx-g-spacing-2xl);
12
+ --dx-c-section-cta-color: var(--dx-g-blue-vibrant-50);
13
+ --dx-c-section-cta-inline-hover-color: var(--dx-g-blue-vibrant-30);
12
14
  }
13
15
 
14
16
  .section {
@@ -86,6 +88,13 @@
86
88
  z-index: 50;
87
89
  }
88
90
 
91
+ .cta {
92
+ --dx-c-button-primary-color: var(--dx-c-section-cta-color);
93
+ --dx-c-button-inline-color-hover: var(
94
+ --dx-c-section-cta-inline-hover-color
95
+ );
96
+ }
97
+
89
98
  /* sections with a swoop and center alignment should not left align as it encroaches on the graphic */
90
99
  .section.align-center.graphic-top .text {
91
100
  text-align: center;
@@ -32,6 +32,16 @@
32
32
  <span class="subtitle dx-text-body-1" if:true={subtitle}>
33
33
  {subtitle}
34
34
  </span>
35
+ <dx-button
36
+ class="cta"
37
+ if:true={ctaLabel}
38
+ href={ctaHref}
39
+ variant={ctaBtnVariant}
40
+ icon-symbol={ctaBtnSymbol}
41
+ target={ctaBtnTarget}
42
+ >
43
+ {ctaLabel}
44
+ </dx-button>
35
45
  </div>
36
46
  <div part="content" class="content">
37
47
  <slot></slot>
@@ -10,6 +10,11 @@ export default class Section extends LightningElement {
10
10
  @api subtitle?: string;
11
11
  @api textAlign: "center" | "left" = "left";
12
12
  @api title?: string;
13
+ @api ctaLabel?: string;
14
+ @api ctaHref?: string;
15
+ @api ctaBtnVariant?: string;
16
+ @api ctaBtnSymbol?: string;
17
+ @api ctaBtnTarget?: string = "_self";
13
18
  @api topGraphic: boolean = false;
14
19
  @api graphicOverlap: boolean = false;
15
20
  @api bottomGraphic: boolean = false;
@@ -12,6 +12,10 @@ dx-empty-state {
12
12
  padding-bottom: var(--dx-g-spacing-md);
13
13
  }
14
14
 
15
+ .sidebar-content-tree {
16
+ padding: var(--dx-g-spacing-xs);
17
+ }
18
+
15
19
  .loading-skeleton {
16
20
  margin-top: var(--dx-g-spacing-md);
17
21
  }
@@ -88,6 +88,7 @@
88
88
  tree-root={tree.tree}
89
89
  onselect={onSelect}
90
90
  value={value}
91
+ onfocus={onItemsFocused}
91
92
  onselecteditemrendered={onSelectedItemRendered}
92
93
  ></dx-tree>
93
94
  </div>
@@ -169,6 +169,8 @@ export default class Sidebar extends SidebarBase {
169
169
 
170
170
  private onSelect(event: CustomEvent) {
171
171
  this._value = event.detail.name;
172
+
173
+ this.dispatchEvent(new CustomEvent("sidebarclick"));
172
174
  }
173
175
 
174
176
  private onToggleClick(event: Event) {
@@ -255,4 +257,10 @@ export default class Sidebar extends SidebarBase {
255
257
  node.children.forEach((child) => this.assignValueToLabel(child));
256
258
  }
257
259
  }
260
+
261
+ private onItemsFocused(): void {
262
+ this.template
263
+ .querySelector("dx-sidebar-search")
264
+ ?.requestOpenDropdown(false);
265
+ }
258
266
  }
@@ -95,6 +95,8 @@ export default class Sidebar extends SidebarBase {
95
95
 
96
96
  private onSelect(event: CustomEvent) {
97
97
  this._value = event.detail.name;
98
+
99
+ this.dispatchEvent(new CustomEvent("sidebarclick"));
98
100
  }
99
101
 
100
102
  private onToggleClick(event: Event) {
@@ -18,7 +18,6 @@
18
18
  value={value}
19
19
  onchange={onInputChange}
20
20
  onfocus={onInputFocus}
21
- onblur={onDropdownRequestClose}
22
21
  onclear={onInputClear}
23
22
  shortcut-key="j"
24
23
  clearable
@@ -78,6 +78,11 @@ export default class SidebarSearch extends LightningElement {
78
78
  }
79
79
  }
80
80
 
81
+ @api
82
+ requestOpenDropdown(value: boolean) {
83
+ this.dropdownRequestedOpen = value;
84
+ }
85
+
81
86
  private _coveoAdvancedQueryConfig!: { [key: string]: any };
82
87
  private dropdownRequestedOpen: boolean = false;
83
88
  private recentSearches: Option[] = [];
@@ -422,7 +427,6 @@ export default class SidebarSearch extends LightningElement {
422
427
  switch (e.detail as PopoverRequestCloseType) {
423
428
  case "interact-outside":
424
429
  case "keypress-escape":
425
- case "input-blur":
426
430
  this.dropdownRequestedOpen = false;
427
431
  break;
428
432
  default:
@@ -1,10 +1,10 @@
1
1
  @import "dxHelpers/reset";
2
2
 
3
3
  :host {
4
- --dx-c-button-custom-color: var(--dx-g-blue-vibrant-50);
4
+ --dx-c-button-custom-color: var(--dx-g-blue-vibrant-40);
5
5
  --dx-c-button-custom-background: transparent;
6
6
  --dx-c-button-custom-border: 1px solid transparent;
7
- --dx-c-button-custom-color-hover: var(--dx-g-blue-vibrant-50);
7
+ --dx-c-button-custom-color-hover: var(--dx-g-blue-vibrant-40);
8
8
  --dx-c-button-custom-background-hover: var(--dx-g-cloud-blue-vibrant-90);
9
9
  --dx-c-button-custom-border-hover: var(--dx-g-cloud-blue-vibrant-90);
10
10
  --dx-c-slot-empty-width: max-content;
@@ -49,7 +49,7 @@ export default class TbidAvatarButton extends LightningElement {
49
49
  @api tbidApiBaseUrl = "";
50
50
 
51
51
  @api login = (event: Event) => this.handleComponentLogin(event);
52
- @api logout = () => this.handleComponentLogout();
52
+ @api logout = (event: Event) => this.handleComponentLogout(event);
53
53
 
54
54
  private userInfo: UserInfo = {};
55
55
  private isLoading = false;
@@ -242,7 +242,8 @@ export default class TbidAvatarButton extends LightningElement {
242
242
  private handleSsoLogout = this.handleLogout.bind(this, true);
243
243
 
244
244
  // This handles logout from _within_ this component ("Logout" click), rather than from SSO via the SFIDWidget.
245
- private handleComponentLogout = () => {
245
+ private handleComponentLogout = (event: Event) => {
246
+ event?.preventDefault();
246
247
  this.handleLogout(false);
247
248
  };
248
249
 
@@ -2,6 +2,7 @@ import { LightningElement, api, track } from "lwc";
2
2
  import cx from "classnames";
3
3
  import { ContentElement } from "typings/custom";
4
4
  import { toJson } from "dxUtils/normalizers";
5
+ import { track as sendGtm } from "dxUtils/analytics";
5
6
 
6
7
  export default class Toc extends LightningElement {
7
8
  @api title!: string;
@@ -65,10 +66,22 @@ export default class Toc extends LightningElement {
65
66
  private onClick(e: Event) {
66
67
  const target = e.currentTarget as HTMLElement;
67
68
  const id = target.getAttribute("contentid");
69
+ const text = target.getAttribute("data-text");
70
+ const href = target.getAttribute("href");
71
+
68
72
  this.dispatchEvent(
69
73
  new CustomEvent("selectedcontent", { detail: { name: id } })
70
74
  );
75
+
71
76
  this._value = id!;
77
+
78
+ sendGtm(e.currentTarget!, "custEv_tableOfContentsClick", {
79
+ clickText: text,
80
+ clickUrl: href,
81
+ elementType: "link",
82
+ locationOnPage: "table of contents",
83
+ itemTitle: this.title
84
+ });
72
85
  }
73
86
 
74
87
  private toggleShowContent() {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <a href={href} target={target} onclick={onLinkClick}>
2
+ <a href={href} target={target} onclick={onLinkClick} tabindex="-1">
3
3
  <dx-tree-tile
4
4
  href={href}
5
5
  is-root={isRoot}
@@ -18,12 +18,13 @@
18
18
  src="/assets/svg/sidebar-item-loading.svg"
19
19
  alt="childrenLoading"
20
20
  />
21
- <template if:true={showChildren}>
21
+ <template if:true={showChildren} tabindex="0">
22
22
  <template for:each={treeNode.children} for:item="child">
23
23
  <dx-tree-item
24
24
  key={child.key}
25
25
  tree-node={child}
26
26
  selected-key={selectedKey}
27
+ parent-name={treeNode.label}
27
28
  ></dx-tree-item>
28
29
  </template>
29
30
  </template>