11<!-- layouts/partials/version-selector.html -->
22< div class ="version-selector ">
3- < button class ="version-button " id ="versionButton ">
3+ < button class ="version-button " id ="versionButton " type =" button " >
44 < span id ="currentVersion "> Loading...</ span >
5- < svg width ="12 " height ="12 " viewBox ="0 0 12 12 " fill ="none ">
6- < path d ="M2 4L6 8L10 4 " stroke ="currentColor " stroke-width ="2 "/>
5+ < svg width ="12 " height ="12 " viewBox ="0 0 12 12 " fill ="none " class =" version-arrow " >
6+ < path d ="M2 4L6 8L10 4 " stroke ="currentColor " stroke-width ="1.5 " stroke-linecap =" round " stroke-linejoin =" round "/>
77 </ svg >
88 </ button >
99 < div class ="version-dropdown " id ="versionDropdown ">
1717 .version-selector {
1818 position : relative;
1919 display : inline-block;
20+ outline : none !important ;
21+ }
22+
23+ .version-selector span ,
24+ .version-selector svg {
25+ outline : none !important ;
2026 }
2127
2228 .version-button {
23- display : flex;
29+ display : inline- flex;
2430 align-items : center;
25- gap : 8px ;
26- padding : 8px 16px ;
27- background : # f5f5f5 ;
28- border : 1px solid # ddd ;
29- border-radius : 6px ;
31+ gap : 6px ;
32+ padding : 0 ;
33+ background : none;
34+ border : none;
3035 cursor : pointer;
3136 font-size : 14px ;
32- font-weight : 500 ;
33- transition : all 0.2s ;
37+ font-weight : 400 ;
38+ color : inherit;
39+ transition : opacity 0.2s ;
40+ font-family : inherit;
41+ outline : none !important ;
42+ box-shadow : none !important ;
43+ -webkit-appearance : none !important ;
44+ -moz-appearance : none !important ;
45+ appearance : none !important ;
46+ -webkit-focus-ring-color : transparent !important ;
47+ -webkit-tap-highlight-color : transparent !important ;
3448 }
3549
3650 .version-button : hover {
37- background : # e8e8e8 ;
38- border-color : # ccc ;
51+ opacity : 0.7 ;
52+ }
53+
54+ .version-button : focus ,
55+ .version-button : focus-visible ,
56+ .version-button : focus-within ,
57+ .version-button : active {
58+ outline : none !important ;
59+ box-shadow : none !important ;
60+ border : none !important ;
61+ -webkit-appearance : none !important ;
62+ -moz-appearance : none !important ;
63+ appearance : none !important ;
64+ -webkit-focus-ring-color : transparent !important ;
65+ -webkit-tap-highlight-color : transparent !important ;
66+ }
67+ .version-arrow {
68+ transition : transform 0.2s , opacity 0.2s ;
69+ opacity : 0.6 ;
70+ }
71+
72+ .version-button : hover .version-arrow {
73+ opacity : 0.8 ;
74+ }
75+
76+ .version-selector .active .version-arrow {
77+ transform : rotate (180deg );
78+ opacity : 0.8 ;
3979 }
4080
4181 .version-dropdown {
4282 position : absolute;
43- top : calc (100% + 4 px );
83+ top : calc (100% + 8 px );
4484 left : 0 ;
4585 min-width : 200px ;
4686 background : white;
47- border : 1px solid # ddd ;
48- border-radius : 6 px ;
49- box-shadow : 0 4px 12 px rgba (0 , 0 , 0 , 0.1 );
87+ border : 1px solid # e0e0e0 ;
88+ border-radius : 8 px ;
89+ box-shadow : 0 4px 16 px rgba (0 , 0 , 0 , 0.12 );
5090 opacity : 0 ;
5191 visibility : hidden;
52- transform : translateY (-8 px );
53- transition : all 0.2s ;
92+ transform : translateY (-4 px );
93+ transition : all 0.2s ease ;
5494 z-index : 1000 ;
5595 }
5696
61101 }
62102
63103 .version-list {
64- padding : 8 px 0 ;
104+ padding : 4 px 0 ;
65105 }
66106
67107 .version-item {
68108 display : block;
69109 padding : 10px 16px ;
70110 color : # 333 ;
71111 text-decoration : none;
72- transition : background 0.2 s ;
112+ transition : background 0.15 s ;
73113 cursor : pointer;
114+ font-size : 14px ;
74115 }
75116
76117 .version-item : hover {
80121 .version-item .active {
81122 background : # e3f2fd ;
82123 color : # 1976d2 ;
83- font-weight : 600 ;
124+ font-weight : 500 ;
125+ }
126+
127+ /* Dark mode styles using .dark-blog selector */
128+ .dark-blog .version-dropdown {
129+ background : # 2a2a2a ;
130+ border-color : # 444 ;
131+ box-shadow : 0 4px 16px rgba (0 , 0 , 0 , 0.5 );
132+ }
133+
134+ .dark-blog .version-item {
135+ color : # ffffff ;
136+ }
137+
138+ .dark-blog .version-item : hover {
139+ background : # 3a3a3a ;
140+ color : # ffffff ;
141+ }
142+
143+ .dark-blog .version-item .active {
144+ background : # 1a3a5c ;
145+ color : # 64b5f6 ;
146+ font-weight : 500 ;
147+ }
148+
149+ /* Also support [data-theme="dark"] for compatibility */
150+ [data-theme = "dark" ] .version-dropdown {
151+ background : # 2a2a2a ;
152+ border-color : # 444 ;
153+ box-shadow : 0 4px 16px rgba (0 , 0 , 0 , 0.5 );
154+ }
155+
156+ [data-theme = "dark" ] .version-item {
157+ color : # ffffff ;
158+ }
159+
160+ [data-theme = "dark" ] .version-item : hover {
161+ background : # 3a3a3a ;
162+ color : # ffffff ;
163+ }
164+
165+ [data-theme = "dark" ] .version-item .active {
166+ background : # 1a3a5c ;
167+ color : # 64b5f6 ;
168+ font-weight : 500 ;
84169 }
85170 </ style >
86171
94179 // Get current path to determine active version
95180 function getCurrentVersion ( ) {
96181 const path = window . location . pathname ;
97- const match = path . match ( / ^ \/ ( v [ \d . ] + ) \/ / ) ;
98- return match ? match [ 1 ] : 'latest' ;
182+ // Check for versioned path like /v24.1/ or /v25.0/
183+ const versionMatch = path . match ( / ^ \/ ( v [ \d . ] + ) \/ / ) ;
184+ if ( versionMatch ) {
185+ return versionMatch [ 1 ] ;
186+ }
187+ // If no version in path, check if we're at root
188+ // Root path should match "main" version
189+ return 'main' ;
190+ }
191+
192+ // Find current version by matching URL or version key
193+ function findCurrentVersion ( data ) {
194+ const currentPath = window . location . pathname ;
195+
196+ // First try to match by version key
197+ const currentVersionKey = getCurrentVersion ( ) ;
198+ let versionData = data . versions . find ( v => v . version === currentVersionKey ) ;
199+
200+ // If not found, try to match by URL
201+ if ( ! versionData ) {
202+ versionData = data . versions . find ( v => {
203+ const url = v . url . replace ( / \/ $ / , '' ) || '/' ;
204+ const normalizedPath = currentPath . replace ( / \/ $ / , '' ) || '/' ;
205+ return normalizedPath === url || normalizedPath . startsWith ( url + '/' ) ;
206+ } ) ;
207+ }
208+
209+ // If still not found, try to match if path starts with version URL
210+ if ( ! versionData ) {
211+ versionData = data . versions . find ( v => {
212+ const url = v . url . replace ( / \/ $ / , '' ) || '/' ;
213+ return currentPath . startsWith ( url ) ;
214+ } ) ;
215+ }
216+
217+ return versionData || data . versions [ 0 ] ; // Fallback to first version
99218 }
100219
101220 // Load versions from versions.json
102221 async function loadVersions ( ) {
103222 try {
104- // Determine the base URL for versions.json
105- const path = window . location . pathname ;
106- const versionMatch = path . match ( / ^ \/ ( v [ \d . ] + ) \/ / ) ;
107- const baseUrl = versionMatch ? `/${ versionMatch [ 1 ] } ` : '' ;
108-
109223 const response = await fetch ( '/versions.json' ) ;
224+ if ( ! response . ok ) {
225+ throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
226+ }
110227 const data = await response . json ( ) ;
111- const currentVersion = getCurrentVersion ( ) ;
112228
113- // Update current version display
114- const currentVersionData = data . versions . find ( v => v . version === currentVersion ) ;
229+ if ( ! data . versions || data . versions . length === 0 ) {
230+ throw new Error ( 'No versions found in versions.json' ) ;
231+ }
232+
233+ // Find and display current version
234+ const currentVersionData = findCurrentVersion ( data ) ;
115235 if ( currentVersionData ) {
116236 currentVersionSpan . textContent = currentVersionData . title ;
237+ } else {
238+ currentVersionSpan . textContent = data . versions [ 0 ] . title ;
117239 }
118240
119241 // Populate version list
242+ const currentVersionKey = getCurrentVersion ( ) ;
120243 versionList . innerHTML = data . versions . map ( version => {
121- const isActive = version . version === currentVersion ;
244+ const isActive = version . version === currentVersionKey ||
245+ ( currentVersionData && version . version === currentVersionData . version ) ;
122246 return `
123247 <a href="${ version . url } " class="version-item ${ isActive ? 'active' : '' } ">
124248 ${ version . title }
135259 // Toggle dropdown
136260 button . addEventListener ( 'click' , ( e ) => {
137261 e . stopPropagation ( ) ;
138- dropdown . classList . toggle ( 'active' ) ;
262+ const isActive = dropdown . classList . toggle ( 'active' ) ;
263+ // Toggle active class on parent for arrow rotation
264+ button . closest ( '.version-selector' ) . classList . toggle ( 'active' , isActive ) ;
139265 } ) ;
140266
141267 // Close dropdown when clicking outside
142268 document . addEventListener ( 'click' , ( ) => {
143269 dropdown . classList . remove ( 'active' ) ;
270+ button . closest ( '.version-selector' ) . classList . remove ( 'active' ) ;
144271 } ) ;
145272
146273 // Prevent dropdown from closing when clicking inside
151278 // Load versions on page load
152279 loadVersions ( ) ;
153280 } ) ( ) ;
281+ </ script >
154282 </ script>
0 commit comments