@salesforcedevs/docs-components 1.17.11 → 1.17.12

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.17.11",
3
+ "version": "1.17.12",
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": "788524c2a30a036b5c06c95ecdb37b46ee522ea5"
28
+ "gitHead": "70531724fc102e034c3240e369b488fe8df896fc"
29
29
  }
@@ -2,44 +2,111 @@ import ContentLayout from "doc/contentLayout";
2
2
 
3
3
  const TOC_HEADER_TAG = "doc-heading";
4
4
  const RNB_BY_TAB = "docs-tab";
5
- const SPECIFICATION_TAB_TITLE = "Specification";
5
+ const SPECIFICATION_TAG = "doc-specification-content";
6
6
  export const OBSERVER_ATTACH_WAIT_TIME = 500;
7
7
 
8
8
  export default class LwcContentLayout extends ContentLayout {
9
9
  private rnbByTab: boolean = false;
10
10
 
11
+ // DOM element caches to avoid repeated queries
12
+ private tabPanelListCache: any = null;
13
+ private hasSpecContentCache: boolean | null = null;
14
+ private allTabsCache: any[] | null = null;
15
+ private mainSlotCache: any = null;
16
+
11
17
  private setRNBByTab() {
12
- const tabPanelListItem: any = this.getTabPanelList();
13
- this.rnbByTab = tabPanelListItem?.id === RNB_BY_TAB ? true : false;
18
+ const tabPanelListItem = this.getTabPanelList();
19
+ this.rnbByTab = tabPanelListItem?.id === RNB_BY_TAB;
14
20
  }
15
21
 
16
22
  get showTabBasedRNB() {
17
23
  return this.rnbByTab;
18
24
  }
19
25
 
26
+ /**
27
+ * Check if the main slot contains doc-specification-content
28
+ * Uses caching to avoid repeated DOM queries
29
+ */
30
+ private hasSpecificationContent(): boolean {
31
+ if (this.hasSpecContentCache !== null) {
32
+ return this.hasSpecContentCache;
33
+ }
34
+
35
+ const mainSlot = this.getMainSlot();
36
+ if (mainSlot) {
37
+ const assignedElements = (mainSlot as any).assignedElements();
38
+
39
+ for (const element of assignedElements) {
40
+ if (
41
+ element.tagName === SPECIFICATION_TAG ||
42
+ element.querySelector(SPECIFICATION_TAG) ||
43
+ element.shadowRoot?.querySelector(SPECIFICATION_TAG)
44
+ ) {
45
+ return (this.hasSpecContentCache = true);
46
+ }
47
+ }
48
+ }
49
+ return (this.hasSpecContentCache = false);
50
+ }
51
+
52
+ /**
53
+ * Clear all caches when content changes
54
+ */
55
+ private clearAllCaches(): void {
56
+ this.hasSpecContentCache = null;
57
+ this.tabPanelListCache = null;
58
+ this.allTabsCache = null;
59
+ this.mainSlotCache = null;
60
+ }
61
+
62
+ /**
63
+ * Get the main slot element with caching
64
+ */
65
+ private getMainSlot(): any {
66
+ if (!this.mainSlotCache) {
67
+ this.mainSlotCache =
68
+ this.template.querySelector("slot:not([name])");
69
+ }
70
+ return this.mainSlotCache;
71
+ }
72
+
73
+ /**
74
+ * Get tab panel list with caching
75
+ */
76
+ private getTabPanelList(): any {
77
+ if (!this.tabPanelListCache) {
78
+ // eslint-disable-next-line @lwc/lwc/no-document-query
79
+ this.tabPanelListCache =
80
+ document.querySelector("dx-tab-panel-list");
81
+ }
82
+ return this.tabPanelListCache;
83
+ }
84
+
20
85
  onRNBClick = (event: CustomEvent) => {
21
86
  event.stopPropagation();
22
- const currentTab = this.getSelectedTabId();
23
- if (currentTab === SPECIFICATION_TAB_TITLE) {
87
+ if (this.hasSpecificationContent()) {
24
88
  this.didScrollToSelectedHash = false;
25
89
  }
26
90
  };
27
91
 
28
92
  onTabChanged = () => {
29
93
  this.updateRNB();
30
- };
31
94
 
32
- private getTabPanelList() {
33
- // eslint-disable-next-line @lwc/lwc/no-document-query
34
- return document.querySelector("dx-tab-panel-list");
35
- }
95
+ const { hash } = window.location;
96
+ if (this.hasSpecificationContent() && hash) {
97
+ this.didScrollToSelectedHash = false;
98
+
99
+ requestAnimationFrame(() => this.updateHeadingForRNB());
100
+ }
101
+ };
36
102
 
37
103
  protected getHeadingElements() {
38
104
  let headingElements = super.getHeadingElements();
39
105
  if (this.showTabBasedRNB) {
40
- const tabPanelListItem: any = this.getTabPanelList();
106
+ const tabPanelListItem = this.getTabPanelList();
41
107
  const tabPanels =
42
108
  tabPanelListItem?.querySelectorAll("dx-tab-panel");
109
+
43
110
  for (const tabPanelItem of tabPanels) {
44
111
  if (tabPanelItem.active) {
45
112
  // This is needed for Specification tab content
@@ -65,6 +132,7 @@ export default class LwcContentLayout extends ContentLayout {
65
132
  private updateURL() {
66
133
  const tabs = this.getAllTabs();
67
134
  const selectedTabId = this.getSelectedTabId();
135
+
68
136
  tabs.forEach((tab: any) => {
69
137
  if (tab.getAttribute("aria-selected") === "true") {
70
138
  const tabID = tab.getAttribute("aria-label");
@@ -101,22 +169,38 @@ export default class LwcContentLayout extends ContentLayout {
101
169
  const selectedTabId = this.getSelectedTabId();
102
170
  if (selectedTabId) {
103
171
  this.selectTabById(selectedTabId);
172
+
173
+ // If there's a hash and we have specification content,
174
+ // we need to wait for the content to load before scrolling
175
+ const { hash } = window.location;
176
+ if (this.hasSpecificationContent() && hash) {
177
+ // Reset the scroll flag to allow scrolling once content is loaded
178
+ this.didScrollToSelectedHash = false;
179
+ }
104
180
  }
105
181
  });
106
182
  }
107
183
 
108
184
  private getAllTabs(): any[] {
109
- const tabPanelListItem: any = this.getTabPanelList();
185
+ // Return cached result if available
186
+ if (this.allTabsCache) {
187
+ return this.allTabsCache;
188
+ }
189
+
190
+ const tabPanelListItem = this.getTabPanelList();
110
191
  if (tabPanelListItem?.shadowRoot) {
111
- return Array.from(
192
+ this.allTabsCache = Array.from(
112
193
  tabPanelListItem.shadowRoot.querySelectorAll(
113
194
  "dx-tab-panel-item"
114
195
  )
115
196
  ).map((tabPanelItem: any) =>
116
197
  tabPanelItem.shadowRoot.querySelector("button")
117
198
  );
199
+ } else {
200
+ this.allTabsCache = [];
118
201
  }
119
- return [];
202
+
203
+ return this.allTabsCache;
120
204
  }
121
205
 
122
206
  private selectTabById(tabId: string) {
@@ -158,8 +242,12 @@ export default class LwcContentLayout extends ContentLayout {
158
242
  }
159
243
  }
160
244
 
245
+ onSlotChange(): void {
246
+ this.clearAllCaches();
247
+ super.onSlotChange();
248
+ }
249
+
161
250
  updateHeadingForRNB(): void {
162
- // We only need to update URL in case of /docs and ignore if tabs are used anywhere else in DSC
163
251
  if (this.showTabBasedRNB) {
164
252
  this.updateURL();
165
253
  }
@@ -73,9 +73,7 @@
73
73
  <template lwc:if={method.firstArgument}>
74
74
  <tr key={method.name}>
75
75
  <td rowspan={method.arguments.length}>
76
- <span class="code">
77
- {method.nameInKebabCase}
78
- </span>
76
+ <span class="code">{method.name}</span>
79
77
  </td>
80
78
  <td rowspan={method.arguments.length}>
81
79
  {method.description}
@@ -100,9 +98,7 @@
100
98
  <template lwc:else>
101
99
  <tr key={method.name}>
102
100
  <td>
103
- <span class="code">
104
- {method.nameInKebabCase}
105
- </span>
101
+ <span class="code">{method.name}</span>
106
102
  </td>
107
103
  <td>{method.description}</td>
108
104
  <td colspan="3"></td>