11import { useState , useEffect } from "react" ;
22
3+ // Available Monaco Editor themes
4+ export const EDITOR_THEMES = [
5+ { id : "vs-dark" , name : "VS Code Dark" , description : "Default dark theme" } ,
6+ { id : "vs" , name : "VS Code Light" , description : "Default light theme" } ,
7+ { id : "hc-black" , name : "High Contrast" , description : "High contrast dark theme" } ,
8+ { id : "dracula" , name : "Dracula" , description : "Popular dark theme with purple accents" } ,
9+ { id : "monokai" , name : "Monokai" , description : "Classic dark theme with vibrant colors" } ,
10+ { id : "github-dark" , name : "GitHub Dark" , description : "GitHub's dark theme" } ,
11+ ] as const ;
12+
13+ export type EditorTheme = typeof EDITOR_THEMES [ number ] [ "id" ] ;
14+
315interface CdnLibrary {
416 id : string ;
517 name : string ;
@@ -50,6 +62,7 @@ export interface CdnSettings {
5062export interface EditorSettings {
5163 showMinimap : boolean ;
5264 wordWrap : boolean ;
65+ theme : EditorTheme ;
5366}
5467
5568interface SettingsModalProps {
@@ -78,10 +91,14 @@ function SettingsModal({ isOpen, onClose, cdnSettings, editorSettings, onSave }:
7891 setLocalCdnSettings ( ( prev ) => ( { ...prev , [ id ] : ! prev [ id ] } ) ) ;
7992 } ;
8093
81- const handleEditorToggle = ( key : keyof EditorSettings ) => {
94+ const handleEditorToggle = ( key : "showMinimap" | "wordWrap" ) => {
8295 setLocalEditorSettings ( ( prev ) => ( { ...prev , [ key ] : ! prev [ key ] } ) ) ;
8396 } ;
8497
98+ const handleThemeChange = ( themeId : EditorTheme ) => {
99+ setLocalEditorSettings ( ( prev ) => ( { ...prev , theme : themeId } ) ) ;
100+ } ;
101+
85102 const handleSave = ( ) => {
86103 onSave ( localCdnSettings , localEditorSettings ) ;
87104 onClose ( ) ;
@@ -102,36 +119,72 @@ function SettingsModal({ isOpen, onClose, cdnSettings, editorSettings, onSave }:
102119 </ div >
103120
104121 { /* Body */ }
105- < div className = "p-6 space-y-6 max-h-[60vh] overflow-y-auto" >
122+ < div className = "p-6 space-y-6 max-h-[60vh] overflow-y-auto settings-scrollbar " >
106123 { /* Editor Settings */ }
107124 < div >
108125 < h3 className = "text-sm font-semibold text-slate-400 uppercase tracking-wider mb-3" >
109126 Editor
110127 </ h3 >
111- < label className = "flex items-center justify-between p-3 rounded-lg bg-slate-900/50 hover:bg-slate-700/50 cursor-pointer transition-colors border border-slate-700/50" >
112- < div >
113- < span className = "text-white font-medium" > Minimap</ span >
114- < p className = "text-xs text-slate-400" > Show code minimap on the right side</ p >
128+
129+ { /* Theme Selector */ }
130+ < div className = "p-4 rounded-xl bg-slate-900/50 setting-card mb-3" >
131+ < div className = "flex items-center justify-between mb-3" >
132+ < div >
133+ < span className = "text-white font-medium" > Theme</ span >
134+ < p className = "text-xs text-slate-400 mt-0.5" > Choose editor color scheme</ p >
135+ </ div >
136+ < svg className = "w-5 h-5 text-slate-500" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
137+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" />
138+ </ svg >
139+ </ div >
140+ < select
141+ value = { localEditorSettings . theme }
142+ onChange = { ( e ) => handleThemeChange ( e . target . value as EditorTheme ) }
143+ className = "w-full px-4 py-2.5 rounded-lg text-white text-sm custom-select"
144+ >
145+ { EDITOR_THEMES . map ( ( theme ) => (
146+ < option key = { theme . id } value = { theme . id } >
147+ { theme . name }
148+ </ option >
149+ ) ) }
150+ </ select >
151+ </ div >
152+
153+ < div
154+ className = "flex items-center justify-between p-4 rounded-xl bg-slate-900/50 setting-card cursor-pointer"
155+ onClick = { ( ) => handleEditorToggle ( "showMinimap" ) }
156+ >
157+ < div className = "flex items-center gap-3" >
158+ < div className = "w-9 h-9 rounded-lg bg-indigo-500/10 flex items-center justify-center" >
159+ < svg className = "w-5 h-5 text-indigo-400" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
160+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" />
161+ </ svg >
162+ </ div >
163+ < div >
164+ < span className = "text-white font-medium" > Minimap</ span >
165+ < p className = "text-xs text-slate-400 mt-0.5" > Show code minimap on the right side</ p >
166+ </ div >
115167 </ div >
116- < input
117- type = "checkbox"
118- checked = { localEditorSettings . showMinimap }
119- onChange = { ( ) => handleEditorToggle ( "showMinimap" ) }
120- className = "w-5 h-5 rounded border-slate-600 bg-slate-700 text-blue-500 focus:ring-blue-500 focus:ring-offset-slate-800"
121- />
122- </ label >
123- < label className = "flex items-center justify-between p-3 rounded-lg bg-slate-900/50 hover:bg-slate-700/50 cursor-pointer transition-colors border border-slate-700/50 mt-3" >
124- < div >
125- < span className = "text-white font-medium" > Word Wrap</ span >
126- < p className = "text-xs text-slate-400" > Wrap long lines to fit editor width</ p >
168+ < div className = { `toggle-switch ${ localEditorSettings . showMinimap ? 'active' : '' } ` } />
169+ </ div >
170+
171+ < div
172+ className = "flex items-center justify-between p-4 rounded-xl bg-slate-900/50 setting-card cursor-pointer mt-3"
173+ onClick = { ( ) => handleEditorToggle ( "wordWrap" ) }
174+ >
175+ < div className = "flex items-center gap-3" >
176+ < div className = "w-9 h-9 rounded-lg bg-purple-500/10 flex items-center justify-center" >
177+ < svg className = "w-5 h-5 text-purple-400" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
178+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M4 6h16M4 12h16m-7 6h7" />
179+ </ svg >
180+ </ div >
181+ < div >
182+ < span className = "text-white font-medium" > Word Wrap</ span >
183+ < p className = "text-xs text-slate-400 mt-0.5" > Wrap long lines to fit editor width</ p >
184+ </ div >
127185 </ div >
128- < input
129- type = "checkbox"
130- checked = { localEditorSettings . wordWrap }
131- onChange = { ( ) => handleEditorToggle ( "wordWrap" ) }
132- className = "w-5 h-5 rounded border-slate-600 bg-slate-700 text-blue-500 focus:ring-blue-500 focus:ring-offset-slate-800"
133- />
134- </ label >
186+ < div className = { `toggle-switch ${ localEditorSettings . wordWrap ? 'active' : '' } ` } />
187+ </ div >
135188 </ div >
136189
137190 { /* CDN Libraries */ }
@@ -145,21 +198,24 @@ function SettingsModal({ isOpen, onClose, cdnSettings, editorSettings, onSave }:
145198
146199 < div className = "space-y-3" >
147200 { CDN_LIBRARIES . map ( ( lib ) => (
148- < label
201+ < div
149202 key = { lib . id }
150- className = "flex items-start gap-3 p-3 rounded-lg bg-slate-900/50 hover:bg-slate-700/50 cursor-pointer transition-colors border border-slate-700/50"
203+ className = "flex items-center justify-between p-4 rounded-xl bg-slate-900/50 setting-card cursor-pointer"
204+ onClick = { ( ) => handleCdnToggle ( lib . id ) }
151205 >
152- < input
153- type = "checkbox"
154- checked = { ! ! localCdnSettings [ lib . id ] }
155- onChange = { ( ) => handleCdnToggle ( lib . id ) }
156- className = "mt-1 w-4 h-4 rounded border-slate-600 bg-slate-700 text-blue-500 focus:ring-blue-500 focus:ring-offset-slate-800"
157- />
158- < div >
159- < span className = "text-white font-medium" > { lib . name } </ span >
160- < p className = "text-xs text-slate-400" > { lib . description } </ p >
206+ < div className = "flex items-center gap-3" >
207+ < div className = "w-9 h-9 rounded-lg bg-blue-500/10 flex items-center justify-center" >
208+ < svg className = "w-5 h-5 text-blue-400" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
209+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
210+ </ svg >
211+ </ div >
212+ < div >
213+ < span className = "text-white font-medium" > { lib . name } </ span >
214+ < p className = "text-xs text-slate-400 mt-0.5" > { lib . description } </ p >
215+ </ div >
161216 </ div >
162- </ label >
217+ < div className = { `toggle-switch ${ localCdnSettings [ lib . id ] ? 'active' : '' } ` } />
218+ </ div >
163219 ) ) }
164220 </ div >
165221 </ div >
0 commit comments