@salesforcedevs/docs-components 1.3.327-do-dont-1 → 1.3.327-rnbtab-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/package.json
CHANGED
|
@@ -11,6 +11,7 @@ type AnchorMap = { [key: string]: { intersect: boolean; id: string } };
|
|
|
11
11
|
declare const Sprig: (eventType: string, eventNme: string) => void;
|
|
12
12
|
|
|
13
13
|
const TOC_HEADER_TAG = "doc-heading";
|
|
14
|
+
const RNB_BY_TAB = "docs-tab";
|
|
14
15
|
const HIGHLIGHTABLE_SELECTOR = [
|
|
15
16
|
"p",
|
|
16
17
|
"h1",
|
|
@@ -101,6 +102,62 @@ export default class ContentLayout extends LightningElement {
|
|
|
101
102
|
return this.contentLoaded && typeof Sprig !== "undefined";
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
get showTabBasedRNB() {
|
|
106
|
+
const tabPanelListItem: any = this.getTabPanelList();
|
|
107
|
+
return tabPanelListItem?.id === RNB_BY_TAB ? true : false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
onTabChanged = () => {
|
|
111
|
+
this.updateRNB();
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
private getTabPanelList() {
|
|
115
|
+
return document.querySelector("dx-tab-panel-list");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
updateRNB = () => {
|
|
119
|
+
const headingElements = this.getHeadingElements();
|
|
120
|
+
headingElements.forEach((headingElement: any) => {
|
|
121
|
+
// Sometimes elements hash and header is not being set when slot content is wrapped with div
|
|
122
|
+
headingElement.hash = headingElement.attributes.hash?.nodeValue;
|
|
123
|
+
headingElement.header = headingElement.attributes.header?.nodeValue;
|
|
124
|
+
});
|
|
125
|
+
this.updateTocItems(headingElements);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
private getHeadingElements() {
|
|
129
|
+
let headingElements = document.querySelectorAll(TOC_HEADER_TAG);
|
|
130
|
+
if (this.showTabBasedRNB) {
|
|
131
|
+
const tabPanelListItem: any = this.getTabPanelList();
|
|
132
|
+
const tabPanels =
|
|
133
|
+
tabPanelListItem?.querySelectorAll("dx-tab-panel");
|
|
134
|
+
for (const tabPanelItem of tabPanels) {
|
|
135
|
+
if (tabPanelItem.active) {
|
|
136
|
+
headingElements =
|
|
137
|
+
tabPanelItem.querySelectorAll(TOC_HEADER_TAG);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return headingElements;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private updateURL() {
|
|
146
|
+
const tabs = this.getAllTabs();
|
|
147
|
+
const selectedTabId = this.getSelectedTabId();
|
|
148
|
+
tabs.forEach((tab: any) => {
|
|
149
|
+
if (tab.getAttribute("aria-selected") === "true") {
|
|
150
|
+
const tabID = tab.getAttribute("aria-label");
|
|
151
|
+
const url = new URL(window.location.href);
|
|
152
|
+
if (selectedTabId !== tabID) {
|
|
153
|
+
url.searchParams.set("type", tabID);
|
|
154
|
+
url.hash = "";
|
|
155
|
+
window.history.pushState({}, "", url.toString());
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
104
161
|
private searchSyncer = new SearchSyncer({
|
|
105
162
|
callbacks: {
|
|
106
163
|
onSearchChange: (nextSearchString: string): void => {
|
|
@@ -148,6 +205,46 @@ export default class ContentLayout extends LightningElement {
|
|
|
148
205
|
);
|
|
149
206
|
this.searchSyncer.init();
|
|
150
207
|
}
|
|
208
|
+
|
|
209
|
+
if (this.showTabBasedRNB) {
|
|
210
|
+
window.addEventListener("tabchanged", this.onTabChanged);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private getSelectedTabId() {
|
|
215
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
216
|
+
const selectedTabId = urlParams.get("type");
|
|
217
|
+
return selectedTabId;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private restoreTabSelection() {
|
|
221
|
+
const selectedTabId = this.getSelectedTabId();
|
|
222
|
+
if (selectedTabId) {
|
|
223
|
+
this.selectTabById(selectedTabId);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private getAllTabs(): any[] {
|
|
228
|
+
const tabPanelListItem: any = this.getTabPanelList();
|
|
229
|
+
if (tabPanelListItem?.shadowRoot) {
|
|
230
|
+
return Array.from(
|
|
231
|
+
tabPanelListItem.shadowRoot.querySelectorAll(
|
|
232
|
+
"dx-tab-panel-item"
|
|
233
|
+
)
|
|
234
|
+
).map((tabPanelItem: any) =>
|
|
235
|
+
tabPanelItem.shadowRoot.querySelector("button")
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
return [];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private selectTabById(tabId: string) {
|
|
242
|
+
const tabs = this.getAllTabs();
|
|
243
|
+
tabs.forEach((tab: any) => {
|
|
244
|
+
if (tab.getAttribute("aria-label") === tabId) {
|
|
245
|
+
tab.click();
|
|
246
|
+
}
|
|
247
|
+
});
|
|
151
248
|
}
|
|
152
249
|
|
|
153
250
|
renderedCallback(): void {
|
|
@@ -167,6 +264,9 @@ export default class ContentLayout extends LightningElement {
|
|
|
167
264
|
|
|
168
265
|
if (!this.hasRendered) {
|
|
169
266
|
this.hasRendered = true;
|
|
267
|
+
if (this.showTabBasedRNB) {
|
|
268
|
+
this.restoreTabSelection();
|
|
269
|
+
}
|
|
170
270
|
this.restoreScroll();
|
|
171
271
|
}
|
|
172
272
|
}
|
|
@@ -179,6 +279,7 @@ export default class ContentLayout extends LightningElement {
|
|
|
179
279
|
);
|
|
180
280
|
window.removeEventListener("scroll", this.adjustNavPosition);
|
|
181
281
|
window.removeEventListener("resize", this.adjustNavPosition);
|
|
282
|
+
window.removeEventListener("tabchanged", this.onTabChanged);
|
|
182
283
|
this.searchSyncer.dispose();
|
|
183
284
|
this.clearRenderObserverTimer();
|
|
184
285
|
|
|
@@ -324,7 +425,13 @@ export default class ContentLayout extends LightningElement {
|
|
|
324
425
|
);
|
|
325
426
|
|
|
326
427
|
// Note: We are doing document.querySelectorAll as a quick fix as we are not getting heading elements reference this.querySelectorAll
|
|
327
|
-
const headingElements =
|
|
428
|
+
const headingElements = this.getHeadingElements();
|
|
429
|
+
|
|
430
|
+
// We only need to update URL in case of /docs and ignore if tabs are used anywhere else in DSC
|
|
431
|
+
if (this.showTabBasedRNB) {
|
|
432
|
+
this.updateURL();
|
|
433
|
+
}
|
|
434
|
+
|
|
328
435
|
for (const headingElement of headingElements as any) {
|
|
329
436
|
// Add headingElements to intersectionObserver for highlighting respective RNB item when user scroll
|
|
330
437
|
const id = headingElement.getAttribute("id")!;
|
|
@@ -340,49 +447,34 @@ export default class ContentLayout extends LightningElement {
|
|
|
340
447
|
}
|
|
341
448
|
};
|
|
342
449
|
|
|
343
|
-
onSlotChange(
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
).assignedElements();
|
|
347
|
-
|
|
348
|
-
if (slotElements.length) {
|
|
349
|
-
this.contentLoaded = true;
|
|
350
|
-
const slotContentElement = slotElements[0];
|
|
351
|
-
const headingElements =
|
|
352
|
-
slotContentElement.ownerDocument?.getElementsByTagName(
|
|
353
|
-
TOC_HEADER_TAG
|
|
354
|
-
);
|
|
355
|
-
|
|
356
|
-
for (const headingElement of headingElements as any) {
|
|
357
|
-
// Sometimes elements hash and header is not being set when slot content is wrapped with div
|
|
358
|
-
headingElement.hash = headingElement.attributes.hash?.nodeValue;
|
|
359
|
-
headingElement.header =
|
|
360
|
-
headingElement.attributes.header?.nodeValue;
|
|
361
|
-
}
|
|
450
|
+
onSlotChange(): void {
|
|
451
|
+
this.updateRNB();
|
|
452
|
+
}
|
|
362
453
|
|
|
363
|
-
|
|
454
|
+
// eslint-disable-next-line no-undef
|
|
455
|
+
private updateTocItems(headingElements: NodeListOf<Element>): void {
|
|
456
|
+
const tocOptions = [];
|
|
364
457
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
458
|
+
for (const headingElement of headingElements as any) {
|
|
459
|
+
headingElement.id = headingElement.hash;
|
|
460
|
+
|
|
461
|
+
// Update tocOptions from anchorTags only for H2, consider default as 2 as per component
|
|
462
|
+
const headingAriaLevel =
|
|
463
|
+
headingElement.attributes["aria-level"]?.nodeValue || "2";
|
|
464
|
+
const isH2 = headingAriaLevel === "2";
|
|
465
|
+
|
|
466
|
+
if (isH2) {
|
|
467
|
+
const tocItem = {
|
|
468
|
+
anchor: `#${headingElement.hash}`,
|
|
469
|
+
id: headingElement.id,
|
|
470
|
+
label: headingElement.header
|
|
471
|
+
};
|
|
472
|
+
tocOptions.push(tocItem);
|
|
473
|
+
this.tocOptionIdsSet.add(headingElement.id);
|
|
382
474
|
}
|
|
383
|
-
|
|
384
|
-
this._tocOptions = tocOptions;
|
|
385
475
|
}
|
|
476
|
+
|
|
477
|
+
this._tocOptions = tocOptions;
|
|
386
478
|
}
|
|
387
479
|
|
|
388
480
|
private disconnectObserver(): void {
|