@salesforcedevs/docs-components
Advanced tools
Comparing version 1.3.324 to 1.3.325-rnbtab-alpha
{ | ||
"name": "@salesforcedevs/docs-components", | ||
"version": "1.3.324", | ||
"version": "1.3.325-rnbtab-alpha", | ||
"description": "Docs Lightning web components for DSC", | ||
@@ -27,3 +27,3 @@ "license": "MIT", | ||
}, | ||
"gitHead": "f005d7f0cbb1ce8f67f11d7267cfeb893d2c031a" | ||
"gitHead": "4629fdd9ca18a13480044ad43515b91945d16aad" | ||
} |
@@ -14,2 +14,3 @@ /* eslint-disable @lwc/lwc/no-document-query */ | ||
const TOC_HEADER_TAG = "doc-heading"; | ||
const RNB_BY_TAB = "docs-tab"; | ||
const HIGHLIGHTABLE_SELECTOR = [ | ||
@@ -45,2 +46,3 @@ "p", | ||
@api bailLabel!: string; | ||
@track initialIndex: number = 0; | ||
@@ -106,2 +108,109 @@ // This is needed for now to prevent failing snapshot tests due to links in the footer | ||
get showTabBasedRNB() { | ||
const tabPanelListItem: any = this.selectTabElement(); | ||
return tabPanelListItem?.id === RNB_BY_TAB ? true : false; | ||
} | ||
onTabChanged = () => { | ||
this.updateRNB(); | ||
}; | ||
private selectTabElement() { | ||
return document.querySelector("dx-tab-panel-list"); | ||
} | ||
updateRNB = () => { | ||
const headingElements = this.getHeadingElements(); | ||
headingElements.forEach((headingElement: any) => { | ||
headingElement.hash = headingElement.attributes.hash?.nodeValue; | ||
}); | ||
this.updateTocItems(headingElements); | ||
}; | ||
private getHeadingElements() { | ||
let headingElements = document.querySelectorAll(TOC_HEADER_TAG); | ||
if (this.showTabBasedRNB) { | ||
const tabPanelListItem: any = this.selectTabElement(); | ||
// for (const tabPanelListItem of tabPanelListItems) { | ||
if (tabPanelListItem.id === RNB_BY_TAB) { | ||
const tabPanels = | ||
tabPanelListItem.querySelectorAll("dx-tab-panel"); | ||
for (const tabPanelItem of tabPanels) { | ||
if (tabPanelItem.active) { | ||
headingElements = | ||
tabPanelItem.querySelectorAll(TOC_HEADER_TAG); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
return headingElements; | ||
} | ||
private updateURL() { | ||
const tabPanelListItem: any = this.selectTabElement(); | ||
if (tabPanelListItem?.id === RNB_BY_TAB) { | ||
const tabPanelItems: any = | ||
tabPanelListItem?.shadowRoot.querySelectorAll( | ||
"dx-tab-panel-item" | ||
); | ||
if (tabPanelItems) { | ||
for (const tabPanelItem of tabPanelItems as any) { | ||
const tab = tabPanelItem.shadowRoot.querySelector("button"); | ||
const url = new URL(window.location.href); | ||
const previousTabID = url.searchParams.get("type"); | ||
const tabID = tab?.getAttribute("aria-label"); | ||
if ( | ||
tab?.getAttribute("aria-selected") === "true" && | ||
previousTabID !== tabID | ||
) { | ||
url.searchParams.set("type", tabID); | ||
url.hash = ""; | ||
window.history.pushState({}, "", url.toString()); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
private tabOnPageLoad() { | ||
const url = new URL(window.location.href); | ||
const previousTabID = url.searchParams.get("type"); | ||
if (!previousTabID) { | ||
this.updateURL(); | ||
} else { | ||
const tabPanelListItem: any = this.selectTabElement(); | ||
const tabPanelItems: any = | ||
tabPanelListItem?.shadowRoot.querySelectorAll( | ||
"dx-tab-panel-item" | ||
); | ||
const tabPanels = tabPanelListItem.querySelectorAll("dx-tab-panel"); | ||
if (tabPanelItems) { | ||
let tabIndex = 0; | ||
for (const tabPanelItem of tabPanelItems as any) { | ||
const tab = tabPanelItem.shadowRoot.querySelector("button"); | ||
const activeTab = | ||
tabPanels[tabIndex]?.shadowRoot.querySelector( | ||
".tabpanel" | ||
); | ||
if (tab?.getAttribute("aria-label") === previousTabID) { | ||
if (activeTab) { | ||
activeTab.classList.add("tabpanel-active"); | ||
} | ||
tab.active = true; | ||
this.initialIndex = tabIndex; | ||
} else { | ||
if (activeTab) { | ||
activeTab.classList.remove("tabpanel-active"); | ||
} | ||
tab.active = false; | ||
} | ||
tabIndex++; | ||
} | ||
} | ||
} | ||
} | ||
private searchSyncer = new SearchSyncer({ | ||
@@ -154,2 +263,7 @@ callbacks: { | ||
} | ||
if (this.showTabBasedRNB) { | ||
window.addEventListener("tabchanged", this.onTabChanged); | ||
this.tabOnPageLoad(); | ||
} | ||
} | ||
@@ -222,6 +336,12 @@ | ||
const docPhaseEl = ( | ||
let docPhaseEl = ( | ||
this.template.querySelector("[name=doc-phase]")! as any | ||
).assignedElements()[0] as HTMLSlotElement; | ||
if (!docPhaseEl) { | ||
docPhaseEl = ( | ||
this.template.querySelector("[name=version-banner]")! as any | ||
).assignedElements()[0] as HTMLSlotElement; | ||
} | ||
if (!sidebarEl || !globalNavEl || !contextNavEl || !docHeaderEl) { | ||
@@ -239,2 +359,10 @@ console.warn("One or more required elements are missing."); | ||
const docHeaderHeight = docHeaderEl.getBoundingClientRect().height; | ||
const totalHeaderHeight = globalNavHeight + docHeaderHeight; | ||
// Selecting the doc section heading and RNB here. | ||
const docHeadingEls = Array.from( | ||
document.querySelectorAll("doc-heading") | ||
); | ||
const rightNavBarEl = this.template.querySelector(".right-nav-bar"); | ||
sidebarEl.style.setProperty( | ||
@@ -250,2 +378,23 @@ "--dx-c-content-sidebar-sticky-top", | ||
// Adjusting the doc section heading on scroll. | ||
docHeadingEls.forEach((docHeadingEl) => { | ||
(docHeadingEl as any).style.scrollMarginTop = docPhaseEl | ||
? `${ | ||
totalHeaderHeight + | ||
docPhaseEl.getBoundingClientRect().height + | ||
40 | ||
}px` | ||
: `${totalHeaderHeight + 40}px`; | ||
}); | ||
// Adjusting the right nav bar on scroll. | ||
if (rightNavBarEl) { | ||
rightNavBarEl.style.top = docPhaseEl | ||
? `${ | ||
totalHeaderHeight + | ||
docPhaseEl.getBoundingClientRect().height | ||
}px` | ||
: `${totalHeaderHeight}px`; | ||
} | ||
// If doc phase element exists, we need to account for its sticky position. Mobile should include the sidebar height (since it becomes sticky aswell). | ||
@@ -263,26 +412,2 @@ if (docPhaseEl) { | ||
); | ||
// Adjust scroll margin for doc headings when doc phase is present | ||
const docHeadingEls = Array.from( | ||
document.querySelectorAll("doc-heading") | ||
); | ||
docHeadingEls.forEach((docHeadingEl) => { | ||
(docHeadingEl as any).style.scrollMarginTop = `${ | ||
globalNavHeight + | ||
docHeaderHeight + | ||
docPhaseEl.getBoundingClientRect().height | ||
}px`; | ||
}); | ||
// Adjust right nav bar position when doc phase is present | ||
const rightNavBarEl = | ||
this.template.querySelector(".right-nav-bar"); | ||
if (rightNavBarEl) { | ||
rightNavBarEl.style.top = `${ | ||
globalNavHeight + | ||
docHeaderHeight + | ||
docPhaseEl.getBoundingClientRect().height | ||
}px`; | ||
} | ||
} | ||
@@ -324,3 +449,4 @@ }); | ||
// Note: We are doing document.querySelectorAll as a quick fix as we are not getting heading elements reference this.querySelectorAll | ||
const headingElements = document.querySelectorAll(TOC_HEADER_TAG); | ||
const headingElements = this.getHeadingElements(); | ||
this.updateURL(); | ||
for (const headingElement of headingElements as any) { | ||
@@ -341,45 +467,39 @@ // Add headingElements to intersectionObserver for highlighting respective RNB item when user scroll | ||
onSlotChange(event: Event): void { | ||
const slotElements = ( | ||
event.target as HTMLSlotElement | ||
).assignedElements(); | ||
onSlotChange(e): void { | ||
const slot = e.target; | ||
const child = slot.assignedElements(); | ||
const tabComponent = child.find( | ||
(element: any) => | ||
element.tagName.toLowerCase() === "dx-tab-panel-list" | ||
); | ||
if (tabComponent) { | ||
tabComponent.initialIndex = this.initialIndex; // Set the index value on the child component | ||
} | ||
this.updateRNB(); | ||
} | ||
if (slotElements.length) { | ||
this.contentLoaded = true; | ||
const slotContentElement = slotElements[0]; | ||
const headingElements = | ||
slotContentElement.ownerDocument?.getElementsByTagName( | ||
TOC_HEADER_TAG | ||
); | ||
// eslint-disable-next-line no-undef | ||
private updateTocItems(headingElements: NodeListOf<Element>): void { | ||
const tocOptions = []; | ||
for (const headingElement of headingElements as any) { | ||
// Sometimes elements hash and header is not being set when slot content is wrapped with div | ||
headingElement.hash = headingElement.attributes.hash?.nodeValue; | ||
headingElement.header = | ||
headingElement.attributes.header?.nodeValue; | ||
} | ||
for (const headingElement of headingElements as any) { | ||
headingElement.id = headingElement.hash; | ||
const tocOptions = []; | ||
// Update tocOptions from anchorTags only for H2, consider default as 2 as per component | ||
const headingAriaLevel = | ||
headingElement.attributes["aria-level"]?.nodeValue || "2"; | ||
const isH2 = headingAriaLevel === "2"; | ||
for (const headingElement of headingElements as any) { | ||
headingElement.id = headingElement.hash; | ||
// Update tocOptions from anchorTags only for H2, consider default as 2 as per component | ||
const headingAriaLevel = | ||
headingElement.attributes["aria-level"]?.nodeValue || "2"; | ||
const isH2 = headingAriaLevel === "2"; | ||
if (isH2) { | ||
const tocItem = { | ||
anchor: `#${headingElement.hash}`, | ||
id: headingElement.id, | ||
label: headingElement.header | ||
}; | ||
tocOptions.push(tocItem); | ||
this.tocOptionIdsSet.add(headingElement.id); | ||
} | ||
if (isH2) { | ||
const tocItem = { | ||
anchor: `#${headingElement.hash}`, | ||
id: headingElement.id, | ||
label: headingElement.header | ||
}; | ||
tocOptions.push(tocItem); | ||
this.tocOptionIdsSet.add(headingElement.id); | ||
} | ||
} | ||
this._tocOptions = tocOptions; | ||
} | ||
this._tocOptions = tocOptions; | ||
} | ||
@@ -386,0 +506,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
259047
0
6645
75
2