11"use client" ;
22
33import { IconCheckmarkLine , IconChevronDownLine } from "@karrotmarket/react-monochrome-icon" ;
4- import { useEffect , useState } from "react" ;
4+ import { useState } from "react" ;
55import { Popover , PopoverContent , PopoverTrigger } from "fumadocs-ui/components/ui/popover" ;
66import { buttonVariants } from "fumadocs-ui/components/ui/button" ;
77import { cva } from "class-variance-authority" ;
@@ -20,47 +20,11 @@ const itemVariants = cva(
2020 "text-sm p-2 rounded-lg inline-flex items-center gap-2 hover:text-fd-accent-foreground hover:bg-fd-accent [&_svg]:size-4" ,
2121) ;
2222
23- // "v2.0 (latest)" → "2.0", "v1.1" → "1.1", "alpha" → undefined
24- const lineOf = ( label : string ) => label . match ( / ( \d + \. \d + ) / ) ?. [ 1 ] ;
25-
26- // 같은 라인(x.y) 내 버전끼리 패치 오름차순 비교
27- const cmpPatch = ( a : string , b : string ) =>
28- a . split ( "." ) . reduce ( ( acc , n , i ) => acc || Number ( n ) - Number ( b . split ( "." ) [ i ] ) , 0 ) ;
29-
30- const latestForLine = ( data : { versions : Record < string , unknown > } , line : string ) =>
31- Object . keys ( data . versions )
32- . filter ( ( v ) => v . startsWith ( `${ line } .` ) && ! v . includes ( "-" ) ) // prerelease 제외
33- . sort ( cmpPatch )
34- . at ( - 1 ) ;
35-
36- type PackageVersions = Record < string , { react ?: string ; css ?: string } > ;
37-
3823export function ReactVersionSwitcher ( ) {
3924 const [ open , setOpen ] = useState ( false ) ;
40- const [ pkgVersions , setPkgVersions ] = useState < PackageVersions > ( { } ) ;
4125
4226 const current = VERSIONS . find ( ( v ) => v . label === CURRENT_VERSION ) ?? VERSIONS [ 0 ] ;
4327
44- // 드롭다운을 처음 열 때 npm registry에서 각 라인의 최신 안정 패치를 1회 조회
45- useEffect ( ( ) => {
46- if ( ! open || Object . keys ( pkgVersions ) . length ) return ;
47- const headers = { Accept : "application/vnd.npm.install-v1+json" } ; // 축약 메타데이터
48- Promise . all ( [
49- fetch ( "https://registry.npmjs.org/@seed-design/react" , { headers } ) . then ( ( r ) => r . json ( ) ) ,
50- fetch ( "https://registry.npmjs.org/@seed-design/css" , { headers } ) . then ( ( r ) => r . json ( ) ) ,
51- ] )
52- . then ( ( [ react , css ] ) => {
53- const map : PackageVersions = { } ;
54- for ( const { label } of VERSIONS ) {
55- const line = lineOf ( label ) ;
56- if ( ! line ) continue ; // alpha 등 라인 매칭 안 되는 항목은 스킵
57- map [ label ] = { react : latestForLine ( react , line ) , css : latestForLine ( css , line ) } ;
58- }
59- setPkgVersions ( map ) ;
60- } )
61- . catch ( ( ) => { } ) ; // 조회 실패 시 버전 숫자만 생략, 셀렉터는 정상 동작
62- } , [ open , pkgVersions ] ) ;
63-
6428 return (
6529 < Popover open = { open } onOpenChange = { setOpen } >
6630 < PopoverTrigger
@@ -76,32 +40,17 @@ export function ReactVersionSwitcher() {
7640 </ div >
7741 </ PopoverTrigger >
7842 < PopoverContent className = "flex flex-col overflow-auto" >
79- { VERSIONS . map ( ( version ) => {
80- const pkg = pkgVersions [ version . label ] ;
81- const isCurrent = version === current ;
82- const content = (
83- < >
84- < span className = "flex flex-col text-start" >
85- { version . label }
86- { pkg && ( pkg . react || pkg . css ) && (
87- < span className = "text-fd-muted-foreground text-xs" >
88- react { pkg . react ?? "—" } · css { pkg . css ?? "—" }
89- </ span >
90- ) }
91- </ span >
92- { isCurrent && < IconCheckmarkLine /> }
93- </ >
94- ) ;
95-
96- return isCurrent ? (
43+ { VERSIONS . map ( ( version ) =>
44+ version === current ? (
9745 < div
9846 aria-current
9947 key = { version . label }
10048 className = { itemVariants ( {
10149 className : "text-fd-primary pointer-events-none justify-between" ,
10250 } ) }
10351 >
104- { content }
52+ { version . label }
53+ < IconCheckmarkLine />
10554 </ div >
10655 ) : (
10756 < a
@@ -112,10 +61,10 @@ export function ReactVersionSwitcher() {
11261 className = { itemVariants ( { className : "justify-between" } ) }
11362 onClick = { ( ) => setOpen ( false ) }
11463 >
115- { content }
64+ { version . label }
11665 </ a >
117- ) ;
118- } ) }
66+ ) ,
67+ ) }
11968 </ PopoverContent >
12069 </ Popover >
12170 ) ;
0 commit comments