Skip to content

Commit 0fc3fe6

Browse files
authored
Filtering by language and chain fams (#3153)
* filtering by language and chain fams * default CCIP sidebar to EVM on initial load
1 parent f7006f5 commit 0fc3fe6

File tree

3 files changed

+89
-18
lines changed

3 files changed

+89
-18
lines changed

src/components/DocsNavigation/DocsNavigationMobile/SubProductContent.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React, { useEffect, useRef } from "react"
22
import { useStore } from "@nanostores/react"
33
import { selectedLanguage } from "~/lib/languageStore.js"
44
import { selectedChainType } from "~/stores/chainType.js"
5-
import { applyChainTypeFilter } from "~/utils/chainType.js"
65
import { BackArrowIcon } from "./BackArrowIcon.js"
76
import { Page } from "../../Header/Nav/config.js"
87
import styles from "./subProductContent.module.css"
@@ -84,9 +83,25 @@ export const SubProductContent = ({ subProducts, onSubproductClick, currentPath
8483
const currentLang = useStore(selectedLanguage)
8584
const currentChain = useStore(selectedChainType)
8685

87-
// Apply chain type filtering using shared utility (same as desktop sidebar)
86+
// Apply unified chain type filtering that respects both language AND chain filters
8887
useEffect(() => {
89-
applyChainTypeFilter(currentChain)
88+
const sidebarItems = document.querySelectorAll<HTMLElement>("[data-chain-types]")
89+
90+
sidebarItems.forEach((item) => {
91+
const chainTypesAttr = item.getAttribute("data-chain-types")
92+
93+
let chainVisible = true
94+
if (chainTypesAttr === "universal" || !chainTypesAttr) {
95+
chainVisible = true // Always show universal/legacy content
96+
} else {
97+
const itemChains = chainTypesAttr.split(",")
98+
chainVisible = itemChains.includes(currentChain)
99+
}
100+
101+
// Don't overwrite language filtering - only hide if chain doesn't match
102+
// Language filtering is already handled in renderPages function above
103+
item.style.display = chainVisible ? "" : "none"
104+
})
90105
}, [currentChain])
91106

92107
if (!subProducts) {

src/components/LeftSidebar/LeftSidebar.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,14 @@ const sidebarSections = getSidebarSections(section)
161161

162162
<script>
163163
import { selectedChainType } from "~/stores/chainType"
164-
import { applyChainTypeFilter } from "~/utils/chainType.js"
165164

166165
/**
167166
* Filters sidebar items based on selected chain type
168-
* Uses shared utility function for consistency with mobile drawer
167+
* Triggers the unified filter in RecursiveSidebar that respects BOTH chain type AND language
169168
*/
170169
function filterSidebarByChainType() {
171-
applyChainTypeFilter(selectedChainType.get())
170+
// trigger a languageChanged event to run the unified filter
171+
window.dispatchEvent(new CustomEvent("languageChanged"))
172172
}
173173

174174
// Run on initial load

src/components/LeftSidebar/RecursiveSidebar.astro

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,49 @@ function shouldExpandSection(item: SectionContent, currentPage: string): boolean
164164
</ul>
165165

166166
<script>
167+
/**
168+
* Unified filter that checks BOTH language AND chain type criteria
169+
* This prevents one filter from overwriting the other's display property
170+
*/
171+
function shouldShowSidebarItem(item: HTMLElement, currentLang: string, currentChain?: string): boolean {
172+
// Check language filter
173+
const sdkLang = item.getAttribute("data-sdk-lang")
174+
const langVisible =
175+
sdkLang === "both" || // Always show language-agnostic items
176+
!sdkLang || // Items without sdkLang attribute
177+
sdkLang === currentLang // Matches current language
178+
179+
// Check chain type filter (only if chain filtering is active)
180+
let chainVisible = true
181+
if (currentChain) {
182+
const chainTypesAttr = item.getAttribute("data-chain-types")
183+
if (chainTypesAttr === "universal" || !chainTypesAttr) {
184+
chainVisible = true // Always show universal/legacy content
185+
} else {
186+
const itemChains = chainTypesAttr.split(",")
187+
chainVisible = itemChains.includes(currentChain)
188+
}
189+
}
190+
191+
// Item is visible only if BOTH filters pass
192+
return langVisible && chainVisible
193+
}
194+
195+
/**
196+
* Detects chain type from URL path
197+
* This ensures consistent behavior even before the store initializes
198+
*/
199+
function detectChainFromPath(pathname: string): string | null {
200+
if (/\/(evm|ethereum)(\/|$)/i.test(pathname)) return "evm"
201+
if (/\/(svm|solana)(\/|$)/i.test(pathname)) return "solana"
202+
if (/\/aptos(\/|$)/i.test(pathname)) return "aptos"
203+
return null
204+
}
205+
167206
/**
168207
* Filters sidebar items based on selected SDK language
169208
* - Hides items with data-sdk-lang that don't match current selection
209+
* - Respects chain type filtering if active
170210
* - Runs on initial load and when language changes
171211
*/
172212
function filterSidebarByLanguage() {
@@ -181,22 +221,38 @@ function shouldExpandSection(item: SectionContent, currentPage: string): boolean
181221
// Fallback to default
182222
}
183223

224+
// Get current chain type if chain filtering is active (for CCIP section)
225+
// Priority: URL path detection → localStorage → default (EVM)
226+
let currentChain: string | undefined
227+
try {
228+
// Priority 1: Detect from URL (e.g., /ccip/getting-started/svm → "solana")
229+
const detectedChain = detectChainFromPath(window.location.pathname)
230+
if (detectedChain) {
231+
currentChain = detectedChain
232+
} else {
233+
// Priority 2: Read from localStorage
234+
const chainStore = localStorage.getItem("chainlink-docs-chain-type")
235+
if (chainStore) {
236+
currentChain = chainStore
237+
} else {
238+
// Priority 3: Default to EVM if we're in a section that uses chain filtering
239+
// Check if any items in the sidebar have chain type attributes
240+
const hasChainTypes = document.querySelector("[data-chain-types]:not([data-chain-types='universal'])")
241+
if (hasChainTypes) {
242+
currentChain = "evm" // Default chain type
243+
}
244+
}
245+
}
246+
} catch {
247+
// Chain filtering not active in this section
248+
}
249+
184250
// Find all sidebar items with data-sdk-lang attribute
185251
const sidebarItems = document.querySelectorAll<HTMLElement>("[data-sdk-lang]")
186252

187253
sidebarItems.forEach((item) => {
188-
const sdkLang = item.getAttribute("data-sdk-lang")
189-
190-
if (sdkLang === "both") {
191-
// Always show items that are language-agnostic
192-
item.style.display = ""
193-
} else if (sdkLang !== currentLang) {
194-
// Hide items that don't match current language
195-
item.style.display = "none"
196-
} else {
197-
// Show items that match current language
198-
item.style.display = ""
199-
}
254+
const visible = shouldShowSidebarItem(item, currentLang, currentChain)
255+
item.style.display = visible ? "" : "none"
200256
})
201257
}
202258

0 commit comments

Comments
 (0)