@salesforcedevs/docs-components 1.3.327 → 1.3.335

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",
3
+ "version": "1.3.335",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -24,5 +24,5 @@
24
24
  "@types/lodash.orderby": "^4.6.7",
25
25
  "@types/lodash.uniqby": "^4.7.7"
26
26
  },
27
- "gitHead": "f684f389715290826e36a66d35c42bf5eb3f04a4"
27
+ "gitHead": "2862c96ace8525a40000901f23ef6ede22b269e9"
28
28
  }
@@ -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",
@@ -96,11 +97,72 @@ export default class ContentLayout extends LightningElement {
96
97
  private hasRendered: boolean = false;
97
98
  private contentLoaded: boolean = false;
98
99
  private sidebarOpen: boolean = false;
100
+ private rnbByTab: boolean = false;
99
101
 
100
102
  get shouldDisplayFeedback() {
101
103
  return this.contentLoaded && typeof Sprig !== "undefined";
102
104
  }
103
105
 
106
+ private setRNBByTab() {
107
+ const tabPanelListItem: any = this.getTabPanelList();
108
+ this.rnbByTab = tabPanelListItem?.id === RNB_BY_TAB ? true : false;
109
+ }
110
+
111
+ get showTabBasedRNB() {
112
+ return this.rnbByTab;
113
+ }
114
+
115
+ onTabChanged = () => {
116
+ this.updateRNB();
117
+ };
118
+
119
+ private getTabPanelList() {
120
+ return document.querySelector("dx-tab-panel-list");
121
+ }
122
+
123
+ updateRNB = () => {
124
+ const headingElements = this.getHeadingElements();
125
+ headingElements.forEach((headingElement: any) => {
126
+ // Sometimes elements hash and header is not being set when slot content is wrapped with div
127
+ headingElement.hash = headingElement.attributes.hash?.nodeValue;
128
+ headingElement.header = headingElement.attributes.header?.nodeValue;
129
+ });
130
+ this.updateTocItems(headingElements);
131
+ };
132
+
133
+ private getHeadingElements() {
134
+ let headingElements = document.querySelectorAll(TOC_HEADER_TAG);
135
+ if (this.showTabBasedRNB) {
136
+ const tabPanelListItem: any = this.getTabPanelList();
137
+ const tabPanels =
138
+ tabPanelListItem?.querySelectorAll("dx-tab-panel");
139
+ for (const tabPanelItem of tabPanels) {
140
+ if (tabPanelItem.active) {
141
+ headingElements =
142
+ tabPanelItem.querySelectorAll(TOC_HEADER_TAG);
143
+ break;
144
+ }
145
+ }
146
+ }
147
+ return headingElements;
148
+ }
149
+
150
+ private updateURL() {
151
+ const tabs = this.getAllTabs();
152
+ const selectedTabId = this.getSelectedTabId();
153
+ tabs.forEach((tab: any) => {
154
+ if (tab.getAttribute("aria-selected") === "true") {
155
+ const tabID = tab.getAttribute("aria-label");
156
+ const url = new URL(window.location.href);
157
+ if (selectedTabId !== tabID) {
158
+ url.searchParams.set("type", tabID);
159
+ url.hash = "";
160
+ window.history.pushState({}, "", url.toString());
161
+ }
162
+ }
163
+ });
164
+ }
165
+
104
166
  private searchSyncer = new SearchSyncer({
105
167
  callbacks: {
106
168
  onSearchChange: (nextSearchString: string): void => {
@@ -150,6 +212,44 @@ export default class ContentLayout extends LightningElement {
150
212
  }
151
213
  }
152
214
 
215
+ private getSelectedTabId() {
216
+ const urlParams = new URLSearchParams(window.location.search);
217
+ const selectedTabId = urlParams.get("type");
218
+ return selectedTabId;
219
+ }
220
+
221
+ private restoreTabSelection() {
222
+ requestAnimationFrame(() => {
223
+ const selectedTabId = this.getSelectedTabId();
224
+ if (selectedTabId) {
225
+ this.selectTabById(selectedTabId);
226
+ }
227
+ });
228
+ }
229
+
230
+ private getAllTabs(): any[] {
231
+ const tabPanelListItem: any = this.getTabPanelList();
232
+ if (tabPanelListItem?.shadowRoot) {
233
+ return Array.from(
234
+ tabPanelListItem.shadowRoot.querySelectorAll(
235
+ "dx-tab-panel-item"
236
+ )
237
+ ).map((tabPanelItem: any) =>
238
+ tabPanelItem.shadowRoot.querySelector("button")
239
+ );
240
+ }
241
+ return [];
242
+ }
243
+
244
+ private selectTabById(tabId: string) {
245
+ const tabs = this.getAllTabs();
246
+ tabs.forEach((tab: any) => {
247
+ if (tab.getAttribute("aria-label") === tabId) {
248
+ tab.click();
249
+ }
250
+ });
251
+ }
252
+
153
253
  renderedCallback(): void {
154
254
  /**
155
255
  * Note: We are adding timeout because chrome is optimizing and not triggering recent renderedCallback though elements reference is changed
@@ -167,6 +267,11 @@ export default class ContentLayout extends LightningElement {
167
267
 
168
268
  if (!this.hasRendered) {
169
269
  this.hasRendered = true;
270
+ this.setRNBByTab();
271
+ if (this.showTabBasedRNB) {
272
+ window.addEventListener("tabchanged", this.onTabChanged);
273
+ this.restoreTabSelection();
274
+ }
170
275
  this.restoreScroll();
171
276
  }
172
277
  }
@@ -179,6 +284,7 @@ export default class ContentLayout extends LightningElement {
179
284
  );
180
285
  window.removeEventListener("scroll", this.adjustNavPosition);
181
286
  window.removeEventListener("resize", this.adjustNavPosition);
287
+ window.removeEventListener("tabchanged", this.onTabChanged);
182
288
  this.searchSyncer.dispose();
183
289
  this.clearRenderObserverTimer();
184
290
 
@@ -324,7 +430,13 @@ export default class ContentLayout extends LightningElement {
324
430
  );
325
431
 
326
432
  // 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);
433
+ const headingElements = this.getHeadingElements();
434
+
435
+ // We only need to update URL in case of /docs and ignore if tabs are used anywhere else in DSC
436
+ if (this.showTabBasedRNB) {
437
+ this.updateURL();
438
+ }
439
+
328
440
  for (const headingElement of headingElements as any) {
329
441
  // Add headingElements to intersectionObserver for highlighting respective RNB item when user scroll
330
442
  const id = headingElement.getAttribute("id")!;
@@ -340,49 +452,34 @@ export default class ContentLayout extends LightningElement {
340
452
  }
341
453
  };
342
454
 
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
- }
455
+ onSlotChange(): void {
456
+ this.updateRNB();
457
+ }
362
458
 
363
- const tocOptions = [];
459
+ // eslint-disable-next-line no-undef
460
+ private updateTocItems(headingElements: NodeListOf<Element>): void {
461
+ const tocOptions = [];
364
462
 
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
- }
463
+ for (const headingElement of headingElements as any) {
464
+ headingElement.id = headingElement.hash;
465
+
466
+ // Update tocOptions from anchorTags only for H2, consider default as 2 as per component
467
+ const headingAriaLevel =
468
+ headingElement.attributes["aria-level"]?.nodeValue || "2";
469
+ const isH2 = headingAriaLevel === "2";
470
+
471
+ if (isH2) {
472
+ const tocItem = {
473
+ anchor: `#${headingElement.hash}`,
474
+ id: headingElement.id,
475
+ label: headingElement.header
476
+ };
477
+ tocOptions.push(tocItem);
478
+ this.tocOptionIdsSet.add(headingElement.id);
382
479
  }
383
-
384
- this._tocOptions = tocOptions;
385
480
  }
481
+
482
+ this._tocOptions = tocOptions;
386
483
  }
387
484
 
388
485
  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={src} alt={caption} />
23
+ <img class="doc-do-dont-img" src={imgSrc} 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 src!: string;
6
+ @api imgSrc!: string;
7
7
  _isDo: boolean = false;
8
8
 
9
9
  @api