1+ import { CIcon } from "@coreui/icons-react" ;
2+ import {
3+ cilSearch ,
4+ cilBarChart ,
5+ cilLayers ,
6+ cilShieldAlt ,
7+ cilCompass ,
8+ cilSpeedometer ,
9+ cilGlobeAlt ,
10+ cilLockLocked ,
11+ cilBell ,
12+ cilRss ,
13+ } from "@coreui/icons" ;
114import React from "react" ;
215
3- /* Named icon set — keeps MDX content simple: pass iconName="search" */
4- const ICONS : Record < string , React . ReactNode > = {
5- search : (
6- < svg
7- viewBox = "0 0 24 24"
8- fill = "none"
9- stroke = "currentColor"
10- strokeWidth = { 1.6 }
11- strokeLinecap = "round"
12- strokeLinejoin = "round"
13- aria-hidden = "true"
14- >
15- < circle cx = "11" cy = "11" r = "7" />
16- < path d = "M20 20l-3.5-3.5" />
17- </ svg >
18- ) ,
19- pulse : (
20- < svg
21- viewBox = "0 0 24 24"
22- fill = "none"
23- stroke = "currentColor"
24- strokeWidth = { 1.6 }
25- strokeLinecap = "round"
26- strokeLinejoin = "round"
27- aria-hidden = "true"
28- >
29- < path d = "M3 12h4l2-6 4 12 2-6h6" />
30- </ svg >
31- ) ,
32- box : (
33- < svg
34- viewBox = "0 0 24 24"
35- fill = "none"
36- stroke = "currentColor"
37- strokeWidth = { 1.6 }
38- strokeLinecap = "round"
39- strokeLinejoin = "round"
40- aria-hidden = "true"
41- >
42- < path d = "M3 7l9-4 9 4-9 4-9-4z" />
43- < path d = "M3 7v10l9 4 9-4V7" />
44- < path d = "M12 11v10" />
45- </ svg >
46- ) ,
47- shield : (
48- < svg
49- viewBox = "0 0 24 24"
50- fill = "none"
51- stroke = "currentColor"
52- strokeWidth = { 1.6 }
53- strokeLinecap = "round"
54- strokeLinejoin = "round"
55- aria-hidden = "true"
56- >
57- < path d = "M12 3l8 3v6c0 4.5-3.4 8.4-8 9-4.6-.6-8-4.5-8-9V6l8-3z" />
58- </ svg >
59- ) ,
60- compass : (
61- < svg
62- viewBox = "0 0 24 24"
63- fill = "none"
64- stroke = "currentColor"
65- strokeWidth = { 1.6 }
66- strokeLinecap = "round"
67- strokeLinejoin = "round"
68- aria-hidden = "true"
69- >
70- < circle cx = "12" cy = "12" r = "9" />
71- < path d = "M15 9l-2 5-5 2 2-5 5-2z" />
72- </ svg >
73- ) ,
74- gauge : (
75- < svg
76- viewBox = "0 0 24 24"
77- fill = "none"
78- stroke = "currentColor"
79- strokeWidth = { 1.6 }
80- strokeLinecap = "round"
81- strokeLinejoin = "round"
82- aria-hidden = "true"
83- >
84- < path d = "M3 14a9 9 0 0 1 18 0" />
85- < path d = "M12 14l4-4" />
86- < circle cx = "12" cy = "14" r = "1.5" />
87- </ svg >
88- ) ,
89- lock : (
90- < svg
91- viewBox = "0 0 24 24"
92- fill = "none"
93- stroke = "currentColor"
94- strokeWidth = { 1.6 }
95- strokeLinecap = "round"
96- strokeLinejoin = "round"
97- aria-hidden = "true"
98- >
99- < rect x = "4" y = "11" width = "16" height = "10" rx = "2" />
100- < path d = "M8 11V7a4 4 0 0 1 8 0v4" />
101- </ svg >
102- ) ,
103- globe : (
104- < svg
105- viewBox = "0 0 24 24"
106- fill = "none"
107- stroke = "currentColor"
108- strokeWidth = { 1.6 }
109- strokeLinecap = "round"
110- strokeLinejoin = "round"
111- aria-hidden = "true"
112- >
113- < circle cx = "12" cy = "12" r = "9" />
114- < path d = "M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" />
115- </ svg >
116- ) ,
117- bell : (
118- < svg
119- viewBox = "0 0 24 24"
120- fill = "none"
121- stroke = "currentColor"
122- strokeWidth = { 1.6 }
123- strokeLinecap = "round"
124- strokeLinejoin = "round"
125- aria-hidden = "true"
126- >
127- < path d = "M6 16V11a6 6 0 1 1 12 0v5l1.5 2H4.5L6 16z" />
128- < path d = "M10 21h4" />
129- </ svg >
130- ) ,
16+ const CUI : Record < string , object > = {
17+ search : cilSearch ,
18+ pulse : cilBarChart ,
19+ box : cilLayers ,
20+ shield : cilShieldAlt ,
21+ compass : cilCompass ,
22+ gauge : cilSpeedometer ,
23+ globe : cilGlobeAlt ,
24+ lock : cilLockLocked ,
25+ bell : cilBell ,
26+ feed : cilRss ,
13127} ;
13228
13329export type Challenge = {
@@ -153,7 +49,9 @@ export default function ChallengeGrid({ challenges }: Props) {
15349 } }
15450 >
15551 { challenges . map ( ( c , i ) => {
156- const icon = c . icon ?? ( c . iconName ? ICONS [ c . iconName ] : null ) ;
52+ const iconEl = c . icon ?? ( c . iconName && CUI [ c . iconName ] ? (
53+ < CIcon icon = { CUI [ c . iconName ] as Parameters < typeof CIcon > [ 0 ] [ "icon" ] } aria-hidden = "true" />
54+ ) : null ) ;
15755 return (
15856 < div
15957 // biome-ignore lint/suspicious/noArrayIndexKey: challenges have no stable id
@@ -168,7 +66,7 @@ export default function ChallengeGrid({ challenges }: Props) {
16866 } }
16967 >
17068 < div style = { { display : "flex" , alignItems : "center" , gap : 12 , marginBottom : 10 } } >
171- { icon && (
69+ { iconEl && (
17270 < div
17371 style = { {
17472 width : 36 ,
@@ -183,7 +81,7 @@ export default function ChallengeGrid({ challenges }: Props) {
18381 flexShrink : 0 ,
18482 } }
18583 >
186- < div style = { { width : 17 , height : 17 , display : "flex" } } > { icon } </ div >
84+ < div style = { { width : 17 , height : 17 , display : "flex" } } > { iconEl } </ div >
18785 </ div >
18886 ) }
18987 < div
@@ -197,7 +95,15 @@ export default function ChallengeGrid({ challenges }: Props) {
19795 { String ( i + 1 ) . padStart ( 2 , "0" ) }
19896 </ div >
19997 </ div >
200- < div style = { { fontSize : 15 , fontWeight : 600 , color : "var(--cs-ink)" , marginBottom : 6 , letterSpacing : "-0.005em" } } >
98+ < div
99+ style = { {
100+ fontSize : 15 ,
101+ fontWeight : 600 ,
102+ color : "var(--cs-ink)" ,
103+ marginBottom : 6 ,
104+ letterSpacing : "-0.005em" ,
105+ } }
106+ >
201107 { c . title }
202108 </ div >
203109 < div style = { { fontSize : 13.5 , color : "var(--cs-ink-dim)" , lineHeight : 1.55 } } > { c . body } </ div >
0 commit comments