@salesforcedevs/docs-components 1.28.0 → 1.28.1-banner-0

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
@@ -6,6 +6,8 @@
6
6
  ],
7
7
  "expose": [
8
8
  "doc/amfReference",
9
+ "doc/banner",
10
+ "doc/localeBanner",
9
11
  "doc/breadcrumbs",
10
12
  "doc/componentPlayground",
11
13
  "doc/content",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/docs-components",
3
- "version": "1.28.0",
3
+ "version": "1.28.1-banner-0",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -25,5 +25,5 @@
25
25
  "@types/lodash.orderby": "4.6.9",
26
26
  "@types/lodash.uniqby": "4.7.9"
27
27
  },
28
- "gitHead": "4027270163b2eb9610b911a09bfa31f536061fe4"
28
+ "gitHead": "602f3fab502240f4098c97535ee601f1f7a522e5"
29
29
  }
@@ -0,0 +1,92 @@
1
+ @import "dxHelpers/reset";
2
+ @import "dxHelpers/text";
3
+
4
+ :host {
5
+ display: block;
6
+
7
+ --doc-banner-padding-left: var(--dx-g-spacing-2xl);
8
+ --doc-banner-padding-right: var(--dx-g-spacing-lg);
9
+ --doc-close-width: calc(var(--dx-g-spacing-3xl) + var(--dx-g-spacing-xs));
10
+ --doc-close-height: calc(var(--dx-g-spacing-2xl) + var(--dx-g-spacing-xs));
11
+ --doc-banner-spacing-16px: var(--dx-g-spacing-md);
12
+ }
13
+
14
+ .container {
15
+ display: flex;
16
+ align-items: flex-start;
17
+ background: var(--dx-g-gray-90);
18
+ padding: 0 var(--doc-banner-padding-right) 0 var(--doc-banner-padding-left);
19
+ }
20
+
21
+ .icon {
22
+ --dx-c-icon-size: var(--dx-g-icon-size-lg);
23
+
24
+ flex-shrink: 0;
25
+ width: var(--dx-g-icon-size-lg);
26
+ height: var(--dx-g-icon-size-lg);
27
+ margin-top: var(--dx-g-spacing-smd);
28
+ margin-right: var(--dx-g-spacing-sm);
29
+ }
30
+
31
+ .main {
32
+ flex: 1;
33
+ min-width: 0;
34
+ display: flex;
35
+ flex-wrap: wrap;
36
+ align-items: flex-start;
37
+ column-gap: var(--doc-banner-spacing-16px);
38
+ padding: calc((var(--dx-g-spacing-xs) + var(--dx-g-spacing-sm)) / 2) 0;
39
+ }
40
+
41
+ .message {
42
+ flex: 0 1 auto;
43
+ font-size: var(--dx-g-text-sm);
44
+ color: var(--dx-g-gray-10);
45
+ padding: calc((var(--dx-g-spacing-xs) + var(--dx-g-spacing-sm)) / 2) 0;
46
+ }
47
+
48
+ .message a {
49
+ color: var(--dx-g-cloud-blue-vibrant-50);
50
+ text-decoration: underline;
51
+ }
52
+
53
+ .actions {
54
+ flex: 0 0 auto;
55
+ display: flex;
56
+ align-items: center;
57
+ gap: var(--dx-g-spacing-smd);
58
+ }
59
+
60
+ .actions dx-button {
61
+ --dx-c-button-font-size: var(--dx-g-text-sm);
62
+ --dx-c-button-font-weight: var(--dx-g-font-normal);
63
+
64
+ flex: 0 0 auto;
65
+ }
66
+
67
+ .close {
68
+ --dx-c-icon-size: var(--dx-g-icon-size-lg);
69
+
70
+ flex-shrink: 0;
71
+ align-self: flex-start;
72
+ width: var(--doc-close-width);
73
+ height: var(--doc-close-height);
74
+ margin-left: auto;
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ }
79
+
80
+ @media (max-width: 1279px) {
81
+ :host {
82
+ --doc-banner-padding-left: var(--dx-g-spacing-xl);
83
+ --doc-banner-padding-right: var(--dx-g-spacing-md);
84
+ }
85
+ }
86
+
87
+ @media (max-width: 768px) {
88
+ :host {
89
+ --doc-banner-padding-left: var(--dx-g-spacing-lg);
90
+ --doc-banner-padding-right: var(--dx-g-spacing-sm);
91
+ }
92
+ }
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <template lwc:if={showBanner}>
3
+ <div class="container" part="container">
4
+ <dx-icon
5
+ class="icon"
6
+ symbol="info"
7
+ size="override"
8
+ color="gray-50"
9
+ part="icon"
10
+ ></dx-icon>
11
+ <div class="main">
12
+ <div class="message" part="message" lwc:dom="manual"></div>
13
+ <div class="actions" part="actions">
14
+ <template lwc:if={hasPrimaryButton}>
15
+ <dx-button
16
+ href={buttonHref}
17
+ variant="primary"
18
+ size="small"
19
+ part="button"
20
+ >
21
+ {buttonLabel}
22
+ </dx-button>
23
+ </template>
24
+ <template lwc:if={hasSecondaryAction}>
25
+ <dx-button
26
+ variant="inline"
27
+ onclick={handleSecondaryClick}
28
+ part="secondary"
29
+ >
30
+ {secondaryLabel}
31
+ </dx-button>
32
+ </template>
33
+ </div>
34
+ </div>
35
+ <dx-button
36
+ class="close"
37
+ variant="icon-only"
38
+ icon-symbol="close"
39
+ icon-size="override"
40
+ icon-color="gray-50"
41
+ aria-label="Close"
42
+ onclick={handleCloseClick}
43
+ part="close"
44
+ ></dx-button>
45
+ </div>
46
+ </template>
47
+ </template>
@@ -0,0 +1,81 @@
1
+ import { LightningElement, api, track } from "lwc";
2
+
3
+ const BANNER_STORAGE_PREFIX = "doc-banner-";
4
+
5
+ export default class Banner extends LightningElement {
6
+ @api message = "";
7
+
8
+ @api buttonLabel = "";
9
+
10
+ @api buttonHref = "";
11
+
12
+ @api secondaryLabel = "";
13
+
14
+ @api dismissStorageKey = "";
15
+
16
+ @track private _dismissed = false;
17
+
18
+ connectedCallback() {
19
+ if (
20
+ this.dismissStorageKey &&
21
+ typeof window !== "undefined" &&
22
+ window.sessionStorage
23
+ ) {
24
+ this._dismissed =
25
+ window.sessionStorage.getItem(
26
+ `${BANNER_STORAGE_PREFIX}${this.dismissStorageKey}`
27
+ ) === "true";
28
+ }
29
+ }
30
+
31
+ renderedCallback() {
32
+ if (this.message) {
33
+ const messageElement = this.template.querySelector(".message");
34
+ if (messageElement) {
35
+ messageElement.innerHTML = this.message;
36
+ }
37
+ }
38
+ }
39
+
40
+ get showBanner(): boolean {
41
+ return !this._dismissed;
42
+ }
43
+
44
+ get hasPrimaryButton(): boolean {
45
+ return !!(this.buttonLabel && this.buttonHref);
46
+ }
47
+
48
+ get hasSecondaryAction(): boolean {
49
+ return !!this.secondaryLabel;
50
+ }
51
+
52
+ private dismissBanner() {
53
+ if (
54
+ this.dismissStorageKey &&
55
+ typeof window !== "undefined" &&
56
+ window.sessionStorage
57
+ ) {
58
+ window.sessionStorage.setItem(
59
+ `${BANNER_STORAGE_PREFIX}${this.dismissStorageKey}`,
60
+ "true"
61
+ );
62
+ }
63
+ this._dismissed = true;
64
+ this.dispatchEvent(
65
+ new CustomEvent("dismissbanner", {
66
+ bubbles: true,
67
+ composed: true
68
+ })
69
+ );
70
+ }
71
+
72
+ @api
73
+ handleSecondaryClick() {
74
+ this.dismissBanner();
75
+ }
76
+
77
+ @api
78
+ handleCloseClick() {
79
+ this.dismissBanner();
80
+ }
81
+ }
@@ -0,0 +1,3 @@
1
+ :host {
2
+ display: block;
3
+ }
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <doc-banner
3
+ message={bannerMessage}
4
+ button-label={bannerButtonLabel}
5
+ button-href={bannerButtonHref}
6
+ secondary-label={bannerSecondaryLabel}
7
+ dismiss-storage-key={dismissStorageKey}
8
+ ></doc-banner>
9
+ </template>
@@ -0,0 +1,57 @@
1
+ import { LightningElement, api } from "lwc";
2
+
3
+ interface LocaleStrings {
4
+ messageText: string;
5
+ linkUrl: string;
6
+ linkText: string;
7
+ buttonLabel: string;
8
+ secondaryLabel: string;
9
+ }
10
+
11
+ const LOCALE_STRINGS: Record<string, LocaleStrings> = {
12
+ "en-us": {
13
+ messageText:
14
+ "This text was translated using Salesforce's machine translation system. More details can be found ",
15
+ linkUrl:
16
+ "https://help.salesforce.com/s/articleView?language=en&id=000396076&type=1",
17
+ linkText: "here",
18
+ buttonLabel: "Switch to English",
19
+ secondaryLabel: "Not Now"
20
+ },
21
+ "ja-jp": {
22
+ messageText:
23
+ "このテキストは Salesforce の機械翻訳システムを使用して翻訳されました。詳細は ",
24
+ linkUrl:
25
+ "https://help.salesforce.com/s/articleView?language=ja&id=000396076&type=1",
26
+ linkText: "こちら",
27
+ buttonLabel: "英語に切り替える",
28
+ secondaryLabel: "後で"
29
+ }
30
+ };
31
+
32
+ export default class LocaleBanner extends LightningElement {
33
+ @api locale = "en-us";
34
+ @api targetHref = "";
35
+ @api dismissStorageKey = "";
36
+
37
+ get localeData(): LocaleStrings {
38
+ return LOCALE_STRINGS[this.locale] || LOCALE_STRINGS["en-us"];
39
+ }
40
+
41
+ get bannerMessage(): string {
42
+ const data = this.localeData;
43
+ return `${data.messageText}<a href="${data.linkUrl}">${data.linkText}</a>`;
44
+ }
45
+
46
+ get bannerButtonLabel(): string {
47
+ return this.localeData.buttonLabel;
48
+ }
49
+
50
+ get bannerButtonHref(): string {
51
+ return this.targetHref;
52
+ }
53
+
54
+ get bannerSecondaryLabel(): string {
55
+ return this.localeData.secondaryLabel;
56
+ }
57
+ }
@@ -57,7 +57,10 @@
57
57
  </div>
58
58
  </div>
59
59
  <div lwc:if={showFooter} class="footer-container">
60
- <dx-footer variant="no-signup" mfe-config-origin={effectiveFooterOrigin}></dx-footer>
60
+ <dx-footer
61
+ variant="no-signup"
62
+ mfe-config-origin={effectiveFooterOrigin}
63
+ ></dx-footer>
61
64
  </div>
62
65
  </div>
63
66
  </div>
@@ -322,8 +322,10 @@ export default class DocXmlContent extends LightningElementWithState<{
322
322
  };
323
323
  }
324
324
 
325
- private handlePopState = (event: PopStateEvent): void =>
325
+ private handlePopState = (event: PopStateEvent): void => {
326
326
  this.updatePageReference(this.getReferenceFromUrl(), event);
327
+ this.handleLocaleReload();
328
+ };
327
329
 
328
330
  handleDismissVersionBanner() {
329
331
  this.showVersionBanner = false;
@@ -598,6 +600,30 @@ export default class DocXmlContent extends LightningElementWithState<{
598
600
  "docs",
599
601
  this.pageReferenceToString(this.pageReference)
600
602
  );
603
+ this.handleLocaleReload();
604
+ }
605
+
606
+ private handleLocaleReload(): void {
607
+ const targetLocale = this.language?.id;
608
+ if (!targetLocale) {
609
+ return;
610
+ }
611
+
612
+ const currentPath = window.location.pathname;
613
+ const localePattern = /atlas\.[a-z]{2}-[a-z]{2}\./;
614
+
615
+ if (localePattern.test(currentPath)) {
616
+ const newPath = currentPath.replace(
617
+ localePattern,
618
+ `atlas.${targetLocale}.`
619
+ );
620
+ const newUrl =
621
+ window.location.origin +
622
+ newPath +
623
+ window.location.search +
624
+ window.location.hash;
625
+ window.location.href = newUrl;
626
+ }
601
627
  }
602
628
 
603
629
  private updateHighlighting(searchParam: string): void {