@salesforcedevs/docs-components 0.0.0 → 0.0.1-superscript
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 +12 -2
- package/package.json +29 -27
- package/src/modules/doc/{amfReference/utils.ts → amfModelParser/amfModelParser.ts} +10 -5
- package/src/modules/doc/amfReference/amfReference.css +11 -3
- package/src/modules/doc/amfReference/amfReference.html +35 -26
- package/src/modules/doc/amfReference/amfReference.ts +239 -95
- package/src/modules/doc/amfReference/types.ts +3 -11
- package/src/modules/doc/amfTopic/amfTopic.css +20 -0
- package/src/modules/doc/amfTopic/amfTopic.ts +59 -18
- package/src/modules/doc/amfTopic/types.ts +15 -13
- package/src/modules/doc/amfTopic/utils.ts +12 -6
- package/src/modules/doc/breadcrumbItem/breadcrumbItem.ts +17 -10
- package/src/modules/doc/breadcrumbs/breadcrumbs.html +6 -9
- package/src/modules/doc/breadcrumbs/breadcrumbs.ts +30 -34
- package/src/modules/doc/componentPlayground/componentPlayground.css +30 -0
- package/src/modules/doc/componentPlayground/componentPlayground.html +20 -0
- package/src/modules/doc/componentPlayground/componentPlayground.ts +97 -0
- package/src/modules/doc/content/content.css +70 -76
- package/src/modules/doc/content/content.html +1 -0
- package/src/modules/doc/content/content.ts +24 -46
- package/src/modules/doc/contentCallout/contentCallout.css +11 -7
- package/src/modules/doc/contentCallout/contentCallout.html +11 -4
- package/src/modules/doc/contentCallout/contentCallout.ts +8 -1
- package/src/modules/doc/contentLayout/contentLayout.css +1 -98
- package/src/modules/doc/contentLayout/contentLayout.html +46 -31
- package/src/modules/doc/contentLayout/contentLayout.ts +337 -89
- package/src/modules/doc/contentMedia/contentMedia.css +1 -1
- package/src/modules/doc/doDont/doDont.css +47 -0
- package/src/modules/doc/doDont/doDont.html +27 -0
- package/src/modules/doc/doDont/doDont.ts +17 -0
- package/src/modules/doc/header/header.css +65 -36
- package/src/modules/doc/header/header.html +44 -138
- package/src/modules/doc/header/header.ts +62 -74
- package/src/modules/doc/heading/heading.css +16 -37
- package/src/modules/doc/heading/heading.html +4 -4
- package/src/modules/doc/heading/heading.ts +12 -10
- package/src/modules/doc/headingAnchor/headingAnchor.css +2 -2
- package/src/modules/doc/headingAnchor/headingAnchor.ts +2 -2
- package/src/modules/doc/headingContent/headingContent.css +1 -1
- package/src/modules/doc/headingContent/headingContent.html +2 -2
- package/src/modules/doc/headingContent/headingContent.ts +2 -2
- package/src/modules/doc/lwcContentLayout/lwcContentLayout.css +9 -0
- package/src/modules/doc/lwcContentLayout/lwcContentLayout.html +64 -0
- package/src/modules/doc/lwcContentLayout/lwcContentLayout.ts +269 -0
- package/src/modules/doc/overview/overview.css +40 -0
- package/src/modules/doc/overview/overview.html +34 -0
- package/src/modules/doc/overview/overview.ts +12 -0
- package/src/modules/doc/phase/phase.css +11 -3
- package/src/modules/doc/phase/phase.html +12 -2
- package/src/modules/doc/phase/phase.ts +44 -8
- package/src/modules/doc/redocReference/redocReference.css +7 -0
- package/src/modules/doc/redocReference/redocReference.html +13 -0
- package/src/modules/doc/redocReference/redocReference.ts +425 -0
- package/src/modules/doc/specificationContent/specificationContent.css +36 -0
- package/src/modules/doc/specificationContent/specificationContent.html +177 -0
- package/src/modules/doc/specificationContent/specificationContent.ts +166 -0
- package/src/modules/doc/sprigSurvey/sprigSurvey.html +20 -0
- package/src/modules/doc/sprigSurvey/sprigSurvey.scoped.css +16 -0
- package/src/modules/doc/sprigSurvey/sprigSurvey.ts +16 -0
- package/src/modules/doc/superscriptSubscript/superscriptSubscript.html +8 -0
- package/src/modules/doc/superscriptSubscript/superscriptSubscript.ts +16 -0
- package/src/modules/doc/toc/toc.html +1 -3
- package/src/modules/doc/toc/toc.ts +1 -1
- package/src/modules/doc/toolbar/toolbar.ts +6 -6
- package/src/modules/doc/versionPicker/versionPicker.css +64 -0
- package/src/modules/doc/versionPicker/versionPicker.html +40 -0
- package/src/modules/doc/versionPicker/versionPicker.ts +65 -0
- package/src/modules/doc/xmlContent/types.ts +9 -3
- package/src/modules/doc/xmlContent/utils.ts +3 -1
- package/src/modules/doc/xmlContent/xmlContent.css +16 -4
- package/src/modules/doc/xmlContent/xmlContent.html +36 -21
- package/src/modules/doc/xmlContent/xmlContent.ts +295 -120
- package/src/modules/docHelpers/amfStyle/amfStyle.css +6 -8
- package/src/modules/docHelpers/contentLayoutStyle/contentLayoutStyle.css +162 -0
- package/src/modules/docHelpers/imgStyle/imgStyle.css +59 -0
- package/src/modules/docHelpers/status/status.css +1 -1
- package/src/modules/docUtils/{SearchSyncer/SearchSyncer.ts → searchSyncer/searchSyncer.ts} +1 -0
- package/src/modules/docUtils/utils/__mocks__/coveo.analytics.ts +16 -0
- package/src/modules/docUtils/utils/coveo.analytics.d.ts +10 -0
- package/src/modules/docUtils/utils/utils.ts +32 -0
- package/LICENSE +0 -12
- package/src/modules/docBaseElements/lightningElementWithState/lightningElementWithState.ts +0 -93
- package/src/modules/docHelpers/phaseContentLayout/phaseContentLayout.css +0 -39
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
/* eslint-disable @lwc/lwc/no-document-query */
|
|
1
2
|
import { LightningElement, api, track } from "lwc";
|
|
2
3
|
import { closest } from "kagekiri";
|
|
3
4
|
import { toJson } from "dxUtils/normalizers";
|
|
4
5
|
import { highlightTerms } from "dxUtils/highlight";
|
|
5
|
-
import { SearchSyncer } from "docUtils/
|
|
6
|
+
import { SearchSyncer } from "docUtils/searchSyncer";
|
|
7
|
+
import type { OptionWithLink } from "typings/custom";
|
|
8
|
+
import { buildDocLinkClickHandler } from "dxUtils/analytics";
|
|
6
9
|
|
|
7
10
|
type AnchorMap = { [key: string]: { intersect: boolean; id: string } };
|
|
8
11
|
|
|
9
|
-
const
|
|
12
|
+
declare const Sprig: (eventType: string, eventNme: string) => void;
|
|
13
|
+
|
|
14
|
+
const TOC_HEADER_TAG = "doc-heading";
|
|
15
|
+
|
|
10
16
|
const HIGHLIGHTABLE_SELECTOR = [
|
|
11
17
|
"p",
|
|
12
18
|
"h1",
|
|
@@ -20,25 +26,33 @@ const HIGHLIGHTABLE_SELECTOR = [
|
|
|
20
26
|
"th",
|
|
21
27
|
"td"
|
|
22
28
|
].join(",");
|
|
23
|
-
const OBSERVER_ATTACH_WAIT_TIME = 500;
|
|
29
|
+
export const OBSERVER_ATTACH_WAIT_TIME = 500;
|
|
24
30
|
|
|
25
31
|
export default class ContentLayout extends LightningElement {
|
|
26
|
-
@api sidebarValue
|
|
27
|
-
@api sidebarHeader
|
|
28
|
-
@api tocTitle
|
|
32
|
+
@api sidebarValue!: string;
|
|
33
|
+
@api sidebarHeader!: string;
|
|
34
|
+
@api tocTitle!: string;
|
|
29
35
|
@api enableSlotChange = false;
|
|
30
|
-
@api coveoOrganizationId!: string;
|
|
31
|
-
@api coveoPublicAccessToken!: string;
|
|
32
|
-
@api coveoSearchHub!: string;
|
|
33
|
-
@api coveoAdvancedQueryConfig!: string;
|
|
34
36
|
@api useOldSidebar?: boolean = false;
|
|
37
|
+
@api languages!: OptionWithLink[];
|
|
38
|
+
@api language!: string;
|
|
39
|
+
@api bailHref!: string;
|
|
40
|
+
@api bailLabel!: string;
|
|
41
|
+
@api devCenter: any;
|
|
42
|
+
@api brand: any;
|
|
43
|
+
@api emptyStateMessage?: string;
|
|
44
|
+
|
|
45
|
+
// This is needed for now to prevent failing snapshot tests due to links in the footer
|
|
46
|
+
@api showFooter = false;
|
|
47
|
+
|
|
48
|
+
@api readingTime?: number;
|
|
35
49
|
|
|
36
50
|
@api
|
|
37
51
|
get breadcrumbs() {
|
|
38
52
|
return this._breadcrumbs;
|
|
39
53
|
}
|
|
40
54
|
|
|
41
|
-
set breadcrumbs(value)
|
|
55
|
+
set breadcrumbs(value) {
|
|
42
56
|
if (value) {
|
|
43
57
|
this._breadcrumbs = toJson(value);
|
|
44
58
|
}
|
|
@@ -49,7 +63,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
49
63
|
return this._sidebarContent;
|
|
50
64
|
}
|
|
51
65
|
|
|
52
|
-
set sidebarContent(value) {
|
|
66
|
+
set sidebarContent(value: any) {
|
|
53
67
|
this._sidebarContent = toJson(value);
|
|
54
68
|
}
|
|
55
69
|
|
|
@@ -62,29 +76,41 @@ export default class ContentLayout extends LightningElement {
|
|
|
62
76
|
this._tocOptions = toJson(value);
|
|
63
77
|
}
|
|
64
78
|
|
|
79
|
+
/**
|
|
80
|
+
* The aria-level to filter headings by when building the TOC.
|
|
81
|
+
* Defaults to "2" (H2 headings).
|
|
82
|
+
*/
|
|
83
|
+
@api tocAriaLevel: string = "2";
|
|
84
|
+
|
|
65
85
|
@api
|
|
66
86
|
setSidebarInputValue(searchTerm: string): void {
|
|
67
|
-
this.template.querySelector("dx-sidebar")?.setInputValue(
|
|
87
|
+
(this.template.querySelector("dx-sidebar") as any)?.setInputValue(
|
|
88
|
+
searchTerm
|
|
89
|
+
);
|
|
68
90
|
}
|
|
69
91
|
|
|
70
92
|
@track
|
|
71
|
-
|
|
93
|
+
protected _sidebarContent: unknown;
|
|
72
94
|
|
|
73
|
-
|
|
95
|
+
protected _breadcrumbs = null;
|
|
74
96
|
|
|
75
97
|
@track
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
98
|
+
protected _tocOptions!: Array<unknown>;
|
|
99
|
+
|
|
100
|
+
protected tocOptionIdsSet = new Set();
|
|
101
|
+
protected anchoredElements: AnchorMap = {};
|
|
102
|
+
protected lastScrollPosition!: number;
|
|
103
|
+
protected observer?: IntersectionObserver;
|
|
104
|
+
protected hasRendered: boolean = false;
|
|
105
|
+
protected contentLoaded: boolean = false;
|
|
106
|
+
protected sidebarOpen: boolean = false;
|
|
107
|
+
|
|
108
|
+
get shouldDisplayFeedback() {
|
|
109
|
+
return this.contentLoaded && typeof Sprig !== "undefined";
|
|
110
|
+
}
|
|
82
111
|
|
|
83
|
-
|
|
112
|
+
protected searchSyncer = new SearchSyncer({
|
|
84
113
|
callbacks: {
|
|
85
|
-
onUrlChange: (nextSearchString: string): void => {
|
|
86
|
-
this.updateHighlightsAndSearch(nextSearchString);
|
|
87
|
-
},
|
|
88
114
|
onSearchChange: (nextSearchString: string): void => {
|
|
89
115
|
this.dispatchHighlightChange(
|
|
90
116
|
new URLSearchParams(nextSearchString).get("q") || ""
|
|
@@ -97,10 +123,12 @@ export default class ContentLayout extends LightningElement {
|
|
|
97
123
|
shouldStopPropagation: true,
|
|
98
124
|
target: window
|
|
99
125
|
});
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
126
|
+
protected tocValue?: string = undefined;
|
|
127
|
+
// eslint-disable-next-line no-undef
|
|
128
|
+
protected observerTimerId?: NodeJS.Timeout;
|
|
129
|
+
protected didScrollToSelectedHash = false;
|
|
130
|
+
protected _scrollInterval = 0;
|
|
131
|
+
protected handleLinkClick = buildDocLinkClickHandler();
|
|
104
132
|
|
|
105
133
|
get showToc(): boolean {
|
|
106
134
|
return this.tocOptions && this.tocOptions.length > 0;
|
|
@@ -117,8 +145,8 @@ export default class ContentLayout extends LightningElement {
|
|
|
117
145
|
);
|
|
118
146
|
}
|
|
119
147
|
|
|
120
|
-
get
|
|
121
|
-
return this.
|
|
148
|
+
get showReadingTime(): boolean {
|
|
149
|
+
return this.readingTime != null && this.readingTime > 1;
|
|
122
150
|
}
|
|
123
151
|
|
|
124
152
|
connectedCallback(): void {
|
|
@@ -134,11 +162,13 @@ export default class ContentLayout extends LightningElement {
|
|
|
134
162
|
this.searchSyncer.init();
|
|
135
163
|
}
|
|
136
164
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}, 1000);
|
|
165
|
+
// Add click handler for all links
|
|
166
|
+
this.template.addEventListener("click", this.handleLinkClick);
|
|
140
167
|
}
|
|
141
168
|
|
|
169
|
+
// Placeholder for childs renderedCallback
|
|
170
|
+
protected postRenderedCallback?(): void;
|
|
171
|
+
|
|
142
172
|
renderedCallback(): void {
|
|
143
173
|
/**
|
|
144
174
|
* Note: We are adding timeout because chrome is optimizing and not triggering recent renderedCallback though elements reference is changed
|
|
@@ -149,9 +179,17 @@ export default class ContentLayout extends LightningElement {
|
|
|
149
179
|
this.attachInteractionObserver,
|
|
150
180
|
OBSERVER_ATTACH_WAIT_TIME
|
|
151
181
|
);
|
|
182
|
+
|
|
183
|
+
this.adjustNavPosition();
|
|
184
|
+
window.addEventListener("scroll", this.adjustNavPosition);
|
|
185
|
+
window.addEventListener("resize", this.adjustNavPosition);
|
|
186
|
+
|
|
152
187
|
if (!this.hasRendered) {
|
|
153
188
|
this.hasRendered = true;
|
|
154
189
|
this.restoreScroll();
|
|
190
|
+
|
|
191
|
+
// Dynamically call `renderedCallbackForLwcContentLayout` if it exists
|
|
192
|
+
this.postRenderedCallback?.();
|
|
155
193
|
}
|
|
156
194
|
}
|
|
157
195
|
|
|
@@ -161,18 +199,15 @@ export default class ContentLayout extends LightningElement {
|
|
|
161
199
|
"highlightedtermchange",
|
|
162
200
|
this.updateHighlighted
|
|
163
201
|
);
|
|
202
|
+
window.removeEventListener("scroll", this.adjustNavPosition);
|
|
203
|
+
window.removeEventListener("resize", this.adjustNavPosition);
|
|
164
204
|
this.searchSyncer.dispose();
|
|
165
205
|
this.clearRenderObserverTimer();
|
|
166
206
|
|
|
167
207
|
window.clearInterval(this._scrollInterval);
|
|
168
|
-
}
|
|
169
208
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
{ scrollValue: document.body.scrollTop },
|
|
173
|
-
"",
|
|
174
|
-
window.location.href
|
|
175
|
-
);
|
|
209
|
+
// Remove link click handler
|
|
210
|
+
this.template.removeEventListener("click", this.handleLinkClick);
|
|
176
211
|
}
|
|
177
212
|
|
|
178
213
|
restoreScroll() {
|
|
@@ -186,98 +221,297 @@ export default class ContentLayout extends LightningElement {
|
|
|
186
221
|
}
|
|
187
222
|
};
|
|
188
223
|
|
|
224
|
+
/*
|
|
225
|
+
This is a workaround for the global nav sticky header being decoupled from the doc header & doc phase.
|
|
226
|
+
We have to account for the global nav changing height due to animations.
|
|
227
|
+
*/
|
|
228
|
+
adjustNavPosition = () => {
|
|
229
|
+
const sidebarEl = this.template.querySelector("dx-sidebar-old");
|
|
230
|
+
const globalNavEl = document.querySelector(
|
|
231
|
+
"hgf-c360nav"
|
|
232
|
+
) as HTMLElement;
|
|
233
|
+
const contextNavEl = document.querySelector(
|
|
234
|
+
"hgf-c360contextnav"
|
|
235
|
+
) as HTMLElement;
|
|
236
|
+
const docHeaderEl = document.querySelector(
|
|
237
|
+
".sticky-doc-header"
|
|
238
|
+
) as HTMLElement;
|
|
239
|
+
|
|
240
|
+
const docPhaseWrapper = this.template.querySelector(
|
|
241
|
+
".doc-phase-wrapper"
|
|
242
|
+
) as HTMLElement;
|
|
243
|
+
const versionWrapper = this.template.querySelector(
|
|
244
|
+
".version-wrapper"
|
|
245
|
+
) as HTMLElement;
|
|
246
|
+
|
|
247
|
+
const docPhaseEl = (
|
|
248
|
+
docPhaseWrapper.querySelector("[name=doc-phase]")! as any
|
|
249
|
+
).assignedElements()[0] as HTMLSlotElement;
|
|
250
|
+
|
|
251
|
+
const verBannerEl = (
|
|
252
|
+
versionWrapper.querySelector("[name=version-banner]")! as any
|
|
253
|
+
).assignedElements()[0] as HTMLSlotElement;
|
|
254
|
+
|
|
255
|
+
if (!sidebarEl || !globalNavEl || !contextNavEl || !docHeaderEl) {
|
|
256
|
+
console.warn("One or more required elements are missing.");
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// sync with the browser to account for any reflows that may have happened
|
|
261
|
+
requestAnimationFrame(() => {
|
|
262
|
+
// ternary is a temporary fix for the global nav height reporting incorrectly on some browsers
|
|
263
|
+
const globalNavHeight =
|
|
264
|
+
(globalNavEl.getBoundingClientRect().height !== 72 ? 0 : 72) +
|
|
265
|
+
contextNavEl.getBoundingClientRect().height;
|
|
266
|
+
const docHeaderHeight = docHeaderEl.getBoundingClientRect().height;
|
|
267
|
+
const totalHeaderHeight = globalNavHeight + docHeaderHeight;
|
|
268
|
+
|
|
269
|
+
// Selecting the doc section heading and RNB here.
|
|
270
|
+
const docHeadingEls = Array.from(
|
|
271
|
+
document.querySelectorAll("doc-heading")
|
|
272
|
+
);
|
|
273
|
+
const rightNavBarEl = this.template.querySelector(".right-nav-bar");
|
|
274
|
+
|
|
275
|
+
sidebarEl.style.setProperty(
|
|
276
|
+
"--dx-c-content-sidebar-sticky-top",
|
|
277
|
+
`${globalNavHeight + docHeaderHeight}px`
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
docHeaderEl.style.setProperty(
|
|
281
|
+
"--dx-g-global-header-height",
|
|
282
|
+
`${globalNavHeight}px`
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
const docPhaseElHeight =
|
|
286
|
+
docPhaseEl || verBannerEl
|
|
287
|
+
? (docPhaseEl || verBannerEl).getBoundingClientRect().height
|
|
288
|
+
: 0;
|
|
289
|
+
|
|
290
|
+
// Adjusting the doc section heading on scroll.
|
|
291
|
+
docHeadingEls.forEach((docHeadingEl) => {
|
|
292
|
+
(docHeadingEl as any).style.scrollMarginTop = `${
|
|
293
|
+
totalHeaderHeight + docPhaseElHeight + 40
|
|
294
|
+
}px`;
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Adjusting the right nav bar on scroll.
|
|
298
|
+
// setting maxheight to make the RNB scrollable based on different parent elements
|
|
299
|
+
if (rightNavBarEl) {
|
|
300
|
+
const viewportHeight = window.innerHeight;
|
|
301
|
+
const maxHeight =
|
|
302
|
+
viewportHeight -
|
|
303
|
+
(docPhaseElHeight + totalHeaderHeight + 24); //added some margin of dx-toc
|
|
304
|
+
|
|
305
|
+
rightNavBarEl.style.top = `${
|
|
306
|
+
totalHeaderHeight + docPhaseElHeight
|
|
307
|
+
}px`;
|
|
308
|
+
|
|
309
|
+
const toc = rightNavBarEl.querySelector("dx-toc");
|
|
310
|
+
const listContainer = toc?.shadowRoot?.querySelector(
|
|
311
|
+
".toc"
|
|
312
|
+
) as HTMLElement;
|
|
313
|
+
|
|
314
|
+
if (listContainer) {
|
|
315
|
+
listContainer.style.maxHeight = `${maxHeight}px`;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const docPhaseTop =
|
|
320
|
+
window.innerWidth < 769
|
|
321
|
+
? globalNavHeight +
|
|
322
|
+
docHeaderHeight +
|
|
323
|
+
sidebarEl.getBoundingClientRect().height
|
|
324
|
+
: globalNavHeight + docHeaderHeight;
|
|
325
|
+
|
|
326
|
+
// If doc phase element exists, we need to account for its sticky position. Mobile should include the sidebar height (since it becomes sticky aswell).
|
|
327
|
+
// To handle sticky position for safari browser, position sticky given to wrapper class
|
|
328
|
+
if (docPhaseEl) {
|
|
329
|
+
docPhaseWrapper.style.top = `${docPhaseTop}px`;
|
|
330
|
+
} else if (verBannerEl) {
|
|
331
|
+
versionWrapper.style.position = "sticky";
|
|
332
|
+
versionWrapper.style.top = `${docPhaseTop}px`;
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
};
|
|
336
|
+
|
|
189
337
|
updateHighlighted = (event: Event): void =>
|
|
190
338
|
highlightTerms(
|
|
191
339
|
this.querySelectorAll(HIGHLIGHTABLE_SELECTOR),
|
|
192
340
|
(event as CustomEvent<string>).detail
|
|
193
341
|
);
|
|
194
342
|
|
|
195
|
-
|
|
196
|
-
if (!this.enableSlotChange) {
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
this.disconnectObserver();
|
|
200
|
-
this.observer = new IntersectionObserver((entries) => {
|
|
201
|
-
entries.forEach(
|
|
202
|
-
(entry) =>
|
|
203
|
-
(this.anchoredElements[
|
|
204
|
-
entry.target.getAttribute("id")
|
|
205
|
-
].intersect = entry.isIntersecting)
|
|
206
|
-
);
|
|
207
|
-
this.calculateActualSection();
|
|
208
|
-
});
|
|
209
|
-
|
|
343
|
+
protected getHeadingElements() {
|
|
210
344
|
// Note: We are doing document.querySelectorAll as a quick fix as we are not getting heading elements reference this.querySelectorAll
|
|
211
345
|
const headingElements = document.querySelectorAll(TOC_HEADER_TAG);
|
|
212
|
-
|
|
346
|
+
return headingElements;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
updateHeadingForRNB(): void {
|
|
350
|
+
const headingElements = this.getHeadingElements();
|
|
351
|
+
this.addObserverAndScroll(headingElements);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
addObserverAndScroll(headingElements: any) {
|
|
355
|
+
for (const headingElement of headingElements as any) {
|
|
213
356
|
// Add headingElements to intersectionObserver for highlighting respective RNB item when user scroll
|
|
214
|
-
const id = headingElement.getAttribute("id")
|
|
357
|
+
const id = headingElement.getAttribute("id")!;
|
|
215
358
|
this.anchoredElements[id] = {
|
|
216
359
|
id,
|
|
217
360
|
intersect: false
|
|
218
361
|
};
|
|
219
|
-
this.observer
|
|
362
|
+
this.observer?.observe(headingElement);
|
|
220
363
|
}
|
|
364
|
+
|
|
221
365
|
if (!this.didScrollToSelectedHash) {
|
|
222
366
|
this.didScrollToSelectedHash = true;
|
|
223
367
|
this.scrollToHash(headingElements);
|
|
224
368
|
}
|
|
225
|
-
}
|
|
369
|
+
}
|
|
226
370
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
371
|
+
attachInteractionObserver = (): void => {
|
|
372
|
+
if (!this.enableSlotChange) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
this.disconnectObserver();
|
|
231
376
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
377
|
+
const globalNavOffset = `-${getComputedStyle(
|
|
378
|
+
document.documentElement
|
|
379
|
+
).getPropertyValue("--dx-g-doc-header-main-nav-height")}`;
|
|
380
|
+
|
|
381
|
+
this.observer = new IntersectionObserver(
|
|
382
|
+
(entries) => {
|
|
383
|
+
entries.forEach(
|
|
384
|
+
(entry) =>
|
|
385
|
+
(this.anchoredElements[
|
|
386
|
+
entry.target.getAttribute("id")!
|
|
387
|
+
].intersect = entry.isIntersecting)
|
|
237
388
|
);
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
389
|
+
this.calculateActualSection();
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
rootMargin: globalNavOffset.trim()
|
|
241
393
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
394
|
+
);
|
|
395
|
+
this.updateHeadingForRNB();
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// eslint-disable-next-line no-undef
|
|
399
|
+
updateTocItems(headingElements: any): void {
|
|
400
|
+
const tocOptions = [];
|
|
245
401
|
|
|
246
|
-
|
|
402
|
+
const maxLevel = Number.parseInt(this.tocAriaLevel, 10) || 2;
|
|
403
|
+
const minLevel = 2;
|
|
404
|
+
|
|
405
|
+
for (const headingElement of headingElements as any) {
|
|
406
|
+
headingElement.id = headingElement.hash;
|
|
407
|
+
|
|
408
|
+
// Update tocOptions from anchorTags for aria-levels 2..tocAriaLevel (inclusive)
|
|
409
|
+
const headingAriaLevel =
|
|
410
|
+
headingElement.attributes["aria-level"]?.nodeValue || "2";
|
|
411
|
+
const headingLevel = Number.parseInt(headingAriaLevel, 10) || 2;
|
|
412
|
+
const matchesLevel =
|
|
413
|
+
headingLevel >= minLevel && headingLevel <= maxLevel;
|
|
414
|
+
|
|
415
|
+
if (matchesLevel) {
|
|
247
416
|
const tocItem = {
|
|
248
417
|
anchor: `#${headingElement.hash}`,
|
|
249
418
|
id: headingElement.id,
|
|
250
|
-
label: headingElement.
|
|
419
|
+
label: headingElement.header,
|
|
420
|
+
level: headingLevel
|
|
251
421
|
};
|
|
252
422
|
tocOptions.push(tocItem);
|
|
423
|
+
this.tocOptionIdsSet.add(headingElement.id);
|
|
253
424
|
}
|
|
425
|
+
}
|
|
254
426
|
|
|
255
|
-
|
|
427
|
+
this._tocOptions = tocOptions;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
setHashAndHeaderForDocHeading(headingElements: any) {
|
|
431
|
+
for (const headingElement of headingElements as any) {
|
|
432
|
+
// Sometimes elements hash and header is not being set when slot content is wrapped with div
|
|
433
|
+
if (!headingElement.hash) {
|
|
434
|
+
headingElement.hash = headingElement.attributes.hash?.nodeValue;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (!headingElement.header) {
|
|
438
|
+
headingElement.header =
|
|
439
|
+
headingElement.attributes.header?.nodeValue;
|
|
440
|
+
}
|
|
256
441
|
}
|
|
442
|
+
|
|
443
|
+
this.updateTocItems(headingElements);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
updateRNB = () => {
|
|
447
|
+
const headingElements = this.getHeadingElements();
|
|
448
|
+
this.setHashAndHeaderForDocHeading(headingElements);
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
onSlotChange(): void {
|
|
452
|
+
this.updateRNB();
|
|
453
|
+
this.contentLoaded = true;
|
|
257
454
|
}
|
|
258
455
|
|
|
259
|
-
|
|
456
|
+
protected disconnectObserver(): void {
|
|
260
457
|
if (this.observer) {
|
|
261
458
|
this.observer.disconnect();
|
|
262
|
-
this.observer =
|
|
459
|
+
this.observer = undefined;
|
|
263
460
|
}
|
|
264
461
|
}
|
|
265
462
|
|
|
266
463
|
// eslint-disable-next-line no-undef
|
|
267
|
-
|
|
464
|
+
protected scrollToHash(headingElements: NodeListOf<Element>): void {
|
|
268
465
|
let { hash } = window.location;
|
|
269
466
|
if (hash) {
|
|
270
467
|
hash = hash.substr(1);
|
|
271
|
-
|
|
468
|
+
|
|
469
|
+
const docHeaderEl = document.querySelector(
|
|
470
|
+
".sticky-doc-header"
|
|
471
|
+
) as HTMLElement;
|
|
472
|
+
const globalNavEl = document.querySelector(
|
|
473
|
+
"hgf-c360nav"
|
|
474
|
+
) as HTMLElement;
|
|
475
|
+
const contextNavEl = document.querySelector(
|
|
476
|
+
"hgf-c360contextnav"
|
|
477
|
+
) as HTMLElement;
|
|
478
|
+
|
|
479
|
+
const headerHeight =
|
|
480
|
+
docHeaderEl?.offsetHeight +
|
|
481
|
+
globalNavEl?.offsetHeight +
|
|
482
|
+
contextNavEl?.offsetHeight;
|
|
483
|
+
|
|
484
|
+
const docPhaseEl = (
|
|
485
|
+
this.template.querySelector("[name=doc-phase]")! as any
|
|
486
|
+
).assignedElements()[0] as HTMLSlotElement;
|
|
487
|
+
|
|
488
|
+
const offset = docPhaseEl
|
|
489
|
+
? headerHeight + docPhaseEl.offsetHeight
|
|
490
|
+
: headerHeight;
|
|
491
|
+
|
|
492
|
+
for (const headingElement of headingElements as any) {
|
|
272
493
|
if (headingElement.getAttribute("id") === hash) {
|
|
273
|
-
|
|
494
|
+
this.scrollIntoViewWithOffset(headingElement, offset);
|
|
274
495
|
break;
|
|
275
496
|
}
|
|
276
497
|
}
|
|
277
498
|
}
|
|
278
499
|
}
|
|
279
500
|
|
|
280
|
-
|
|
501
|
+
protected scrollIntoViewWithOffset(
|
|
502
|
+
headingElement: HTMLElement,
|
|
503
|
+
offset: number
|
|
504
|
+
) {
|
|
505
|
+
window.scrollTo({
|
|
506
|
+
behavior: "auto",
|
|
507
|
+
top:
|
|
508
|
+
headingElement.getBoundingClientRect().top -
|
|
509
|
+
document.body.getBoundingClientRect().top -
|
|
510
|
+
offset
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
protected calculateActualSection(): void {
|
|
281
515
|
const currentScrollPosition = document.documentElement.scrollTop;
|
|
282
516
|
const id = Object.keys(this.anchoredElements).find(
|
|
283
517
|
(_id) => this.anchoredElements[_id].intersect
|
|
@@ -292,18 +526,21 @@ export default class ContentLayout extends LightningElement {
|
|
|
292
526
|
this.lastScrollPosition = currentScrollPosition;
|
|
293
527
|
}
|
|
294
528
|
|
|
295
|
-
|
|
529
|
+
protected calculatePreviousElementId(): string | undefined {
|
|
296
530
|
const keys = Object.keys(this.anchoredElements);
|
|
297
531
|
const currentIndex = keys.findIndex((id) => this.tocValue === id);
|
|
298
532
|
|
|
299
533
|
return currentIndex > 0 ? keys[currentIndex - 1] : undefined;
|
|
300
534
|
}
|
|
301
535
|
|
|
302
|
-
|
|
303
|
-
|
|
536
|
+
protected assignElementId(id: string | undefined): void {
|
|
537
|
+
// Change toc(RNB) highlight only for H2
|
|
538
|
+
if (this.tocOptionIdsSet.has(id)) {
|
|
539
|
+
this.tocValue = id;
|
|
540
|
+
}
|
|
304
541
|
}
|
|
305
542
|
|
|
306
|
-
|
|
543
|
+
protected dispatchHighlightChange(term: string): void {
|
|
307
544
|
this.dispatchEvent(
|
|
308
545
|
new CustomEvent("highlightedtermchange", {
|
|
309
546
|
detail: term,
|
|
@@ -313,10 +550,21 @@ export default class ContentLayout extends LightningElement {
|
|
|
313
550
|
);
|
|
314
551
|
}
|
|
315
552
|
|
|
316
|
-
|
|
553
|
+
protected updateHighlightsAndSearch(nextSearchString: string): void {
|
|
317
554
|
const nextSearchParam =
|
|
318
555
|
new URLSearchParams(nextSearchString).get("q") || "";
|
|
319
556
|
this.setSidebarInputValue(nextSearchParam);
|
|
320
557
|
this.dispatchHighlightChange(nextSearchParam);
|
|
321
558
|
}
|
|
559
|
+
|
|
560
|
+
protected onToggleSidebar(e: CustomEvent): void {
|
|
561
|
+
this.sidebarOpen = e.detail.open;
|
|
562
|
+
|
|
563
|
+
// eslint-disable-next-line @lwc/lwc/no-document-query
|
|
564
|
+
const footer = document.querySelector("dx-footer") as HTMLElement;
|
|
565
|
+
|
|
566
|
+
if (footer) {
|
|
567
|
+
footer.style.display = this.sidebarOpen ? "none" : "block";
|
|
568
|
+
}
|
|
569
|
+
}
|
|
322
570
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
@import "dxHelpers/reset";
|
|
2
|
+
@import "dxHelpers/text";
|
|
3
|
+
|
|
4
|
+
.container {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
gap: var(--dx-g-spacing-md);
|
|
8
|
+
flex: 1;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.doc-do-dont-header {
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
gap: var(--dx-g-spacing-sm);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.doc-do-dont-label {
|
|
18
|
+
font-family: var(--dx-g-font-display);
|
|
19
|
+
font-size: var(--dx-g-spacing-md);
|
|
20
|
+
font-weight: var(--dx-g-font-demi);
|
|
21
|
+
line-height: var(--dx-g-spacing-lg);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.doc-do-color {
|
|
25
|
+
color: var(--dx-g-green-vibrant-50);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.doc-dont-color {
|
|
29
|
+
color: var(--dx-g-red-vibrant-30);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.do-dont-image-container {
|
|
33
|
+
display: flex;
|
|
34
|
+
max-height: 480px;
|
|
35
|
+
min-height: 140px;
|
|
36
|
+
padding: var(--dx-g-spacing-3xl) var(--dx-g-spacing-2xl);
|
|
37
|
+
flex-direction: column;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
align-items: center;
|
|
40
|
+
flex: 1;
|
|
41
|
+
border-radius: var(--dx-g-spacing-sm);
|
|
42
|
+
border: 1px solid var(--dx-g-brand-default-color-border-2);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.doc-do-dont-img {
|
|
46
|
+
object-fit: contain;
|
|
47
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="container">
|
|
3
|
+
<div class="doc-do-dont-header">
|
|
4
|
+
<template lwc:if={isDo}>
|
|
5
|
+
<dx-icon
|
|
6
|
+
symbol="success"
|
|
7
|
+
size="large"
|
|
8
|
+
color="green-vibrant-50"
|
|
9
|
+
></dx-icon>
|
|
10
|
+
<div class="doc-do-dont-label doc-do-color">Do</div>
|
|
11
|
+
</template>
|
|
12
|
+
<template lwc:else>
|
|
13
|
+
<dx-icon
|
|
14
|
+
symbol="clear"
|
|
15
|
+
size="large"
|
|
16
|
+
color="red-vibrant-30"
|
|
17
|
+
class="doc-do-dont-icon"
|
|
18
|
+
></dx-icon>
|
|
19
|
+
<div class="doc-do-dont-label doc-dont-color">Don't</div>
|
|
20
|
+
</template>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="do-dont-image-container">
|
|
23
|
+
<img class="doc-do-dont-img" src={imgSrc} alt={caption} />
|
|
24
|
+
</div>
|
|
25
|
+
<div class="dx-text-body-4">{caption}</div>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|