@salesforcedevs/dx-components 1.3.227 → 1.3.228-version-picker2

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/lwc.config.json CHANGED
@@ -77,6 +77,7 @@
77
77
  "dx/select",
78
78
  "dx/sidebar",
79
79
  "dx/sidebarOld",
80
+ "dx/sidebarFooterNav",
80
81
  "dx/skipNavLink",
81
82
  "dx/socials",
82
83
  "dx/spinner",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dx-components",
3
- "version": "1.3.227",
3
+ "version": "1.3.228-version-picker2",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -43,6 +43,5 @@
43
43
  },
44
44
  "volta": {
45
45
  "node": "16.19.1"
46
- },
47
- "gitHead": "ca4d2f11924db69bc1e872fb61587af9bb78cdde"
46
+ }
48
47
  }
@@ -7,7 +7,7 @@
7
7
  aria-label={ariaLabel}
8
8
  part="container"
9
9
  >
10
- <span if:false={loading}>
10
+ <span if:false={loading} part="content">
11
11
  <slot onslotchange={onSlotChange}></slot>
12
12
  </span>
13
13
  <dx-icon
@@ -29,7 +29,7 @@
29
29
  aria-label={ariaLabel}
30
30
  part="container"
31
31
  >
32
- <span if:false={loading}>
32
+ <span if:false={loading} part="content">
33
33
  <slot onslotchange={onSlotChange}></slot>
34
34
  </span>
35
35
  <dx-icon
@@ -80,6 +80,6 @@ export default class Button extends LightningElement {
80
80
 
81
81
  private onSlotChange(e: LightningSlotElement) {
82
82
  const slot = e.target;
83
- this.isSlotEmpty = slot.assignedElements().length !== 0;
83
+ this.isSlotEmpty = slot.assignedNodes().length === 0;
84
84
  }
85
85
  }
@@ -38,7 +38,7 @@
38
38
  }
39
39
 
40
40
  .option:active {
41
- background: var(--dx-g-blue-vibrant-95) !important;
41
+ background: var(--dx-g-cloud-blue-vibrant-95) !important;
42
42
  }
43
43
 
44
44
  .option:not(.option-active):hover {
@@ -46,7 +46,9 @@
46
46
  }
47
47
 
48
48
  .option-active {
49
- background: var(--dx-g-blue-vibrant-95);
49
+ --dx-c-dropdown-option-label-color: var(--dx-g-blue-vibrant-50);
50
+
51
+ background: var(--dx-g-cloud-blue-vibrant-95);
50
52
  }
51
53
 
52
54
  .option_details {
@@ -67,7 +69,7 @@
67
69
  color: var(--dx-c-dropdown-option-label-color, var(--dx-g-blue-vibrant-50));
68
70
  display: flex;
69
71
  align-items: center;
70
- font-weight: var(--dx-g-font-bold);
72
+ font-weight: var(--dx-c-dropdown-option-font-weight, var(--dx-g-font-bold));
71
73
  font-size: var(--dx-c-dropdown-option-font-size, var(--dx-g-text-base));
72
74
  }
73
75
 
@@ -28,7 +28,7 @@
28
28
  max-height: 65vh;
29
29
  padding: var(--popover-padding);
30
30
  overflow-y: auto;
31
- transition: opacity 0.2s linear, transform 0.2s linear;
31
+ transition: var(--popover-transition);
32
32
  transition-delay: 0.02s;
33
33
  transform: translateY(var(--dx-g-spacing-xs));
34
34
  opacity: 0;
@@ -41,7 +41,7 @@
41
41
 
42
42
  .popover-container_open .popover {
43
43
  opacity: 1;
44
- transform: translateY(0);
44
+ transform: var(--popover-container-open-transform);
45
45
  }
46
46
 
47
47
  .popover-overridewidth {
@@ -15,7 +15,7 @@ dx-empty-state {
15
15
 
16
16
  .sidebar-content {
17
17
  overflow-y: auto;
18
- padding-bottom: var(--dx-g-spacing-md);
18
+ padding: var(--dx-g-spacing-sm) 0 var(--dx-g-spacing-md);
19
19
  }
20
20
 
21
21
  .loading-skeleton {
@@ -53,6 +53,13 @@ dx-empty-state {
53
53
  --dx-c-button-secondary-color-hover: var(--dx-g-gray-80);
54
54
  }
55
55
 
56
+ .results-heading {
57
+ --dx-g-text-body-color: var(--sds-g-gray-14);
58
+
59
+ margin-bottom: var(--dx-g-spacing-sm);
60
+ font-weight: var(--dx-g-font-bold);
61
+ }
62
+
56
63
  @media (max-width: 768px) {
57
64
  :host {
58
65
  width: 100%;
@@ -61,8 +68,4 @@ dx-empty-state {
61
68
  .loading-skeleton {
62
69
  width: 100%;
63
70
  }
64
-
65
- .sidebar-content-tree {
66
- padding: 0 var(--dx-g-spacing-sm);
67
- }
68
71
  }
@@ -21,17 +21,14 @@
21
21
  </dx-button>
22
22
  </div>
23
23
  </div>
24
-
25
- <div class="sidebar-header padding-horizontal">
26
- <div class="header" if:false={mobile}>
24
+ <div class="sidebar-header" show-shadow={showBoxShadow}>
25
+ <div class="header padding-horizontal" if:false={mobile}>
27
26
  <h2 class="dx-text-display-6 header-title">{header}</h2>
28
- <slot name="header"></slot>
29
27
  </div>
30
- <div class="mobile-header" if:true={mobile}>
28
+ <div class="mobile-header padding-horizontal" if:true={mobile}>
31
29
  <h2 class="dx-text-display-6">{header}</h2>
32
- <slot name="header"></slot>
33
30
  </div>
34
- <div class="search">
31
+ <div class="search padding-horizontal">
35
32
  <dx-sidebar-search
36
33
  onchange={onSearchChange}
37
34
  onloading={onSearchLoading}
@@ -41,8 +38,9 @@
41
38
  coveo-advanced-query-config={coveoAdvancedQueryConfig}
42
39
  ></dx-sidebar-search>
43
40
  </div>
41
+ <slot name="version-picker"></slot>
44
42
  <h2
45
- class="results-heading dx-text-display-8"
43
+ class="results-heading dx-text-body-3"
46
44
  if:true={showResultsHeading}
47
45
  >
48
46
  Results
@@ -83,7 +81,7 @@
83
81
  size="small"
84
82
  ></dx-empty-state>
85
83
  </div>
86
- <div class="sidebar-content sidebar-content-tree">
84
+ <div class={sidebarContentClass} onscroll={handleScroll}>
87
85
  <dx-tree
88
86
  for:each={trees}
89
87
  for:item="tree"
@@ -95,5 +93,27 @@
95
93
  onselecteditemrendered={onSelectedItemRendered}
96
94
  ></dx-tree>
97
95
  </div>
96
+
97
+ <template if:false={mobile}>
98
+ <div if:true={hasSidebarFooter} class="footer-nav">
99
+ <dx-sidebar-footer-nav
100
+ lang-value-path={langValuePath}
101
+ language={language}
102
+ languages={languages}
103
+ bail-href={bailHref}
104
+ bail-label={bailLabel}
105
+ ></dx-sidebar-footer-nav>
106
+ </div>
107
+ </template>
108
+
109
+ <template if:true={mobile}>
110
+ <div if:true={hasMobileSidebarFooter} class="footer-nav">
111
+ <dx-sidebar-footer-nav
112
+ lang-value-path={langValuePath}
113
+ language={language}
114
+ languages={languages}
115
+ ></dx-sidebar-footer-nav>
116
+ </div>
117
+ </template>
98
118
  </div>
99
119
  </template>
@@ -15,15 +15,6 @@ export default class Sidebar extends SidebarBase {
15
15
  @api coveoAdvancedQueryConfig!: string;
16
16
  @api header: string = "";
17
17
 
18
- @api
19
- get value() {
20
- return this._value;
21
- }
22
-
23
- set value(value) {
24
- this._value = value;
25
- }
26
-
27
18
  @api
28
19
  get trees() {
29
20
  return this._trees;
@@ -52,16 +43,10 @@ export default class Sidebar extends SidebarBase {
52
43
  )?.setInputValue(searchTerm);
53
44
  }
54
45
 
55
- private expanded: boolean = true;
56
- private _value?: string = undefined;
57
-
58
46
  @track
59
47
  private _trees!: Array<TreeNode>;
60
-
61
- private mobile: boolean = true;
62
48
  private matchMedia!: MediaQueryList;
63
49
  private valueToLabel: { [key: string]: string } = {};
64
-
65
50
  private isSearchLoading: boolean = false;
66
51
  private searchValue: string | null = null;
67
52
  private searchResults: SidebarSearchResult[] = [];
@@ -171,32 +156,6 @@ export default class Sidebar extends SidebarBase {
171
156
  this.matchMedia.removeEventListener("change", this.onMediaChange);
172
157
  }
173
158
 
174
- private onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {
175
- this.mobile = event.matches;
176
- this.expanded = !this.mobile;
177
- };
178
-
179
- private onSelect(event: CustomEvent) {
180
- this._value = event.detail.name;
181
-
182
- if (this.mobile) {
183
- this.onToggleClick();
184
- }
185
- }
186
-
187
- private onToggleClick() {
188
- this.expanded = !this.expanded;
189
- this.dispatchEvent(
190
- new CustomEvent("togglesidebar", {
191
- detail: {
192
- open: this.expanded,
193
- bubbles: true,
194
- composed: true
195
- }
196
- })
197
- );
198
- }
199
-
200
159
  private makeKey(): string {
201
160
  return Math.random().toString(36).substring(7);
202
161
  }
@@ -216,7 +175,7 @@ export default class Sidebar extends SidebarBase {
216
175
  this.isSearchLoading = e.detail;
217
176
  }
218
177
 
219
- private onSidebarSearchContentScroll() {
178
+ private onSidebarSearchContentScroll(scrollEvent) {
220
179
  if (this.isSearchLoading) {
221
180
  return;
222
181
  }
@@ -233,6 +192,7 @@ export default class Sidebar extends SidebarBase {
233
192
  this.requestedFetchMoreResults = true;
234
193
  search.fetchMoreResults();
235
194
  }
195
+ this.handleScroll(scrollEvent);
236
196
  }
237
197
 
238
198
  private initializeSearchScrollPosition() {
@@ -0,0 +1,52 @@
1
+ @import "dxHelpers/reset";
2
+
3
+ :host {
4
+ --button-primary-color: var(--dx-g-blue-vibrant-50);
5
+ --button-primary-color-hover: var(--dx-g-cloud-blue-vibrant-95);
6
+ --popover-container-open-transform: translateX(-4px) translateY(-8px);
7
+ --popover-transition: none;
8
+ --dx-c-dropdown-option-font-weight: normal;
9
+ --dx-c-dropdown-option-label-color: var(--dx-g-gray-10);
10
+ }
11
+
12
+ .footer-display {
13
+ display: flex;
14
+ }
15
+
16
+ .footer_lang-dropdown {
17
+ --dx-c-button-primary-color: var(--button-primary-color);
18
+ --border-color: var(--button-primary-color);
19
+
20
+ display: flex;
21
+ padding: 0 var(--dx-g-spacing-md);
22
+ height: var(--dx-g-spacing-xl);
23
+ border-radius: var(--dx-g-spacing-xs);
24
+ align-items: center;
25
+ }
26
+
27
+ .footer_lang-dropdown[aria-expanded="true"] {
28
+ background-color: var(--dx-g-cloud-blue-vibrant-95);
29
+
30
+ --border-color: var(--dx-g-cloud-blue-vibrant-95);
31
+ }
32
+
33
+ .footer_lang-dropdown:hover,
34
+ .footer_lang-dropdown:active,
35
+ .footer_lang-dropdown:focus,
36
+ .pdf_bail-link:hover {
37
+ background-color: var(--button-primary-color-hover);
38
+
39
+ --border-color: var(--button-primary-color-hover);
40
+ }
41
+
42
+ .pdf_bail-link {
43
+ --dx-c-button-horizontal-spacing: var(--dx-g-spacing-sm);
44
+ --dx-c-button-priamry-color-hover: var(--dx-g-cloud-blue-vibrant-95);
45
+
46
+ padding: 0 var(--dx-g-spacing-md);
47
+ border-radius: var(--dx-g-spacing-xs);
48
+ margin-right: var(--dx-g-spacing-sm);
49
+ display: flex;
50
+ height: var(--dx-g-spacing-xl);
51
+ align-items: center;
52
+ }
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <div if:false={mobile} class="footer-display">
3
+ <dx-button
4
+ if:true={hasBailLink}
5
+ aria-label={bailLabel}
6
+ class="pdf_bail-link"
7
+ href={bailHref}
8
+ onclick={handleBailClick}
9
+ variant="inline"
10
+ icon-size="medium"
11
+ icon-symbol="new_window"
12
+ target="_blank"
13
+ >
14
+ {bailLabel}
15
+ </dx-button>
16
+ <dx-dropdown
17
+ if:true={hasLanguages}
18
+ options={languages}
19
+ small
20
+ value-path={langValuePath}
21
+ value={language}
22
+ onchange={onLangChange}
23
+ >
24
+ <dx-button
25
+ class="footer_lang-dropdown"
26
+ aria-label="Select Language"
27
+ variant="inline"
28
+ icon-size="medium"
29
+ icon-symbol="world"
30
+ >
31
+ {languageLabel}
32
+ </dx-button>
33
+ </dx-dropdown>
34
+ </div>
35
+ <div if:true={mobile} class="footer-display">
36
+ <dx-dropdown
37
+ if:true={hasLanguages}
38
+ options={languages}
39
+ small
40
+ value-path={langValuePath}
41
+ value={language}
42
+ onchange={onLangChange}
43
+ >
44
+ <dx-button
45
+ class="footer_lang-dropdown"
46
+ aria-label="Select Language"
47
+ variant="inline"
48
+ icon-size="small"
49
+ icon-symbol="world"
50
+ >
51
+ {languageLabel}
52
+ </dx-button>
53
+ </dx-dropdown>
54
+ </div>
55
+ </template>
@@ -0,0 +1,106 @@
1
+ /* eslint-disable @lwc/lwc/no-document-query */
2
+ import { LightningElement, api } from "lwc";
3
+ import type { OptionWithLink } from "typings/custom";
4
+ import { toJson } from "dxUtils/normalizers";
5
+ import get from "lodash.get";
6
+ import { track } from "dxUtils/analytics";
7
+
8
+ const MOBILE_SIZE_MATCH = "768px";
9
+
10
+ export default class SidebarFooterNav extends LightningElement {
11
+ @api langValuePath: string = "id";
12
+ @api bailHref?: string | null = null;
13
+ @api bailLabel?: string | null = null;
14
+
15
+ @api
16
+ get languages() {
17
+ return this._languages;
18
+ }
19
+
20
+ set languages(value) {
21
+ this._languages = toJson(value);
22
+ }
23
+
24
+ @api
25
+ get language() {
26
+ return this._language;
27
+ }
28
+
29
+ set language(value) {
30
+ this._language = value;
31
+ }
32
+
33
+ private _languages!: OptionWithLink[];
34
+ private _language: string | null = null;
35
+ private mobile: boolean = false;
36
+ private matchMedia!: MediaQueryList;
37
+
38
+ private get hasLanguages(): boolean {
39
+ return this.languages?.length > 1;
40
+ }
41
+
42
+ private get languageLabel(): string {
43
+ const matchingLanguageData = this.language
44
+ ? this.languages.find(
45
+ (lang) => get(lang, this.langValuePath) === this.language
46
+ )
47
+ : null;
48
+ return matchingLanguageData?.label || this.languages[0].label;
49
+ }
50
+
51
+ get hasBailLink(): boolean {
52
+ return !!(this.bailHref && this.bailLabel);
53
+ }
54
+
55
+ private onLangChange(event: CustomEvent<string>): void {
56
+ const { detail } = event;
57
+ this._language = detail;
58
+
59
+ this.dispatchEvent(
60
+ new CustomEvent("langchange", {
61
+ detail,
62
+ bubbles: true,
63
+ composed: true
64
+ })
65
+ );
66
+ }
67
+
68
+ private getFilename = function (path: string) {
69
+ return path.substring(path.lastIndexOf("/") + 1);
70
+ };
71
+
72
+ private handleBailClick(event: Event) {
73
+ const payload = {
74
+ click_text: "pdf",
75
+ click_url: this.bailHref,
76
+ element_title: "pdf",
77
+ element_type: "link",
78
+ content_category: "download"
79
+ };
80
+ track(event.target!, "custEv_pdfDownload", {
81
+ ...payload,
82
+ file_name: this.getFilename(this.bailHref!),
83
+ file_extension: "pdf"
84
+ });
85
+
86
+ track(event.target!, "custEv_linkClick", {
87
+ ...payload
88
+ });
89
+ }
90
+
91
+ connectedCallback() {
92
+ this.matchMedia = window.matchMedia(
93
+ `(max-width: ${MOBILE_SIZE_MATCH})`
94
+ );
95
+ this.onMediaChange(this.matchMedia);
96
+ this.matchMedia.addEventListener("change", this.onMediaChange);
97
+ }
98
+
99
+ disconnectedCallback() {
100
+ this.matchMedia.removeEventListener("change", this.onMediaChange);
101
+ }
102
+
103
+ private onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {
104
+ this.mobile = event.matches;
105
+ };
106
+ }
@@ -2,6 +2,7 @@
2
2
 
3
3
  .sidebar-content {
4
4
  overflow-y: auto;
5
+ padding-top: var(--dx-g-spacing-sm);
5
6
  }
6
7
 
7
8
  dx-empty-state {
@@ -23,16 +23,14 @@
23
23
  </div>
24
24
 
25
25
  <template if:true={expanded}>
26
- <div class="padding-horizontal">
27
- <div class="header" if:false={mobile}>
26
+ <div class="sidebar-header" show-shadow={showBoxShadow}>
27
+ <div class="header padding-horizontal" if:false={mobile}>
28
28
  <h2 class="dx-text-display-6 header-title">{header}</h2>
29
- <slot name="header"></slot>
30
29
  </div>
31
- <div class="mobile-header" if:true={mobile}>
30
+ <div class="mobile-header padding-horizontal" if:true={mobile}>
32
31
  <h2 class="dx-text-display-6">{header}</h2>
33
- <slot name="header"></slot>
34
32
  </div>
35
- <div class="search">
33
+ <div class="search padding-horizontal">
36
34
  <dx-input
37
35
  class="search-box"
38
36
  type="search"
@@ -46,10 +44,12 @@
46
44
  shortcut-key="j"
47
45
  ></dx-input>
48
46
  </div>
47
+ <slot name="version-picker"></slot>
49
48
  </div>
50
49
  <div
51
- class="sidebar-content sidebar-content-tree"
50
+ class={sidebarContentClass}
52
51
  if:true={anyResultMatch}
52
+ onscroll={handleScroll}
53
53
  >
54
54
  <dx-tree
55
55
  for:each={filteredTrees}
@@ -70,6 +70,25 @@
70
70
  suggestions={emptyStateSuggestions}
71
71
  if:false={anyResultMatch}
72
72
  ></dx-empty-state>
73
+ <div if:true={hasMobileSidebarFooter} class="footer-nav">
74
+ <dx-sidebar-footer-nav
75
+ lang-value-path={langValuePath}
76
+ language={language}
77
+ languages={languages}
78
+ ></dx-sidebar-footer-nav>
79
+ </div>
80
+ </template>
81
+
82
+ <template if:false={mobile}>
83
+ <div if:true={hasSidebarFooter} class="footer-nav">
84
+ <dx-sidebar-footer-nav
85
+ lang-value-path={langValuePath}
86
+ language={language}
87
+ languages={languages}
88
+ bail-href={bailHref}
89
+ bail-label={bailLabel}
90
+ ></dx-sidebar-footer-nav>
91
+ </div>
73
92
  </template>
74
93
  </div>
75
94
  </template>
@@ -11,15 +11,6 @@ const MOBILE_SIZE_MATCH = "768px";
11
11
  export default class Sidebar extends SidebarBase {
12
12
  @api header: string = "";
13
13
 
14
- @api
15
- get value() {
16
- return this._value;
17
- }
18
-
19
- set value(value) {
20
- this._value = value;
21
- }
22
-
23
14
  @api
24
15
  get trees() {
25
16
  return this._trees;
@@ -37,13 +28,10 @@ export default class Sidebar extends SidebarBase {
37
28
  this.assignFilteredTrees();
38
29
  }
39
30
 
40
- private expanded: boolean = true;
41
31
  private _searchTimeout?: number;
42
- private _value?: string = undefined;
43
32
  private _trees!: Array<TreeNode>;
44
33
 
45
34
  private filteredTrees: Array<{ key: string; tree: TreeNode }> = [];
46
- private mobile: boolean = true;
47
35
  private searchText: string = "";
48
36
  private matchMedia!: MediaQueryList;
49
37
  private valueToLabel: { [key: string]: string } = {};
@@ -101,32 +89,6 @@ export default class Sidebar extends SidebarBase {
101
89
  this.matchMedia.removeEventListener("change", this.onMediaChange);
102
90
  }
103
91
 
104
- private onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {
105
- this.mobile = event.matches;
106
- this.expanded = !this.mobile;
107
- };
108
-
109
- private onSelect(event: CustomEvent) {
110
- this._value = event.detail.name;
111
-
112
- if (this.mobile) {
113
- this.onToggleClick();
114
- }
115
- }
116
-
117
- private onToggleClick() {
118
- this.expanded = !this.expanded;
119
- this.dispatchEvent(
120
- new CustomEvent("togglesidebar", {
121
- detail: {
122
- open: this.expanded,
123
- bubbles: true,
124
- composed: true
125
- }
126
- })
127
- );
128
- }
129
-
130
92
  /*
131
93
  * Debouncing this method: Do not apply searchText filter as long as this
132
94
  * function is being called to avoid running the recursivity logic very often.
@@ -8,29 +8,51 @@ a {
8
8
  }
9
9
 
10
10
  .sidebar-item {
11
- padding: var(--dx-g-spacing-smd) var(--dx-g-spacing-md);
11
+ padding: var(--dx-g-spacing-smd) var(--dx-g-spacing-lg)
12
+ var(--dx-g-spacing-smd) var(--dx-g-spacing-2xl);
13
+ }
14
+
15
+ .sidebar-item:focus-visible {
16
+ margin: 0 calc(var(--dx-g-spacing-2xs) + 1px);
17
+ outline: 2px solid var(--dx-g-blue-vibrant-40);
18
+ border-radius: 2px;
12
19
  }
13
20
 
14
21
  .search-text {
15
- font-size: var(--dx-g-text-xs);
22
+ font-size: var(--dx-g-text-sm);
16
23
  font-family: var(--dx-g-font-sans);
17
- line-height: 18px;
24
+ line-height: var(--dx-g-text-lg);
25
+ font-weight: var(--dx-g-font-bold);
18
26
  overflow-wrap: break-word;
19
27
  }
20
28
 
21
29
  .description {
22
30
  -webkit-line-clamp: 3;
23
31
  overflow-wrap: break-word;
32
+
33
+ --dx-g-text-body-color: var(--dx-g-blue-vibrant-20);
34
+
35
+ font-weight: var(--dx-g-font-normal);
24
36
  }
25
37
 
26
38
  .title {
27
39
  color: var(--dx-g-text-heading-color);
28
40
  }
29
41
 
42
+ .title:hover {
43
+ color: var(--dx-g-blue-vibrant-50);
44
+ }
45
+
30
46
  .bold {
31
47
  font-weight: 700;
32
48
  }
33
49
 
34
50
  a > *:not(:last-child) {
35
- margin-bottom: 2px;
51
+ margin-bottom: var(--dx-g-spacing-xs);
52
+ }
53
+
54
+ @media (max-width: 768px) {
55
+ .sidebar-item {
56
+ padding: var(--dx-g-spacing-smd) var(--dx-g-spacing-lg);
57
+ }
36
58
  }
@@ -11,22 +11,13 @@ a {
11
11
  );
12
12
 
13
13
  position: relative;
14
- display: flex;
15
- align-items: center;
16
- height: var(--dx-g-spacing-xl);
17
- font-family: var(--dx-g-font-display);
18
- white-space: nowrap;
19
- color: var(--dx-g-blue-vibrant-20);
20
- transition: var(--dx-g-transition-hue-1x);
21
- cursor: pointer;
22
- outline-offset: -1px;
14
+ height: calc(var(--dx-g-spacing-3xl) - 4px);
23
15
  }
24
16
 
25
17
  .nav-list-item_default {
26
- border: 0;
27
- border-radius: var(--dx-g-spacing-md);
28
- font-size: var(--dx-g-text-sm);
29
- padding: 0 var(--horizontal-spacing);
18
+ padding: calc(var(--dx-g-spacing-sm) + 2px) var(--dx-g-spacing-md);
19
+ justify-content: center;
20
+ display: flex;
30
21
  }
31
22
 
32
23
  .nav-list-item_small {
@@ -46,8 +37,6 @@ button.nav-list-item_small > dx-icon {
46
37
  margin-left: var(--dx-g-spacing-xs);
47
38
  }
48
39
 
49
- .nav-list-item_default:hover,
50
- .nav-list-item_default:active,
51
40
  :host([aria-expanded="true"]) button.nav-list-item_default {
52
41
  background: var(
53
42
  --dx-g-brand-current-button-color-background-inactive,
@@ -76,11 +65,10 @@ button.nav-list-item:active > dx-icon,
76
65
  }
77
66
 
78
67
  .nav-list-item_default.state-active {
79
- background: var(
80
- --dx-g-brand-current-button-color-background-active,
81
- var(--dx-g-brand-default-button-color-background-active)
82
- );
83
- color: var(--dx-g-brand-current-color, var(--dx-g-brand-default-color));
68
+ color: var(--dx-g-blue-vibrant-50);
69
+ font-family: var(--dx-g-font-sans);
70
+ font-size: var(--dx-g-text-base);
71
+ border-bottom: var(--dx-g-spacing-xs) solid var(--dx-g-blue-vibrant-50);
84
72
  }
85
73
 
86
74
  @media (max-width: 1160px) {
@@ -100,3 +88,10 @@ button.nav-list-item:active > dx-icon,
100
88
  );
101
89
  }
102
90
  }
91
+
92
+ @media (max-width: 768px) {
93
+ .nav-list-item {
94
+ height: var(--dx-g-spacing-3xl);
95
+ display: flex;
96
+ }
97
+ }
@@ -14,8 +14,8 @@ button:focus {
14
14
  }
15
15
 
16
16
  .tree-children-loading {
17
- margin: var(--dx-g-spacing-sm) var(--dx-g-spacing-md) var(--dx-g-spacing-md)
18
- var(--dx-g-spacing-md);
17
+ margin: var(--dx-g-spacing-sm) var(--dx-g-spacing-lg) var(--dx-g-spacing-md)
18
+ var(--dx-g-spacing-2xl);
19
19
  }
20
20
 
21
21
  @media (max-width: 768px) {
@@ -23,21 +23,23 @@
23
23
  --tile-height: 20px;
24
24
 
25
25
  font-family: var(--dx-g-font-sans);
26
- font-size: 13px;
26
+ font-size: 14px;
27
27
  line-height: var(--tile-height);
28
+ font-weight: var(--dx-g-font-normal);
28
29
  }
29
30
 
30
31
  .tile-root {
31
- font-family: var(--dx-g-font-display);
32
+ font-family: var(--dx-g-font-sans);
32
33
  font-size: var(--dx-g-text-sm);
33
- font-weight: var(--dx-g-font-demi);
34
- color: var(--dx-g-blue-vibrant-30);
34
+ font-weight: var(--dx-g-font-bold);
35
+ color: var(--dx-g-blue-vibrant-20);
35
36
  display: block;
36
37
  }
37
38
 
38
39
  .tile-icon {
39
40
  align-items: center;
40
41
  height: var(--tile-height);
42
+ padding-right: calc(var(--dx-g-spacing-xs) + 2px);
41
43
  }
42
44
 
43
45
  .tile-label {
@@ -54,95 +56,102 @@
54
56
 
55
57
  .tile-with-children .tile-expand-icon {
56
58
  order: 1;
57
- padding-right: var(--dx-g-spacing-xs);
58
59
  }
59
60
 
60
61
  .indentation {
61
- padding-left: var(--indentation);
62
+ padding-left: calc(var(--indentation) + var(--dx-g-spacing-2xs));
62
63
  }
63
64
 
64
65
  .tile-with-children .indentation {
65
66
  padding-left: calc(var(--indentation) - var(--base-indentation));
66
67
  }
67
68
 
69
+ .tile-root-with-child .indentation {
70
+ padding-left: 0;
71
+ }
72
+
73
+ [aria-level="2"] {
74
+ --indentation: var(--dx-g-spacing-md);
75
+ }
76
+
68
77
  [aria-level="3"] {
69
- --indentation: var(--base-indentation);
78
+ --indentation: calc(2 * var(--base-indentation));
70
79
  }
71
80
 
72
81
  [aria-level="4"] {
73
- --indentation: calc(2 * var(--base-indentation));
82
+ --indentation: calc(3 * var(--base-indentation));
74
83
  }
75
84
 
76
85
  [aria-level="5"] {
77
- --indentation: calc(3 * var(--base-indentation));
86
+ --indentation: calc(4 * var(--base-indentation));
78
87
  }
79
88
 
80
89
  [aria-level="6"] {
81
- --indentation: calc(4 * var(--base-indentation));
90
+ --indentation: calc(5 * var(--base-indentation));
82
91
  }
83
92
 
84
93
  [aria-level="7"] {
85
- --indentation: calc(5 * var(--base-indentation));
94
+ --indentation: calc(6 * var(--base-indentation));
86
95
  }
87
96
 
88
97
  [aria-level="8"] {
89
- --indentation: calc(6 * var(--base-indentation));
98
+ --indentation: calc(7 * var(--base-indentation));
90
99
  }
91
100
 
92
101
  [aria-level="9"] {
93
- --indentation: calc(7 * var(--base-indentation));
102
+ --indentation: calc(8 * var(--base-indentation));
94
103
  }
95
104
 
96
105
  [aria-level="10"] {
97
- --indentation: calc(8 * var(--base-indentation));
106
+ --indentation: calc(9 * var(--base-indentation));
98
107
  }
99
108
 
100
109
  [aria-level="11"] {
101
- --indentation: calc(9 * var(--base-indentation));
110
+ --indentation: calc(10 * var(--base-indentation));
102
111
  }
103
112
 
104
113
  [aria-level="12"] {
105
- --indentation: calc(10 * var(--base-indentation));
114
+ --indentation: calc(11 * var(--base-indentation));
106
115
  }
107
116
 
108
117
  [aria-level="13"] {
109
- --indentation: calc(11 * var(--base-indentation));
118
+ --indentation: calc(12 * var(--base-indentation));
110
119
  }
111
120
 
112
121
  [aria-level="14"] {
113
- --indentation: calc(12 * var(--base-indentation));
122
+ --indentation: calc(13 * var(--base-indentation));
114
123
  }
115
124
 
116
125
  [aria-level="15"] {
117
- --indentation: calc(13 * var(--base-indentation));
126
+ --indentation: calc(14 * var(--base-indentation));
118
127
  }
119
128
 
120
129
  [aria-level="16"] {
121
- --indentation: calc(14 * var(--base-indentation));
130
+ --indentation: calc(15 * var(--base-indentation));
122
131
  }
123
132
 
124
133
  [aria-level="17"] {
125
- --indentation: calc(15 * var(--base-indentation));
134
+ --indentation: calc(16 * var(--base-indentation));
126
135
  }
127
136
 
128
137
  [aria-level="18"] {
129
- --indentation: calc(16 * var(--base-indentation));
138
+ --indentation: calc(17 * var(--base-indentation));
130
139
  }
131
140
 
132
141
  [aria-level="19"] {
133
- --indentation: calc(17 * var(--base-indentation));
142
+ --indentation: calc(18 * var(--base-indentation));
134
143
  }
135
144
 
136
145
  [aria-level="20"] {
137
- --indentation: calc(18 * var(--base-indentation));
146
+ --indentation: calc(19 * var(--base-indentation));
138
147
  }
139
148
 
140
149
  [aria-level="21"] {
141
- --indentation: calc(19 * var(--base-indentation));
150
+ --indentation: calc(20 * var(--base-indentation));
142
151
  }
143
152
 
144
153
  [aria-level="22"] {
145
- --indentation: calc(20 * var(--base-indentation));
154
+ --indentation: calc(21 * var(--base-indentation));
146
155
  }
147
156
 
148
157
  dx-metadata-badge {
@@ -181,10 +190,10 @@ a {
181
190
 
182
191
  a:link,
183
192
  a:visited {
184
- color: var(--dx-g-gray-10);
193
+ color: var(--dx-g-blue-vibrant-20);
185
194
  }
186
195
 
187
196
  a:visited.tile-root,
188
197
  a:link.tile-root {
189
- color: var(--dx-g-blue-vibrant-30);
198
+ color: var(--dx-g-blue-vibrant-20);
190
199
  }
@@ -1,12 +1,6 @@
1
1
  <template>
2
2
  <a href={href} class={tileClass} target={target}>
3
3
  <div class="flex indentation" role="heading" aria-level={tileAriaLevel}>
4
- <span
5
- class="tile-label sidebar-item-truncate-text"
6
- title={treeNode.label}
7
- >
8
- {treeNode.label}
9
- </span>
10
4
  <div class="flex tile-expand-icon tile-icon" if:true={showArrow}>
11
5
  <dx-icon
12
6
  aria-expanded={isExpanded}
@@ -16,6 +10,12 @@
16
10
  onclick={onClickIcon}
17
11
  ></dx-icon>
18
12
  </div>
13
+ <span
14
+ class="tile-label sidebar-item-truncate-text"
15
+ title={treeNode.label}
16
+ >
17
+ {treeNode.label}
18
+ </span>
19
19
  <dx-metadata-badge
20
20
  if:true={showMethod}
21
21
  class="flex tile-icon"
@@ -37,7 +37,7 @@ export default class TreeTile extends LightningElement {
37
37
  }
38
38
 
39
39
  private get iconSize() {
40
- return this.isRoot ? "small" : "xsmall";
40
+ return "xsmall";
41
41
  }
42
42
 
43
43
  private get metadataBadgeColor(): string | undefined {
@@ -62,6 +62,7 @@ export default class TreeTile extends LightningElement {
62
62
  return cx("tile", "sidebar-item", {
63
63
  "tile-root": this.isRoot,
64
64
  "tile-with-children": !this.isRoot && this.hasChildren,
65
+ "tile-root-with-child": this.isRoot && this.showArrow,
65
66
  "sidebar-item-selected": this.isSelected
66
67
  });
67
68
  }
@@ -1,4 +1,6 @@
1
- import { LightningElement } from "lwc";
1
+ import { LightningElement, api } from "lwc";
2
+ import type { OptionWithLink } from "typings/custom";
3
+ import { toJson } from "dxUtils/normalizers";
2
4
 
3
5
  export const HEIGHT_OF_SIDEBAR_ITEM = 32;
4
6
  export const WAIT_TIME_BEFORE_SCROLL_IN_MS = 500;
@@ -8,6 +10,35 @@ export class SidebarBase extends LightningElement {
8
10
 
9
11
  selectedElement: HTMLElement | null = null;
10
12
  timerId: ReturnType<typeof setTimeout> | null = null;
13
+ _languages!: OptionWithLink[];
14
+ mobile: boolean = true;
15
+ expanded: boolean = true;
16
+ _value?: string = undefined;
17
+ showBoxShadow: boolean = false;
18
+ private scrolling: boolean = false;
19
+
20
+ @api langValuePath: string = "id";
21
+ @api language!: string;
22
+ @api bailHref!: string;
23
+ @api bailLabel!: string;
24
+
25
+ @api
26
+ get languages() {
27
+ return this._languages;
28
+ }
29
+
30
+ set languages(value) {
31
+ this._languages = toJson(value);
32
+ }
33
+
34
+ @api
35
+ get value() {
36
+ return this._value;
37
+ }
38
+
39
+ set value(value) {
40
+ this._value = value;
41
+ }
11
42
 
12
43
  get sidebarContent() {
13
44
  if (!this._sidebarContent) {
@@ -18,6 +49,29 @@ export class SidebarBase extends LightningElement {
18
49
  return this._sidebarContent;
19
50
  }
20
51
 
52
+ /**
53
+ * This method is to handle the scroll event for LNB and show box shadow
54
+ * @param scrollEvent
55
+ */
56
+ handleScroll(scrollEvent: any) {
57
+ const lnb = scrollEvent.target;
58
+
59
+ if (!this.scrolling) {
60
+ this.scrolling = true;
61
+ // Set a timeout to handle scroll event after a delay
62
+ setTimeout(() => {
63
+ // Check if lnb is scrolled
64
+ if (lnb.scrollTop > 0 && lnb.scrollHeight > lnb.clientHeight) {
65
+ this.showBoxShadow = true;
66
+ } else {
67
+ this.showBoxShadow = false;
68
+ }
69
+ // Reset scrolling back to false after handling the scroll
70
+ this.scrolling = false;
71
+ }, 200);
72
+ }
73
+ }
74
+
21
75
  renderedCallback(): void {
22
76
  /**
23
77
  * Implementing debouncing kind of logic here to scroll to selected element once tree rendering is done
@@ -62,4 +116,45 @@ export class SidebarBase extends LightningElement {
62
116
  this.selectedElement = null;
63
117
  }
64
118
  }
119
+
120
+ onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {
121
+ this.mobile = event.matches;
122
+ this.expanded = !this.mobile;
123
+ };
124
+
125
+ onSelect(event: CustomEvent) {
126
+ this._value = event.detail.name;
127
+
128
+ if (this.mobile) {
129
+ this.onToggleClick();
130
+ }
131
+ }
132
+
133
+ onToggleClick() {
134
+ this.expanded = !this.expanded;
135
+ this.dispatchEvent(
136
+ new CustomEvent("togglesidebar", {
137
+ detail: {
138
+ open: this.expanded,
139
+ bubbles: true,
140
+ composed: true
141
+ }
142
+ })
143
+ );
144
+ }
145
+
146
+ private get hasMobileSidebarFooter(): boolean {
147
+ return this.mobile && this.languages?.length > 1 && this.expanded;
148
+ }
149
+
150
+ private get hasSidebarFooter(): boolean {
151
+ return this.languages?.length > 1 || Boolean(this.bailHref);
152
+ }
153
+
154
+ private get sidebarContentClass(): string {
155
+ const sidebarConterCss = "sidebar-content sidebar-content-tree";
156
+ return this.hasSidebarFooter || this.hasMobileSidebarFooter
157
+ ? sidebarConterCss + " sidebar-content-hasfooter"
158
+ : sidebarConterCss;
159
+ }
65
160
  }
@@ -58,7 +58,7 @@ header.state-show-mobile-nav .header_l2_group-nav_overflow {
58
58
  /* Second row */
59
59
 
60
60
  .header_l2 {
61
- background: var(--dx-g-brand-current-color-background);
61
+ background: white;
62
62
  padding: var(--dx-g-spacing-lg) var(--dx-g-global-header-padding-horizontal);
63
63
  }
64
64
 
@@ -70,6 +70,7 @@ header.state-show-mobile-nav .header_l2_group-nav_overflow {
70
70
 
71
71
  .header_l2_group-title {
72
72
  flex-shrink: 0;
73
+ padding-right: var(--dx-g-spacing-xl);
73
74
  }
74
75
 
75
76
  .header_l2_group-title
@@ -2,7 +2,7 @@
2
2
  @import "dxHelpers/text";
3
3
 
4
4
  :host {
5
- --dx-c-sidebar-width: 275px;
5
+ --dx-c-sidebar-width: 337px;
6
6
  --dx-c-sidebar-button-color: var(--dx-g-blue-vibrant-50);
7
7
  --dx-c-sidebar-button-background: white;
8
8
  --dx-c-sidebar-button-border: white;
@@ -11,10 +11,7 @@
11
11
  --dx-c-sidebar-button-border-hover: var(--dx-g-blue-vibrant-50);
12
12
  --dx-c-sidebar-left-padding: var(--dx-g-global-header-padding-horizontal);
13
13
  --dx-c-sidebar-vertical-padding: var(--dx-g-spacing-md);
14
- }
15
-
16
- dx-tree:not(:last-child) {
17
- margin-bottom: var(--dx-g-spacing-sm);
14
+ --doc-version-picker-width: 296px;
18
15
  }
19
16
 
20
17
  .header {
@@ -31,8 +28,11 @@ dx-tree:not(:last-child) {
31
28
  }
32
29
 
33
30
  .padding-horizontal {
34
- padding-left: var(--dx-g-spacing-md);
35
- padding-right: var(--dx-g-spacing-md);
31
+ padding: 0 var(--dx-g-spacing-lg) 0 var(--dx-c-sidebar-left-padding);
32
+ }
33
+
34
+ .sidebar-header[show-shadow="true"] {
35
+ box-shadow: 0 4px 4px -2px var(--dx-g-gray-90);
36
36
  }
37
37
 
38
38
  .header-title {
@@ -53,7 +53,7 @@ dx-tree:not(:last-child) {
53
53
  }
54
54
 
55
55
  .container {
56
- background-color: var(--dx-g-gray-95);
56
+ background-color: white;
57
57
  display: flex;
58
58
  flex-direction: column;
59
59
  height: var(--dx-c-sidebar-height);
@@ -66,10 +66,10 @@ dx-tree:not(:last-child) {
66
66
  var(--dx-c-sidebar-left-padding) - var(--dx-g-spacing-md)
67
67
  );
68
68
 
69
+ border-right: 1px solid var(--dx-g-gray-90);
69
70
  box-shadow: 2px 0 0 0 var(--border-color);
70
71
  min-height: var(--dx-c-sidebar-min-height);
71
- padding: var(--dx-c-sidebar-vertical-padding) 0
72
- var(--dx-c-sidebar-vertical-padding) var(--left-spacing);
72
+ padding: var(--dx-c-sidebar-vertical-padding) 0 var(--dx-g-spacing-2xs) 0;
73
73
  position: relative;
74
74
  }
75
75
 
@@ -127,9 +127,29 @@ dx-tree:not(:last-child) {
127
127
  white-space: nowrap;
128
128
  }
129
129
 
130
- @media screen and (max-width: 768px) {
131
- .padding-horizontal {
132
- padding-left: var(--dx-g-spacing-lg);
133
- padding-right: var(--dx-g-spacing-md);
130
+ .footer-nav {
131
+ display: flex;
132
+ padding: var(--dx-g-spacing-xs) var(--dx-g-spacing-sm)
133
+ var(--dx-g-spacing-xs) var(--dx-g-spacing-xl);
134
+ position: fixed;
135
+ bottom: 0;
136
+ left: 0;
137
+ width: inherit;
138
+ background: white;
139
+ border-top: 1px solid var(--dx-g-gray-90);
140
+ border-right: 1px solid var(--dx-g-gray-90);
141
+ height: var(--dx-g-spacing-2xl);
142
+ align-items: center;
143
+ }
144
+
145
+ .sidebar-content-hasfooter {
146
+ margin-bottom: var(--dx-g-spacing-2xl);
147
+ }
148
+
149
+ @media screen and (max-width: 767px) {
150
+ :host {
151
+ --doc-version-picker-width: calc(
152
+ 100vw - var(--dx-c-sidebar-left-padding) - var(--dx-g-spacing-lg)
153
+ );
134
154
  }
135
155
  }
@@ -8,14 +8,33 @@
8
8
 
9
9
  .sidebar-item-selected {
10
10
  background: var(--dx-g-cloud-blue-vibrant-95);
11
- box-shadow: inset var(--dx-g-spacing-xs) 0 0 0 var(--dx-g-blue-vibrant-60);
11
+ box-shadow: inset var(--dx-g-spacing-xs) 0 0 0 var(--dx-g-blue-vibrant-40);
12
12
  border-radius: 0;
13
+ color: var(--dx-g-blue-vibrant-40) !important;
13
14
  }
14
15
 
15
16
  .sidebar-item {
16
- padding: 6px var(--dx-g-spacing-md);
17
+ padding: 6px var(--dx-g-spacing-lg) 6px var(--dx-g-spacing-2xl);
18
+ }
19
+
20
+ .sidebar-item:focus-visible {
21
+ margin: 0 calc(var(--dx-g-spacing-2xs) + 1px);
22
+ outline: 2px solid var(--dx-g-blue-vibrant-40);
23
+ border-radius: 2px;
17
24
  }
18
25
 
19
26
  .sidebar-item:not(.sidebar-item-selected):hover {
20
- background-color: var(--dx-g-gray-90);
27
+ color: var(--dx-g-blue-vibrant-50);
28
+ }
29
+
30
+ @media (max-width: 1279px) {
31
+ .sidebar-item {
32
+ padding: 6px var(--dx-g-spacing-lg) 6px var(--dx-g-spacing-xl);
33
+ }
34
+ }
35
+
36
+ @media (max-width: 767px) {
37
+ .sidebar-item {
38
+ padding: 6px var(--dx-g-spacing-lg) 6px var(--dx-g-spacing-lg);
39
+ }
21
40
  }
package/LICENSE DELETED
@@ -1,12 +0,0 @@
1
- Copyright (c) 2020, Salesforce.com, Inc.
2
- All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
-
6
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
-
8
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
-
10
- * Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
-
12
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.