@salesforcedevs/docs-components 1.27.22-banner → 1.27.22-banner11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/modules/doc/banner/banner.css +128 -52
- package/src/modules/doc/banner/banner.html +58 -66
- package/src/modules/doc/banner/banner.ts +43 -1
- package/src/modules/doc/contentLayout/contentLayout.html +3 -0
- package/src/modules/doc/contentLayout/contentLayout.ts +30 -11
- package/src/modules/doc/xmlContent/xmlContent.html +12 -0
- package/src/modules/doc/xmlContent/xmlContent.ts +107 -9
- package/src/modules/docHelpers/contentLayoutStyle/contentLayoutStyle.css +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/docs-components",
|
|
3
|
-
"version": "1.27.22-
|
|
3
|
+
"version": "1.27.22-banner11",
|
|
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": "
|
|
28
|
+
"gitHead": "ea29a6b1c177ea33e34105b1ad4a1ec3e9bb4b54"
|
|
29
29
|
}
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
@import "dxHelpers/text";
|
|
3
3
|
|
|
4
4
|
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
|
|
5
7
|
--doc-banner-bg: var(--neutral-90, #e5e5e5);
|
|
6
8
|
--doc-banner-height: 44px;
|
|
7
9
|
--doc-banner-padding-x-left: 40px;
|
|
8
|
-
--doc-banner-padding-x-right:
|
|
9
|
-
--doc-banner-icon-size:
|
|
10
|
-
--doc-banner-
|
|
10
|
+
--doc-banner-padding-x-right: var(--dx-g-spacing-lg);
|
|
11
|
+
--doc-banner-icon-size: 18.4615px;
|
|
12
|
+
--doc-banner-icon-frame-width: calc(
|
|
13
|
+
var(--doc-banner-padding-x-left) + var(--doc-banner-icon-size) +
|
|
14
|
+
var(--dx-g-spacing-sm)
|
|
15
|
+
);
|
|
11
16
|
--doc-banner-close-color: #747474;
|
|
12
17
|
--doc-banner-primary-bg: #0176d3;
|
|
13
18
|
--doc-banner-primary-bg-hover: #0160b3;
|
|
@@ -15,29 +20,45 @@
|
|
|
15
20
|
|
|
16
21
|
.doc-notification-bar {
|
|
17
22
|
display: flex;
|
|
18
|
-
align-items:
|
|
23
|
+
align-items: flex-start;
|
|
19
24
|
justify-content: space-between;
|
|
20
25
|
width: 100%;
|
|
21
|
-
|
|
22
|
-
height: var(--doc-banner-height);
|
|
23
|
-
padding
|
|
24
|
-
|
|
26
|
+
margin: 0;
|
|
27
|
+
min-height: var(--doc-banner-height);
|
|
28
|
+
padding: 0 var(--doc-banner-padding-x-right) 0
|
|
29
|
+
var(--doc-banner-padding-x-left);
|
|
25
30
|
background: var(--doc-banner-bg);
|
|
26
31
|
box-sizing: border-box;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
.doc-notification-bar .icon-wrap,
|
|
35
|
+
.doc-notification-bar .main,
|
|
36
|
+
.doc-notification-bar .content,
|
|
30
37
|
.doc-notification-bar .actions,
|
|
31
38
|
.doc-notification-bar .close-wrap {
|
|
32
39
|
display: flex;
|
|
33
40
|
align-items: center;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.doc-notification-bar .icon-wrap,
|
|
44
|
+
.doc-notification-bar .close-wrap {
|
|
34
45
|
flex-shrink: 0;
|
|
35
46
|
}
|
|
36
47
|
|
|
48
|
+
.doc-notification-bar .main {
|
|
49
|
+
flex: 1 1 0;
|
|
50
|
+
min-width: 0;
|
|
51
|
+
align-self: flex-start;
|
|
52
|
+
padding: 6px 0;
|
|
53
|
+
gap: var(--dx-g-spacing-md);
|
|
54
|
+
}
|
|
55
|
+
|
|
37
56
|
.doc-notification-bar .icon-wrap {
|
|
38
|
-
width:
|
|
39
|
-
height:
|
|
40
|
-
|
|
57
|
+
width: calc(var(--doc-banner-icon-size) + var(--dx-g-spacing-sm));
|
|
58
|
+
min-height: 32px;
|
|
59
|
+
align-self: flex-start;
|
|
60
|
+
justify-content: flex-start;
|
|
61
|
+
align-items: flex-start;
|
|
41
62
|
}
|
|
42
63
|
|
|
43
64
|
.doc-notification-bar .icon-wrap dx-icon {
|
|
@@ -45,21 +66,25 @@
|
|
|
45
66
|
|
|
46
67
|
width: var(--doc-banner-icon-size);
|
|
47
68
|
height: var(--doc-banner-icon-size);
|
|
69
|
+
padding: 12px 8px 0 0;
|
|
70
|
+
box-sizing: content-box;
|
|
48
71
|
}
|
|
49
72
|
|
|
50
73
|
.doc-notification-bar .content {
|
|
51
|
-
flex: 1;
|
|
74
|
+
flex: 0 1 auto;
|
|
52
75
|
min-width: 0;
|
|
53
|
-
max-width:
|
|
54
|
-
height:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
align-items: center;
|
|
58
|
-
box-sizing: border-box;
|
|
76
|
+
max-width: 100%;
|
|
77
|
+
min-height: 32px;
|
|
78
|
+
align-items: flex-start;
|
|
79
|
+
gap: var(--dx-g-spacing-sm);
|
|
59
80
|
}
|
|
60
81
|
|
|
61
82
|
.doc-notification-bar .message {
|
|
62
83
|
margin: 0;
|
|
84
|
+
padding: 6px 0;
|
|
85
|
+
font-size: 14px;
|
|
86
|
+
font-weight: 400;
|
|
87
|
+
line-height: 20px;
|
|
63
88
|
color: var(--dx-g-neutral-30, #444);
|
|
64
89
|
}
|
|
65
90
|
|
|
@@ -73,9 +98,10 @@
|
|
|
73
98
|
}
|
|
74
99
|
|
|
75
100
|
.doc-notification-bar .actions {
|
|
76
|
-
|
|
77
|
-
height: 32px;
|
|
78
|
-
gap: var(--dx-g-spacing-
|
|
101
|
+
flex-shrink: 0;
|
|
102
|
+
min-height: 32px;
|
|
103
|
+
gap: var(--dx-g-spacing-smd);
|
|
104
|
+
flex-wrap: wrap;
|
|
79
105
|
}
|
|
80
106
|
|
|
81
107
|
.doc-notification-bar .primary-btn {
|
|
@@ -84,52 +110,102 @@
|
|
|
84
110
|
--dx-c-button-vertical-spacing: 0;
|
|
85
111
|
--dx-c-button-horizontal-spacing: var(--dx-g-spacing-md);
|
|
86
112
|
|
|
87
|
-
min-width: 144px;
|
|
113
|
+
min-width: min(144px, 100%);
|
|
88
114
|
height: 32px;
|
|
89
|
-
border-radius:
|
|
115
|
+
border-radius: var(--dx-g-spacing-xs);
|
|
90
116
|
}
|
|
91
117
|
|
|
92
118
|
.doc-notification-bar .primary-btn::part(container) {
|
|
93
|
-
min-width: 144px;
|
|
119
|
+
min-width: min(144px, 100%);
|
|
94
120
|
width: 100%;
|
|
95
121
|
height: 32px;
|
|
96
122
|
padding: 0 var(--dx-g-spacing-md);
|
|
97
|
-
border-radius:
|
|
98
|
-
|
|
123
|
+
border-radius: var(--dx-g-spacing-xs);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.doc-notification-bar .secondary-btn {
|
|
127
|
+
font-weight: var(--dx-g-font-normal);
|
|
99
128
|
}
|
|
100
129
|
|
|
101
130
|
.doc-notification-bar .close-wrap {
|
|
131
|
+
align-self: flex-start;
|
|
102
132
|
justify-content: center;
|
|
133
|
+
align-items: center;
|
|
103
134
|
width: 52px;
|
|
104
|
-
height:
|
|
135
|
+
height: 44px;
|
|
136
|
+
padding: 12px 8px 18px;
|
|
137
|
+
margin-left: auto;
|
|
138
|
+
box-sizing: border-box;
|
|
105
139
|
}
|
|
106
140
|
|
|
107
|
-
.doc-notification-bar .close {
|
|
108
|
-
display: flex;
|
|
109
|
-
align-items: center;
|
|
110
|
-
justify-content: center;
|
|
141
|
+
.doc-notification-bar .close-wrap .close-btn {
|
|
111
142
|
width: 100%;
|
|
112
143
|
height: 100%;
|
|
113
|
-
padding: 2.9px;
|
|
114
|
-
margin: 0;
|
|
115
|
-
color: var(--doc-banner-close-color);
|
|
116
|
-
background: none;
|
|
117
|
-
border: none;
|
|
118
|
-
cursor: pointer;
|
|
119
|
-
border-radius: 0;
|
|
120
|
-
box-sizing: border-box;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.doc-notification-bar .close:hover {
|
|
124
|
-
background: rgb(0 0 0 / 5%);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
.doc-notification-bar .close svg {
|
|
128
|
-
width: var(--doc-banner-close-icon-size);
|
|
129
|
-
height: var(--doc-banner-close-icon-size);
|
|
130
|
-
flex-shrink: 0;
|
|
131
|
-
}
|
|
132
144
|
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
--dx-c-button-custom-color: var(--doc-banner-close-color);
|
|
146
|
+
--dx-c-button-custom-color-hover: var(--doc-banner-close-color);
|
|
147
|
+
--dx-c-button-custom-background: transparent;
|
|
148
|
+
--dx-c-button-custom-background-hover: rgb(0 0 0 / 5%);
|
|
149
|
+
--dx-c-button-custom-border: none;
|
|
150
|
+
--dx-c-button-custom-border-hover: none;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@media (max-width: 1279px) {
|
|
154
|
+
:host {
|
|
155
|
+
--doc-banner-padding-x-left: 32px;
|
|
156
|
+
--doc-banner-padding-x-right: var(--dx-g-spacing-md);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.doc-notification-bar {
|
|
160
|
+
position: relative;
|
|
161
|
+
max-width: 100%;
|
|
162
|
+
min-height: 78px;
|
|
163
|
+
flex-wrap: wrap;
|
|
164
|
+
align-content: space-between;
|
|
165
|
+
padding: 0 var(--doc-banner-padding-x-right) 0 0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.doc-notification-bar .icon-wrap {
|
|
169
|
+
position: absolute;
|
|
170
|
+
left: 0;
|
|
171
|
+
top: 0;
|
|
172
|
+
bottom: 0;
|
|
173
|
+
width: var(--doc-banner-icon-frame-width);
|
|
174
|
+
min-height: 0;
|
|
175
|
+
padding: 0 0 0 var(--doc-banner-padding-x-left);
|
|
176
|
+
order: 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.doc-notification-bar .main {
|
|
180
|
+
order: 1;
|
|
181
|
+
flex-wrap: wrap;
|
|
182
|
+
margin-left: var(--doc-banner-icon-frame-width);
|
|
183
|
+
gap: var(--dx-g-spacing-2xs);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.doc-notification-bar .content {
|
|
187
|
+
order: 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.doc-notification-bar .close-wrap {
|
|
191
|
+
order: 2;
|
|
192
|
+
min-height: 44px;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.doc-notification-bar .actions {
|
|
196
|
+
order: 1;
|
|
197
|
+
flex: 0 0 100%;
|
|
198
|
+
width: 100%;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@media (max-width: 768px) {
|
|
203
|
+
:host {
|
|
204
|
+
--doc-banner-padding-x-left: 24px;
|
|
205
|
+
--doc-banner-padding-x-right: var(--dx-g-spacing-sm);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.doc-notification-bar {
|
|
209
|
+
min-height: 44px;
|
|
210
|
+
}
|
|
135
211
|
}
|
|
@@ -1,70 +1,62 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<div class="
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
2
|
+
<template lwc:if={showBanner}>
|
|
3
|
+
<div class="doc-notification-bar" part="container">
|
|
4
|
+
<div class="icon-wrap" part="icon-wrap">
|
|
5
|
+
<dx-icon symbol="info" part="icon" color="#747474"></dx-icon>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="main" part="main">
|
|
8
|
+
<div class="content" part="content">
|
|
9
|
+
<p class="message dx-text-body-4" part="message">
|
|
10
|
+
<template lwc:if={messageText}>{messageText}</template>
|
|
11
|
+
<template lwc:if={hasMessageLink}>
|
|
12
|
+
<a
|
|
13
|
+
href={messageLinkUrl}
|
|
14
|
+
target="_blank"
|
|
15
|
+
rel="noopener noreferrer"
|
|
16
|
+
part="message-link"
|
|
17
|
+
>
|
|
18
|
+
{messageLinkText}
|
|
19
|
+
</a>
|
|
20
|
+
</template>
|
|
21
|
+
</p>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="actions" part="actions">
|
|
24
|
+
<template lwc:if={hasPrimaryButton}>
|
|
25
|
+
<dx-button
|
|
26
|
+
class="primary-btn"
|
|
27
|
+
href={buttonHref}
|
|
28
|
+
variant="primary"
|
|
29
|
+
size="small"
|
|
30
|
+
part="button"
|
|
31
|
+
>
|
|
32
|
+
{buttonLabel}
|
|
33
|
+
</dx-button>
|
|
34
|
+
</template>
|
|
35
|
+
<template lwc:if={hasSecondaryAction}>
|
|
36
|
+
<dx-button
|
|
37
|
+
class="secondary-btn"
|
|
38
|
+
variant="inline"
|
|
39
|
+
onclick={handleSecondaryClick}
|
|
40
|
+
part="secondary"
|
|
41
|
+
>
|
|
42
|
+
{secondaryLabel}
|
|
43
|
+
</dx-button>
|
|
44
|
+
</template>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<template lwc:if={showCloseButton}>
|
|
48
|
+
<div class="close-wrap" part="close-wrap">
|
|
49
|
+
<dx-button
|
|
50
|
+
class="close-btn"
|
|
51
|
+
variant="icon-only"
|
|
52
|
+
icon-symbol="close"
|
|
53
|
+
icon-color="#747474"
|
|
54
|
+
aria-label="Close"
|
|
55
|
+
onclick={handleCloseClick}
|
|
56
|
+
part="close"
|
|
57
|
+
></dx-button>
|
|
58
|
+
</div>
|
|
41
59
|
</template>
|
|
42
60
|
</div>
|
|
43
|
-
|
|
44
|
-
<div class="close-wrap" part="close-wrap">
|
|
45
|
-
<button
|
|
46
|
-
type="button"
|
|
47
|
-
class="close"
|
|
48
|
-
part="close"
|
|
49
|
-
aria-label="Close"
|
|
50
|
-
onclick={handleCloseClick}
|
|
51
|
-
>
|
|
52
|
-
<svg
|
|
53
|
-
width="14"
|
|
54
|
-
height="14"
|
|
55
|
-
viewBox="0 0 14 14"
|
|
56
|
-
fill="none"
|
|
57
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
58
|
-
aria-hidden="true"
|
|
59
|
-
>
|
|
60
|
-
<path
|
|
61
|
-
d="M1 1L13 13M13 1L1 13"
|
|
62
|
-
stroke-width="2"
|
|
63
|
-
stroke-linecap="round"
|
|
64
|
-
/>
|
|
65
|
-
</svg>
|
|
66
|
-
</button>
|
|
67
|
-
</div>
|
|
68
|
-
</template>
|
|
69
|
-
</div>
|
|
61
|
+
</template>
|
|
70
62
|
</template>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { LightningElement, api } from "lwc";
|
|
1
|
+
import { LightningElement, api, track } from "lwc";
|
|
2
2
|
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
3
3
|
|
|
4
|
+
const LOCALE_BANNER_STORAGE_PREFIX = "dsc-doc-locale-banner-dismissed-";
|
|
5
|
+
|
|
4
6
|
export default class Banner extends LightningElement {
|
|
5
7
|
@api messageText = "";
|
|
6
8
|
|
|
@@ -14,6 +16,8 @@ export default class Banner extends LightningElement {
|
|
|
14
16
|
|
|
15
17
|
@api secondaryLabel = "";
|
|
16
18
|
|
|
19
|
+
@api dismissStorageKey = "";
|
|
20
|
+
|
|
17
21
|
_showCloseButton = false;
|
|
18
22
|
|
|
19
23
|
@api
|
|
@@ -24,6 +28,28 @@ export default class Banner extends LightningElement {
|
|
|
24
28
|
this._showCloseButton = normalizeBoolean(value);
|
|
25
29
|
}
|
|
26
30
|
|
|
31
|
+
@track private _dismissed = false;
|
|
32
|
+
|
|
33
|
+
connectedCallback() {
|
|
34
|
+
if (
|
|
35
|
+
this.dismissStorageKey &&
|
|
36
|
+
typeof window !== "undefined" &&
|
|
37
|
+
window.sessionStorage
|
|
38
|
+
) {
|
|
39
|
+
this._dismissed =
|
|
40
|
+
window.sessionStorage.getItem(
|
|
41
|
+
`${LOCALE_BANNER_STORAGE_PREFIX}${this.dismissStorageKey}`
|
|
42
|
+
) === "true";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get showBanner(): boolean {
|
|
47
|
+
if (!this.dismissStorageKey) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return !this._dismissed;
|
|
51
|
+
}
|
|
52
|
+
|
|
27
53
|
get hasMessageLink(): boolean {
|
|
28
54
|
return !!this.messageLinkUrl;
|
|
29
55
|
}
|
|
@@ -36,13 +62,29 @@ export default class Banner extends LightningElement {
|
|
|
36
62
|
return !!this.secondaryLabel;
|
|
37
63
|
}
|
|
38
64
|
|
|
65
|
+
persistDismissAndHide() {
|
|
66
|
+
if (
|
|
67
|
+
this.dismissStorageKey &&
|
|
68
|
+
typeof window !== "undefined" &&
|
|
69
|
+
window.sessionStorage
|
|
70
|
+
) {
|
|
71
|
+
window.sessionStorage.setItem(
|
|
72
|
+
`${LOCALE_BANNER_STORAGE_PREFIX}${this.dismissStorageKey}`,
|
|
73
|
+
"true"
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
this._dismissed = true;
|
|
77
|
+
}
|
|
78
|
+
|
|
39
79
|
handleSecondaryClick() {
|
|
80
|
+
this.persistDismissAndHide();
|
|
40
81
|
this.dispatchEvent(
|
|
41
82
|
new CustomEvent("dismiss", { bubbles: true, composed: true })
|
|
42
83
|
);
|
|
43
84
|
}
|
|
44
85
|
|
|
45
86
|
handleCloseClick() {
|
|
87
|
+
this.persistDismissAndHide();
|
|
46
88
|
this.dispatchEvent(
|
|
47
89
|
new CustomEvent("dismiss", { bubbles: true, composed: true })
|
|
48
90
|
);
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
<slot name="sidebar-header" slot="version-picker"></slot>
|
|
18
18
|
</dx-sidebar-old>
|
|
19
19
|
<div class="content-body-doc-phase-container">
|
|
20
|
+
<div class="locale-notification-wrapper">
|
|
21
|
+
<slot name="locale-banner"></slot>
|
|
22
|
+
</div>
|
|
20
23
|
<div class="doc-phase-wrapper">
|
|
21
24
|
<slot name="doc-phase"></slot>
|
|
22
25
|
</div>
|
|
@@ -268,6 +268,9 @@ export default class ContentLayout extends LightningElement {
|
|
|
268
268
|
".sticky-doc-header"
|
|
269
269
|
) as HTMLElement;
|
|
270
270
|
|
|
271
|
+
const localeBannerWrapper = this.template.querySelector(
|
|
272
|
+
".locale-notification-wrapper"
|
|
273
|
+
) as HTMLElement;
|
|
271
274
|
const docPhaseWrapper = this.template.querySelector(
|
|
272
275
|
".doc-phase-wrapper"
|
|
273
276
|
) as HTMLElement;
|
|
@@ -275,6 +278,12 @@ export default class ContentLayout extends LightningElement {
|
|
|
275
278
|
".version-wrapper"
|
|
276
279
|
) as HTMLElement;
|
|
277
280
|
|
|
281
|
+
const localeBannerSlot = localeBannerWrapper?.querySelector(
|
|
282
|
+
"[name=locale-banner]"
|
|
283
|
+
) as HTMLSlotElement | null;
|
|
284
|
+
const localeBannerEl = localeBannerSlot?.assignedElements?.()[0] as
|
|
285
|
+
| HTMLElement
|
|
286
|
+
| undefined;
|
|
278
287
|
const docPhaseEl = (
|
|
279
288
|
docPhaseWrapper.querySelector("[name=doc-phase]")! as any
|
|
280
289
|
).assignedElements()[0] as HTMLSlotElement;
|
|
@@ -297,6 +306,12 @@ export default class ContentLayout extends LightningElement {
|
|
|
297
306
|
const docHeaderHeight = docHeaderEl.getBoundingClientRect().height;
|
|
298
307
|
const totalHeaderHeight = globalNavHeight + docHeaderHeight;
|
|
299
308
|
|
|
309
|
+
const localeBannerHeight = localeBannerEl?.offsetHeight ?? 0;
|
|
310
|
+
const docPhaseElHeight =
|
|
311
|
+
(docPhaseEl?.getBoundingClientRect?.()?.height ?? 0) +
|
|
312
|
+
(verBannerEl?.getBoundingClientRect?.()?.height ?? 0);
|
|
313
|
+
const totalBannerHeight = localeBannerHeight + docPhaseElHeight;
|
|
314
|
+
|
|
300
315
|
// Selecting the doc section heading and RNB here.
|
|
301
316
|
const docHeadingEls = Array.from(
|
|
302
317
|
document.querySelectorAll("doc-heading")
|
|
@@ -313,15 +328,10 @@ export default class ContentLayout extends LightningElement {
|
|
|
313
328
|
`${globalNavHeight}px`
|
|
314
329
|
);
|
|
315
330
|
|
|
316
|
-
const docPhaseElHeight =
|
|
317
|
-
docPhaseEl || verBannerEl
|
|
318
|
-
? (docPhaseEl || verBannerEl).getBoundingClientRect().height
|
|
319
|
-
: 0;
|
|
320
|
-
|
|
321
331
|
// Adjusting the doc section heading on scroll.
|
|
322
332
|
docHeadingEls.forEach((docHeadingEl) => {
|
|
323
333
|
(docHeadingEl as any).style.scrollMarginTop = `${
|
|
324
|
-
totalHeaderHeight +
|
|
334
|
+
totalHeaderHeight + totalBannerHeight + 40
|
|
325
335
|
}px`;
|
|
326
336
|
});
|
|
327
337
|
|
|
@@ -331,10 +341,10 @@ export default class ContentLayout extends LightningElement {
|
|
|
331
341
|
const viewportHeight = window.innerHeight;
|
|
332
342
|
const maxHeight =
|
|
333
343
|
viewportHeight -
|
|
334
|
-
(
|
|
344
|
+
(totalBannerHeight + totalHeaderHeight + 24); //added some margin of dx-toc
|
|
335
345
|
|
|
336
346
|
rightNavBarEl.style.top = `${
|
|
337
|
-
totalHeaderHeight +
|
|
347
|
+
totalHeaderHeight + totalBannerHeight
|
|
338
348
|
}px`;
|
|
339
349
|
|
|
340
350
|
const toc = rightNavBarEl.querySelector("dx-toc");
|
|
@@ -512,13 +522,22 @@ export default class ContentLayout extends LightningElement {
|
|
|
512
522
|
globalNavEl?.offsetHeight +
|
|
513
523
|
contextNavEl?.offsetHeight;
|
|
514
524
|
|
|
525
|
+
const localeBannerWrapper = this.template.querySelector(
|
|
526
|
+
".locale-notification-wrapper"
|
|
527
|
+
) as HTMLElement;
|
|
528
|
+
const localeBannerSlot = localeBannerWrapper?.querySelector(
|
|
529
|
+
"[name=locale-banner]"
|
|
530
|
+
) as HTMLSlotElement | null;
|
|
531
|
+
const localeBannerEl = localeBannerSlot?.assignedElements?.()[0] as
|
|
532
|
+
| HTMLElement
|
|
533
|
+
| undefined;
|
|
515
534
|
const docPhaseEl = (
|
|
516
535
|
this.template.querySelector("[name=doc-phase]")! as any
|
|
517
536
|
).assignedElements()[0] as HTMLSlotElement;
|
|
518
537
|
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
538
|
+
const localeBannerHeight = localeBannerEl?.offsetHeight ?? 0;
|
|
539
|
+
const docPhaseHeight = docPhaseEl?.offsetHeight ?? 0;
|
|
540
|
+
const offset = headerHeight + localeBannerHeight + docPhaseHeight;
|
|
522
541
|
|
|
523
542
|
for (const headingElement of headingElements as any) {
|
|
524
543
|
if (headingElement.getAttribute("id") === hash) {
|
|
@@ -15,6 +15,18 @@
|
|
|
15
15
|
reading-time={computedReadingTime}
|
|
16
16
|
origin={origin}
|
|
17
17
|
>
|
|
18
|
+
<doc-banner
|
|
19
|
+
slot="locale-banner"
|
|
20
|
+
lwc:if={showLocaleBannerInSlot}
|
|
21
|
+
message-text="This text was translated using Salesforce's machine translation system. More details can be found "
|
|
22
|
+
message-link-url="https://help.salesforce.com/s/articleView?id=sf.machine_translation.htm"
|
|
23
|
+
message-link-text="here"
|
|
24
|
+
button-label="Switch to English"
|
|
25
|
+
button-href={localeBannerEnUsHref}
|
|
26
|
+
secondary-label="Not Now"
|
|
27
|
+
show-close-button="true"
|
|
28
|
+
dismiss-storage-key={deliverable}
|
|
29
|
+
></doc-banner>
|
|
18
30
|
<doc-phase
|
|
19
31
|
slot="version-banner"
|
|
20
32
|
lwc:if={showVersionBanner}
|
|
@@ -17,6 +17,7 @@ import { LightningElementWithState } from "dxBaseElements/lightningElementWithSt
|
|
|
17
17
|
import { oldVersionDocInfo } from "docUtils/utils";
|
|
18
18
|
import { Breadcrumb, DocPhaseInfo, Language } from "typings/custom";
|
|
19
19
|
import { track as trackGTM } from "dxUtils/analytics";
|
|
20
|
+
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
20
21
|
import DOMPurify from "dompurify";
|
|
21
22
|
|
|
22
23
|
// TODO: Imitating from actual implementation as doc-content use it like this. We should refactor it later.
|
|
@@ -48,6 +49,11 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
48
49
|
/** Optional origin URL for the footer MFE (e.g. wp-json endpoint). Passed through to dx-footer-mfe. */
|
|
49
50
|
@api origin: string | null = null;
|
|
50
51
|
|
|
52
|
+
/** Optional base URL for the canonical link (e.g. https://developer.salesforce.com). When set, used instead of window.location for the canonical href. */
|
|
53
|
+
@api baseUrl: string | null = null;
|
|
54
|
+
|
|
55
|
+
@api localeBannerEnabled = false;
|
|
56
|
+
|
|
51
57
|
@api
|
|
52
58
|
get allLanguages(): Array<Language> {
|
|
53
59
|
return this._allLanguages;
|
|
@@ -74,6 +80,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
74
80
|
private docTitle = "";
|
|
75
81
|
private _pathName = "";
|
|
76
82
|
private listenerAttached = false;
|
|
83
|
+
private _xmlLocaleBannerDispatched = false;
|
|
77
84
|
private sidebarFooterContent: SiderbarFooter = { ...defaultSidebarFooter };
|
|
78
85
|
private latestVersion = false;
|
|
79
86
|
private previewVersion = false;
|
|
@@ -215,6 +222,15 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
215
222
|
this.setState({ internalLinkClicked: false });
|
|
216
223
|
}
|
|
217
224
|
|
|
225
|
+
if (
|
|
226
|
+
this.displayContent &&
|
|
227
|
+
!normalizeBoolean(this.localeBannerEnabled) &&
|
|
228
|
+
this.shouldShowLocaleBanner &&
|
|
229
|
+
!this._xmlLocaleBannerDispatched
|
|
230
|
+
) {
|
|
231
|
+
this.injectLocaleBannerIntoThemeHost();
|
|
232
|
+
}
|
|
233
|
+
|
|
218
234
|
if (
|
|
219
235
|
(this.prevState.isFetchingContent &&
|
|
220
236
|
!this.state.isFetchingContent) ||
|
|
@@ -251,6 +267,90 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
251
267
|
return this.pageReference.deliverable;
|
|
252
268
|
}
|
|
253
269
|
|
|
270
|
+
private get showLocaleBannerInSlot(): boolean {
|
|
271
|
+
return (
|
|
272
|
+
normalizeBoolean(this.localeBannerEnabled) &&
|
|
273
|
+
this.shouldShowLocaleBanner
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private get shouldShowLocaleBanner(): boolean {
|
|
278
|
+
if (!this.pageReference?.deliverable) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
if (!this.language || this.language.id === "en-us") {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
const hasEnUs = this.availableLanguages?.some(
|
|
285
|
+
(lang: DocLanguage) => lang.id === "en-us"
|
|
286
|
+
);
|
|
287
|
+
return !!hasEnUs;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
private get localeBannerEnUsHref(): string {
|
|
291
|
+
if (!this.pageReference) {
|
|
292
|
+
return "";
|
|
293
|
+
}
|
|
294
|
+
const enUsLanguage = this.availableLanguages?.find(
|
|
295
|
+
(lang: DocLanguage) => lang.id === "en-us"
|
|
296
|
+
);
|
|
297
|
+
if (!enUsLanguage) {
|
|
298
|
+
return "";
|
|
299
|
+
}
|
|
300
|
+
return this.pageReferenceToString({
|
|
301
|
+
...this.pageReference,
|
|
302
|
+
docId: enUsLanguage.url
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
private injectLocaleBannerIntoThemeHost(retryCount = 0): void {
|
|
307
|
+
if (typeof document === "undefined") {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const host = document.getElementById("doc-xml-locale-banner-host");
|
|
311
|
+
if (!host) {
|
|
312
|
+
const maxRetries = 5;
|
|
313
|
+
const delays = [100, 300, 500, 800, 1200];
|
|
314
|
+
if (retryCount < maxRetries) {
|
|
315
|
+
const delay = delays[retryCount] ?? 1200;
|
|
316
|
+
setTimeout(
|
|
317
|
+
() => this.injectLocaleBannerIntoThemeHost(retryCount + 1),
|
|
318
|
+
delay
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
if (host.hasChildNodes()) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const banner = document.createElement("doc-banner");
|
|
327
|
+
banner.setAttribute(
|
|
328
|
+
"message-text",
|
|
329
|
+
"This text was translated using Salesforce's machine translation system. More details can be found "
|
|
330
|
+
);
|
|
331
|
+
banner.setAttribute(
|
|
332
|
+
"message-link-url",
|
|
333
|
+
"https://help.salesforce.com/s/articleView?id=sf.machine_translation.htm"
|
|
334
|
+
);
|
|
335
|
+
banner.setAttribute("message-link-text", "here");
|
|
336
|
+
banner.setAttribute("button-label", "Switch to English");
|
|
337
|
+
banner.setAttribute("button-href", this.localeBannerEnUsHref);
|
|
338
|
+
banner.setAttribute("secondary-label", "Not Now");
|
|
339
|
+
banner.setAttribute("show-close-button", "true");
|
|
340
|
+
banner.setAttribute(
|
|
341
|
+
"dismiss-storage-key",
|
|
342
|
+
this.deliverable || "default"
|
|
343
|
+
);
|
|
344
|
+
host.setAttribute("aria-hidden", "false");
|
|
345
|
+
this._xmlLocaleBannerDispatched = true;
|
|
346
|
+
// Defer append so custom element can upgrade and host :empty state updates next frame
|
|
347
|
+
requestAnimationFrame(() => {
|
|
348
|
+
if (!host.hasChildNodes()) {
|
|
349
|
+
host.appendChild(banner);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
254
354
|
private get useOldSidebar(): boolean {
|
|
255
355
|
// Coveo is enabled and the version is greater than 51 (within the latest 3 versions)
|
|
256
356
|
// TODO: we need a better fix for version number check
|
|
@@ -766,21 +866,19 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
766
866
|
}
|
|
767
867
|
|
|
768
868
|
if (this.pageReference) {
|
|
769
|
-
const
|
|
869
|
+
const canonicalLink = document.querySelector(
|
|
770
870
|
'link[rel="canonical"]'
|
|
771
871
|
);
|
|
772
|
-
if (
|
|
872
|
+
if (canonicalLink) {
|
|
773
873
|
const copyPageReference = { ...this.pageReference };
|
|
774
874
|
copyPageReference.docId = copyPageReference.docId
|
|
775
875
|
? this.dropVersionFromDocId(copyPageReference.docId)
|
|
776
876
|
: copyPageReference.docId;
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
this.pageReferenceToString(copyPageReference)
|
|
783
|
-
);
|
|
877
|
+
const path = this.pageReferenceToString(copyPageReference);
|
|
878
|
+
const origin = this.baseUrl
|
|
879
|
+
? this.baseUrl.replace(/\/$/, "")
|
|
880
|
+
: `${window.location.protocol}//${window.location.host}`;
|
|
881
|
+
canonicalLink.setAttribute("href", `${origin}${path}`);
|
|
784
882
|
}
|
|
785
883
|
}
|
|
786
884
|
|