@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/docs-components",
3
- "version": "1.3.327-do-dont-1",
3
+ "version": "1.3.327-rnbtab-alpha",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -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 = document.querySelectorAll(TOC_HEADER_TAG);
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(event: Event): void {
344
- const slotElements = (
345
- event.target as HTMLSlotElement
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
- const tocOptions = [];
454
+ // eslint-disable-next-line no-undef
455
+ private updateTocItems(headingElements: NodeListOf<Element>): void {
456
+ const tocOptions = [];
364
457
 
365
- for (const headingElement of headingElements as any) {
366
- headingElement.id = headingElement.hash;
367
-
368
- // Update tocOptions from anchorTags only for H2, consider default as 2 as per component
369
- const headingAriaLevel =
370
- headingElement.attributes["aria-level"]?.nodeValue || "2";
371
- const isH2 = headingAriaLevel === "2";
372
-
373
- if (isH2) {
374
- const tocItem = {
375
- anchor: `#${headingElement.hash}`,
376
- id: headingElement.id,
377
- label: headingElement.header
378
- };
379
- tocOptions.push(tocItem);
380
- this.tocOptionIdsSet.add(headingElement.id);
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 {
@@ -20,7 +20,7 @@
20
20
  </template>
21
21
  </div>
22
22
  <div class="do-dont-image-container">
23
- <img class="doc-do-dont-img" src={imgSrc} alt={caption} />
23
+ <img class="doc-do-dont-img" src={src} alt={caption} />
24
24
  </div>
25
25
  <div class="dx-text-body-4">{caption}</div>
26
26
  </div>
@@ -3,7 +3,7 @@ import { normalizeBoolean } from "dxUtils/normalizers";
3
3
 
4
4
  export default class DoDont extends LightningElement {
5
5
  @api caption: string = "";
6
- @api imgSrc!: string;
6
+ @api src!: string;
7
7
  _isDo: boolean = false;
8
8
 
9
9
  @api