@salesforcedevs/docs-components 1.3.209-lang4-alpha → 1.3.209-tag1-alpha

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
@@ -18,7 +18,6 @@
18
18
  "doc/overview",
19
19
  "doc/phase",
20
20
  "doc/xmlContent",
21
- "doc/sidebarFooterNav",
22
21
  "docUtils/utils"
23
22
  ]
24
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/docs-components",
3
- "version": "1.3.209-lang4-alpha",
3
+ "version": "1.3.209-tag1-alpha",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -16,8 +16,6 @@
16
16
  toc-title={tocTitle}
17
17
  toc-options={tocOptions}
18
18
  enable-slot-change="true"
19
- languages={languages}
20
- language={language}
21
19
  >
22
20
  <doc-phase
23
21
  slot="doc-phase"
@@ -4,7 +4,6 @@ import { sentenceCase } from "sentence-case";
4
4
  import qs from "query-string";
5
5
  import { AmfModelParser } from "doc/amfModelParser";
6
6
  import { normalizeBoolean } from "dxUtils/normalizers";
7
- import type { OptionWithLink } from "typings/custom";
8
7
  import type {
9
8
  AmfConfig,
10
9
  AmfMetadataTopic,
@@ -49,8 +48,6 @@ export default class AmfReference extends LightningElement {
49
48
  @api useOldSidebar: boolean = false;
50
49
  @api tocTitle?: string;
51
50
  @api tocOptions?: string;
52
- @api languages!: OptionWithLink[];
53
- @api language!: string;
54
51
  @track navigation = [] as NavigationItem[];
55
52
  @track versions: Array<ReferenceVersion> = [];
56
53
  @track showVersionBanner = false;
@@ -1346,19 +1343,15 @@ export default class AmfReference extends LightningElement {
1346
1343
  * New Title: E1 | Ref Spec2 | Project Name | Salesforce Developer
1347
1344
  *
1348
1345
  */
1349
- if (titleTag) {
1350
- let titleTagValue = titleTag.textContent;
1351
- const titleTagSectionValues: string[] =
1352
- titleTagValue?.split(TITLE_SEPARATOR);
1353
- if (titleTagSectionValues) {
1354
- if (titleTagSectionValues.length <= 3) {
1355
- titleTagValue = navTitle + TITLE_SEPARATOR + titleTagValue;
1356
- } else {
1357
- titleTagSectionValues[0] = navTitle;
1358
- titleTagValue = titleTagSectionValues.join(TITLE_SEPARATOR);
1359
- }
1360
- }
1361
- titleTag.textContent = titleTagValue;
1346
+ // eslint-disable-next-line @lwc/lwc/no-document-query
1347
+ const coveoTitleMetaTag = document.querySelector(
1348
+ 'meta[name="coveo-search-title"]'
1349
+ );
1350
+ if (coveoTitleMetaTag && titleTag && navTitle) {
1351
+ const titleTagValue = titleTag.textContent;
1352
+ const coveoSerachTitle = navTitle + TITLE_SEPARATOR + titleTagValue;
1353
+ coveoTitleMetaTag.setAttribute("content", coveoSerachTitle);
1354
+ titleTag.textContent = coveoSerachTitle;
1362
1355
  }
1363
1356
  }
1364
1357
 
@@ -61,16 +61,12 @@ dx-toc {
61
61
  flex-direction: row;
62
62
  justify-content: center;
63
63
  max-width: var(--dx-g-doc-content-max-width);
64
-
65
- /* Derived this manually by substracting (topHeader, doc header, banner and the content). */
66
- min-height: 62vh;
67
64
  margin: auto;
68
65
  padding: 0 var(--dx-g-global-header-padding-horizontal);
69
- margin-bottom: calc(2 * (var(--dx-g-spacing-5xl) + 4px));
70
66
  }
71
67
 
72
68
  .content-body {
73
- margin: var(--dx-g-spacing-sm) 0 0;
69
+ margin: var(--dx-g-spacing-sm) 0 var(--dx-g-spacing-xl);
74
70
  max-width: 900px;
75
71
  flex: 1;
76
72
  width: 0;
@@ -110,7 +106,6 @@ dx-toc {
110
106
  .content-body-container {
111
107
  padding-right: 0;
112
108
  overflow-x: auto;
113
- margin-bottom: calc(var(--dx-g-spacing-5xl) + 4px);
114
109
  }
115
110
 
116
111
  .left-nav-bar {
@@ -7,10 +7,6 @@
7
7
  value={sidebarValue}
8
8
  header={sidebarHeader}
9
9
  ontogglesidebar={onToggleSidebar}
10
- languages={languages}
11
- language={language}
12
- bail-href={bailHref}
13
- bail-label={bailLabel}
14
10
  >
15
11
  <slot name="sidebar-header" slot="header"></slot>
16
12
  </dx-sidebar-old>
@@ -26,10 +22,6 @@
26
22
  coveo-search-hub={coveoSearchHub}
27
23
  coveo-advanced-query-config={coveoAdvancedQueryConfig}
28
24
  ontogglesidebar={onToggleSidebar}
29
- languages={languages}
30
- language={language}
31
- bail-href={bailHref}
32
- bail-label={bailLabel}
33
25
  >
34
26
  <slot name="sidebar-header" slot="header"></slot>
35
27
  </dx-sidebar>
@@ -56,9 +48,6 @@
56
48
  ></dx-toc>
57
49
  </div>
58
50
  </div>
59
- <div class="footer-container">
60
- <dx-footer variant="no-signup"></dx-footer>
61
- </div>
62
51
  </div>
63
52
  </div>
64
53
  </template>
@@ -4,7 +4,6 @@ import { closest } from "kagekiri";
4
4
  import { toJson } from "dxUtils/normalizers";
5
5
  import { highlightTerms } from "dxUtils/highlight";
6
6
  import { SearchSyncer } from "docUtils/searchSyncer";
7
- import type { OptionWithLink } from "typings/custom";
8
7
 
9
8
  type AnchorMap = { [key: string]: { intersect: boolean; id: string } };
10
9
 
@@ -37,10 +36,6 @@ export default class ContentLayout extends LightningElement {
37
36
  @api coveoSearchHub!: string;
38
37
  @api coveoAdvancedQueryConfig!: string;
39
38
  @api useOldSidebar?: boolean = false;
40
- @api languages!: OptionWithLink[];
41
- @api language!: string;
42
- @api bailHref!: string;
43
- @api bailLabel!: string;
44
39
 
45
40
  @api
46
41
  get breadcrumbs() {
@@ -7,8 +7,6 @@ dx-logo {
7
7
  .header_l2 {
8
8
  justify-content: space-between;
9
9
  height: var(--dx-g-doc-header-main-nav-height);
10
- padding-bottom: var(--dx-g-spacing-xs);
11
- background: white;
12
10
  }
13
11
 
14
12
  .nav_menu-button {
@@ -18,32 +16,44 @@ dx-logo {
18
16
  );
19
17
  }
20
18
 
21
- .has-brand.has-scoped-nav-items {
22
- border-bottom: 1px solid var(--dx-g-gray-90);
23
- border-top: 1px solid var(--dx-g-gray-90);
24
- }
25
-
26
19
  .nav_menu-ctas {
27
20
  margin-right: var(--dx-g-spacing-sm);
28
21
  }
29
22
 
30
23
  header:not(.has-brand) > .header_l1 {
31
- background: white;
32
- border-bottom: 1px solid var(--dx-g-gray-90);
24
+ background: var(--dx-g-brand-current-color-background);
33
25
  }
34
26
 
35
27
  header:not(.has-brand) > .header_l2 {
36
- border-bottom: 1px solid var(--dx-g-gray-90);
37
- border-top: 1px solid var(--dx-g-gray-90);
38
- padding-bottom: var(--dx-g-spacing-lg);
28
+ background: var(--dx-g-brand-current-color-background-2);
39
29
  }
40
30
 
41
31
  .header_l2_group.header_l2_group-right-ctas {
42
32
  align-items: baseline;
43
33
  }
44
34
 
45
- .has-brand .header_l2_group-title {
46
- padding-bottom: calc(var(--dx-g-spacing-md) + 2px);
35
+ .header_bail-link {
36
+ --dx-c-button-horizontal-spacing: var(--dx-g-spacing-sm);
37
+
38
+ margin-left: var(--dx-g-spacing-sm);
39
+ }
40
+
41
+ .header_lang-dropdown {
42
+ --button-primary-color: var(--dx-g-blue-vibrant-40);
43
+ --button-primary-color-hover: var(--dx-g-blue-vibrant-30);
44
+ }
45
+
46
+ .header_lang-dropdown > dx-button {
47
+ --dx-c-button-primary-color: var(--button-primary-color);
48
+ --dx-c-button-primary-color-hover: var(--button-primary-color-hover);
49
+ --dx-c-slot-empty-width: min-content;
50
+ --border-color: var(--button-primary-color);
51
+
52
+ border-bottom: 1px dashed var(--border-color);
53
+ }
54
+
55
+ .header_lang-dropdown > dx-button:hover {
56
+ --border-color: var(--button-primary-color-hover);
47
57
  }
48
58
 
49
59
  @media (max-width: 768px) {
@@ -72,10 +82,6 @@ header:not(.has-brand) > .header_l2 {
72
82
  margin-right: var(--dx-g-spacing-sm);
73
83
  }
74
84
 
75
- .has-brand .header_l2_group-title {
76
- padding-bottom: var(--dx-g-spacing-smd);
77
- }
78
-
79
85
  .header_l2_group-title {
80
86
  margin-right: 0;
81
87
  padding: var(--dx-g-spacing-smd)
@@ -83,15 +89,19 @@ header:not(.has-brand) > .header_l2 {
83
89
  min-height: var(--dx-g-doc-header-main-nav-height);
84
90
  }
85
91
 
92
+ .header_l2_group-title .header_lang-dropdown {
93
+ margin-left: auto;
94
+ }
95
+
96
+ .header_lang-dropdown > dx-button {
97
+ padding: var(--dx-g-spacing-2xs) 0;
98
+ }
99
+
86
100
  .has-scoped-nav-items > .header_l2 {
87
101
  height: unset;
88
102
  }
89
103
 
90
104
  .has-scoped-nav-items .header_l2_group-title {
91
- border-bottom: 1px solid var(--dx-g-gray-90);
92
- }
93
-
94
- header:not(.has-brand) > .header_l2 {
95
- padding-bottom: 0;
105
+ border-bottom: 1px solid var(--dx-g-brand-current-color-border-2);
96
106
  }
97
107
  }
@@ -14,12 +14,28 @@
14
14
  if:true={isValidBrand}
15
15
  sprite="salesforcebrand"
16
16
  symbol={brand}
17
- size="large"
17
+ size="xlarge"
18
18
  ></dx-icon>
19
- <span class="subtitle dx-text-display-7">
19
+ <span class="subtitle dx-text-display-6">
20
20
  {subtitle}
21
21
  </span>
22
22
  </a>
23
+ <dx-dropdown
24
+ if:true={showMobileLanguages}
25
+ class="header_lang-dropdown"
26
+ options={languages}
27
+ small
28
+ value={language}
29
+ value-path={langValuePath}
30
+ onchange={onLangChange}
31
+ >
32
+ <dx-button
33
+ aria-label="Select Language"
34
+ variant="inline"
35
+ icon-size="large"
36
+ icon-symbol="world"
37
+ ></dx-button>
38
+ </dx-dropdown>
23
39
  </div>
24
40
  <div
25
41
  if:true={hasScopedNavItems}
@@ -36,6 +52,41 @@
36
52
  ></dx-header-nav>
37
53
  </div>
38
54
  </div>
55
+ <div
56
+ if:false={smallMobile}
57
+ class="header_l2_group header_l2_group-right-ctas"
58
+ >
59
+ <dx-dropdown
60
+ if:true={hasLanguages}
61
+ class="header_lang-dropdown"
62
+ options={languages}
63
+ small
64
+ value-path={langValuePath}
65
+ value={language}
66
+ onchange={onLangChange}
67
+ >
68
+ <dx-button
69
+ aria-label="Select Language"
70
+ variant="inline"
71
+ icon-size="small"
72
+ icon-symbol="world"
73
+ >
74
+ {languageLabel}
75
+ </dx-button>
76
+ </dx-dropdown>
77
+ <dx-button
78
+ if:true={hasBailLink}
79
+ aria-label={bailLabel}
80
+ class="header_bail-link"
81
+ href={bailHref}
82
+ onclick={handleBailClick}
83
+ variant="tertiary"
84
+ icon-symbol="new_window"
85
+ target="_blank"
86
+ >
87
+ {bailLabel}
88
+ </dx-button>
89
+ </div>
39
90
  </div>
40
91
  </header>
41
92
  </dx-brand-theme-provider>
@@ -1,11 +1,14 @@
1
1
  import { api } from "lwc";
2
2
  import cx from "classnames";
3
- import type { OptionWithNested } from "typings/custom";
3
+ import type { OptionWithNested, OptionWithLink } from "typings/custom";
4
4
  import { HeaderBase } from "dxBaseElements/headerBase";
5
5
  import { toJson } from "dxUtils/normalizers";
6
+ import get from "lodash.get";
7
+ import { track } from "dxUtils/analytics";
6
8
 
7
9
  const TABLET_MATCH = "980px";
8
10
  const MOBILE_MATCH = "880px";
11
+ const SMALL_MOBILE_MATCH = "768px";
9
12
 
10
13
  export default class Header extends HeaderBase {
11
14
  @api langValuePath: string = "id"; // allows to override how language property is interpreted, follows valuePath dropdown api.
@@ -20,7 +23,31 @@ export default class Header extends HeaderBase {
20
23
  this._scopedNavItems = toJson(value);
21
24
  }
22
25
 
26
+ @api
27
+ get languages() {
28
+ return this._languages;
29
+ }
30
+
31
+ set languages(value) {
32
+ this._languages = toJson(value);
33
+ }
34
+
35
+ @api
36
+ get language() {
37
+ return this._language;
38
+ }
39
+
40
+ set language(value) {
41
+ if (this._language !== value) {
42
+ this._language = value;
43
+ }
44
+ }
45
+
46
+ private _language: string | null = null;
47
+ private _languages!: OptionWithLink[];
23
48
  private _scopedNavItems!: OptionWithNested[];
49
+ private smallMobile = false;
50
+ private smallMobileMatchMedia!: MediaQueryList;
24
51
  private tablet = false;
25
52
  private tabletMatchMedia!: MediaQueryList;
26
53
  private shouldRender = false;
@@ -33,6 +60,24 @@ export default class Header extends HeaderBase {
33
60
  return this.scopedNavItems && this.scopedNavItems.length > 0;
34
61
  }
35
62
 
63
+ private get hasLanguages(): boolean {
64
+ return !!(this.languages && this.languages.length);
65
+ }
66
+
67
+ private get showMobileLanguages(): boolean {
68
+ return this.smallMobile && this.hasLanguages;
69
+ }
70
+
71
+ private get languageLabel(): string {
72
+ return (
73
+ (this.language &&
74
+ this.languages.find(
75
+ (lang) => get(lang, this.langValuePath) === this.language
76
+ )?.label) ||
77
+ this.languages[0].label
78
+ );
79
+ }
80
+
36
81
  connectedCallback(): void {
37
82
  super.connectedCallback();
38
83
  this.tabletMatchMedia = window.matchMedia(
@@ -41,6 +86,14 @@ export default class Header extends HeaderBase {
41
86
  this.onTabletChange(this.tabletMatchMedia);
42
87
  this.tabletMatchMedia.addEventListener("change", this.onTabletChange);
43
88
 
89
+ this.smallMobileMatchMedia = window.matchMedia(
90
+ `(max-width: ${SMALL_MOBILE_MATCH})`
91
+ );
92
+ this.onSmallMobileChange(this.smallMobileMatchMedia);
93
+ this.smallMobileMatchMedia.addEventListener(
94
+ "change",
95
+ this.onSmallMobileChange
96
+ );
44
97
  if (
45
98
  (window.location.pathname.includes("/docs/") &&
46
99
  window.location.pathname !== "/docs/apis") ||
@@ -57,15 +110,53 @@ export default class Header extends HeaderBase {
57
110
  "change",
58
111
  this.onTabletChange
59
112
  );
113
+
114
+ this.smallMobileMatchMedia.removeEventListener(
115
+ "change",
116
+ this.onSmallMobileChange
117
+ );
60
118
  }
61
119
 
62
120
  private onTabletChange = (e: MediaQueryListEvent | MediaQueryList) =>
63
121
  (this.tablet = e.matches);
64
122
 
123
+ private onSmallMobileChange = (e: MediaQueryListEvent | MediaQueryList) =>
124
+ (this.smallMobile = e.matches);
125
+
65
126
  protected additionalClasses(): string {
66
127
  return cx(
67
128
  this.brand && "has-brand",
68
129
  this.hasScopedNavItems && "has-scoped-nav-items"
69
130
  );
70
131
  }
132
+
133
+ private onLangChange(event: CustomEvent<string>): void {
134
+ const { detail } = event;
135
+ this._language = detail;
136
+
137
+ this.dispatchEvent(new CustomEvent("langchange", { detail }));
138
+ }
139
+
140
+ private handleBailClick(event: Event) {
141
+ const payload = {
142
+ click_text: "pdf",
143
+ click_url: this.bailHref,
144
+ element_title: "pdf",
145
+ element_type: "link",
146
+ content_category: "download"
147
+ };
148
+ track(event.target!, "custEv_pdfDownload", {
149
+ ...payload,
150
+ file_name: this.getFilename(this.bailHref!),
151
+ file_extension: "pdf"
152
+ });
153
+
154
+ track(event.target!, "custEv_linkClick", {
155
+ ...payload
156
+ });
157
+ }
158
+
159
+ private getFilename = function (path: string) {
160
+ return path.substring(path.lastIndexOf("/") + 1);
161
+ };
71
162
  }
@@ -61,15 +61,12 @@ export type ApiDocLanguage = {
61
61
 
62
62
  export interface Header extends Element {
63
63
  subtitle: string;
64
- headerHref: string;
65
- }
66
-
67
- export type SiderbarFooter = {
68
64
  bailHref: string;
69
65
  bailLabel: string;
70
66
  languages: Array<DocLanguage>;
71
67
  language?: string;
72
- };
68
+ headerHref: string;
69
+ }
73
70
 
74
71
  export type ApiNavItem = {
75
72
  children: Array<ApiNavItem>;
@@ -11,11 +11,6 @@
11
11
  sidebar-value={sidebarValue}
12
12
  onselect={handleSelect}
13
13
  use-old-sidebar={useOldSidebar}
14
- onlangchange={handleLanguageChange}
15
- languages={sidebarFooterContent.languages}
16
- language={sidebarFooterContent.language}
17
- bail-href={sidebarFooterContent.bailHref}
18
- bail-label={sidebarFooterContent.bailLabel}
19
14
  >
20
15
  <doc-phase
21
16
  slot="version-banner"
@@ -8,7 +8,6 @@ import {
8
8
  DocVersion,
9
9
  TreeNode,
10
10
  Header,
11
- SiderbarFooter,
12
11
  HistoryState,
13
12
  PageReference,
14
13
  TocMap
@@ -27,12 +26,6 @@ const PIXEL_PER_CHARACTER_MAP: { [key: string]: number } = {
27
26
  "ja-jp": 12.5
28
27
  };
29
28
 
30
- const defaultSidebarFooter: SiderbarFooter = {
31
- bailHref: "",
32
- bailLabel: "",
33
- languages: [],
34
- language: ""
35
- };
36
29
  export default class DocXmlContent extends LightningElementWithState<{
37
30
  isFetchingDocument: boolean;
38
31
  isFetchingContent: boolean;
@@ -71,16 +64,15 @@ export default class DocXmlContent extends LightningElementWithState<{
71
64
  private docContent = "";
72
65
  private language?: DocLanguage | null = null;
73
66
  private loaded = false;
74
- private _pageHeader?: Header;
75
67
  private pdfUrl = "";
76
68
  private tocMap: TocMap = {};
77
69
  private sidebarContent: Array<TreeNode> | null = null;
78
70
  private version: DocVersion | null = null;
79
71
  private docTitle = "";
80
72
  private _pathName = "";
73
+ private _pageHeader?: Header;
81
74
  private listenerAttached = false;
82
75
  private _enableCoveo?: boolean = false;
83
- private sidebarFooterContent: SiderbarFooter = { ...defaultSidebarFooter };
84
76
 
85
77
  private searchSyncer = new SearchSyncer({
86
78
  callbacks: {
@@ -222,6 +214,13 @@ export default class DocXmlContent extends LightningElementWithState<{
222
214
  disconnectedCallback(): void {
223
215
  window.removeEventListener("popstate", this.handlePopState);
224
216
  this.searchSyncer.dispose();
217
+ if (this.listenerAttached) {
218
+ this.pageHeader.removeEventListener(
219
+ "langchange",
220
+ this.handleLanguageChange
221
+ );
222
+ this.listenerAttached = false;
223
+ }
225
224
  }
226
225
 
227
226
  private get languageId(): string | undefined {
@@ -415,8 +414,12 @@ export default class DocXmlContent extends LightningElementWithState<{
415
414
  }
416
415
 
417
416
  getReferenceFromUrl(): PageReference {
418
- const [page, docId, deliverable, contentDocumentId] =
419
- window.location.pathname.substr(1).split("/");
417
+ const [
418
+ page,
419
+ docId,
420
+ deliverable,
421
+ contentDocumentId
422
+ ] = window.location.pathname.substr(1).split("/");
420
423
 
421
424
  const { origin: domain, hash, search } = window.location;
422
425
 
@@ -466,7 +469,7 @@ export default class DocXmlContent extends LightningElementWithState<{
466
469
  this.availableVersions = data.availableVersions;
467
470
  this.pdfUrl = data.pdfUrl;
468
471
 
469
- this.updateHeaderAndSidebarFooter();
472
+ this.updateHeader();
470
473
 
471
474
  this.buildBreadcrumbs();
472
475
 
@@ -530,7 +533,7 @@ export default class DocXmlContent extends LightningElementWithState<{
530
533
  });
531
534
  }
532
535
 
533
- updateHeaderAndSidebarFooter(): void {
536
+ updateHeader(): void {
534
537
  if (!this.pageHeader) {
535
538
  return;
536
539
  }
@@ -540,12 +543,20 @@ export default class DocXmlContent extends LightningElementWithState<{
540
543
  }
541
544
 
542
545
  if (this.pdfUrl) {
543
- this.sidebarFooterContent.bailHref = this.pdfUrl;
544
- this.sidebarFooterContent.bailLabel = "PDF";
546
+ this.pageHeader.bailHref = this.pdfUrl;
547
+ this.pageHeader.bailLabel = "PDF";
545
548
  }
546
549
 
547
- this.sidebarFooterContent.languages = this.availableLanguages;
548
- this.sidebarFooterContent.language = this.language?.id;
550
+ if (!this.listenerAttached) {
551
+ this.pageHeader.addEventListener(
552
+ "langchange",
553
+ this.handleLanguageChange
554
+ );
555
+ this.listenerAttached = true;
556
+ }
557
+
558
+ this.pageHeader.languages = this.availableLanguages;
559
+ this.pageHeader.language = this.language?.id;
549
560
 
550
561
  if (this.pageReference) {
551
562
  const { docId, deliverable, page } = this.pageReference;
@@ -570,14 +581,20 @@ export default class DocXmlContent extends LightningElementWithState<{
570
581
  }
571
582
 
572
583
  private updateSearchInput(searchParam: string): void {
573
- (
574
- this.template.querySelector("doc-content-layout") as any
575
- )?.setSidebarInputValue(searchParam);
584
+ (this.template.querySelector(
585
+ "doc-content-layout"
586
+ ) as any)?.setSidebarInputValue(searchParam);
576
587
  }
577
588
 
578
589
  private pageReferenceToString(reference: PageReference): string {
579
- const { page, docId, deliverable, contentDocumentId, hash, search } =
580
- reference;
590
+ const {
591
+ page,
592
+ docId,
593
+ deliverable,
594
+ contentDocumentId,
595
+ hash,
596
+ search
597
+ } = reference;
581
598
  return `/${page}/${docId}/${deliverable}/${contentDocumentId}${this.normalizeSearch(
582
599
  search!
583
600
  )}${this.normalizeHash(hash)}`;
@@ -1,44 +0,0 @@
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
- }
7
-
8
- .footer-display {
9
- display: flex;
10
- }
11
-
12
- .footer_lang-dropdown {
13
- display: flex;
14
- padding: 0 var(--dx-g-spacing-md);
15
- margin-left: var(--dx-g-spacing-sm);
16
- height: var(--dx-g-spacing-xl);
17
- border-radius: var(--dx-g-spacing-xs);
18
- align-items: center;
19
- }
20
-
21
- .footer_lang-dropdown > dx-button {
22
- --dx-c-button-primary-color: var(--button-primary-color);
23
- --dx-c-slot-empty-width: min-content;
24
- --border-color: var(--button-primary-color);
25
- }
26
-
27
- .footer_lang-dropdown:hover,
28
- .footer_lang-dropdown:active,
29
- .footer_lang-dropdown:focus,
30
- .pdf_bail-link:hover {
31
- background-color: var(--button-primary-color-hover);
32
-
33
- --border-color: var(--button-primary-color-hover);
34
- }
35
-
36
- .pdf_bail-link {
37
- --dx-c-button-horizontal-spacing: var(--dx-g-spacing-sm);
38
-
39
- padding: 0 var(--dx-g-spacing-md);
40
- border-radius: var(--dx-g-spacing-xs);
41
- display: flex;
42
- height: var(--dx-g-spacing-xl);
43
- align-items: center;
44
- }
@@ -1,59 +0,0 @@
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
- class="footer_lang-dropdown"
19
- options={languages}
20
- small
21
- value-path={langValuePath}
22
- value={language}
23
- onchange={onLangChange}
24
- variant="docoption"
25
- lang-picker="true"
26
- >
27
- <dx-button
28
- aria-label="Select Language"
29
- variant="inline"
30
- icon-size="medium"
31
- icon-symbol="world"
32
- >
33
- {languageLabel}
34
- </dx-button>
35
- </dx-dropdown>
36
- </div>
37
- <div if:true={mobile} class="footer-display">
38
- <dx-dropdown
39
- if:true={hasLanguages}
40
- class="footer_lang-dropdown"
41
- options={languages}
42
- small
43
- value-path={langValuePath}
44
- value={language}
45
- onchange={onLangChange}
46
- variant="docoption"
47
- lang-picker="true"
48
- >
49
- <dx-button
50
- aria-label="Select Language"
51
- variant="inline"
52
- icon-size="small"
53
- icon-symbol="world"
54
- >
55
- {languageLabel}
56
- </dx-button>
57
- </dx-dropdown>
58
- </div>
59
- </template>
@@ -1,109 +0,0 @@
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
- if (this._language !== value) {
31
- this._language = value;
32
- }
33
- }
34
-
35
- private _languages!: OptionWithLink[];
36
- private _language: string | null = null;
37
- private mobile: boolean = false;
38
- private matchMedia!: MediaQueryList;
39
-
40
- private get hasLanguages(): boolean {
41
- return !!(this.languages && this.languages.length > 1);
42
- }
43
-
44
- private get languageLabel(): string {
45
- return (
46
- (this.language &&
47
- this.languages.find(
48
- (lang) => get(lang, this.langValuePath) === this.language
49
- )?.label) ||
50
- this.languages[0].label
51
- );
52
- }
53
-
54
- get hasBailLink(): boolean {
55
- return !!(this.bailHref && this.bailLabel);
56
- }
57
-
58
- private onLangChange(event: CustomEvent<string>): void {
59
- const { detail } = event;
60
- this._language = detail;
61
-
62
- this.dispatchEvent(
63
- new CustomEvent("langchange", {
64
- detail,
65
- bubbles: true,
66
- composed: true
67
- })
68
- );
69
- }
70
-
71
- private getFilename = function (path: string) {
72
- return path.substring(path.lastIndexOf("/") + 1);
73
- };
74
-
75
- private handleBailClick(event: Event) {
76
- const payload = {
77
- click_text: "pdf",
78
- click_url: this.bailHref,
79
- element_title: "pdf",
80
- element_type: "link",
81
- content_category: "download"
82
- };
83
- track(event.target!, "custEv_pdfDownload", {
84
- ...payload,
85
- file_name: this.getFilename(this.bailHref!),
86
- file_extension: "pdf"
87
- });
88
-
89
- track(event.target!, "custEv_linkClick", {
90
- ...payload
91
- });
92
- }
93
-
94
- connectedCallback() {
95
- this.matchMedia = window.matchMedia(
96
- `(max-width: ${MOBILE_SIZE_MATCH})`
97
- );
98
- this.onMediaChange(this.matchMedia);
99
- this.matchMedia.addEventListener("change", this.onMediaChange);
100
- }
101
-
102
- disconnectedCallback() {
103
- this.matchMedia.removeEventListener("change", this.onMediaChange);
104
- }
105
-
106
- private onMediaChange = (event: MediaQueryListEvent | MediaQueryList) => {
107
- this.mobile = event.matches;
108
- };
109
- }