11import { cdnImports , importFromCdnWithFallback } from './cdn.js'
2+ import { createCodeMirrorEditor } from './editor-codemirror.js'
23
34const statusNode = document . getElementById ( 'status' )
45const renderMode = document . getElementById ( 'render-mode' )
@@ -65,6 +66,10 @@ button:focus-visible {
6566jsxEditor . value = defaultJsx
6667cssEditor . value = defaultCss
6768
69+ let jsxCodeEditor = null
70+ let cssCodeEditor = null
71+ let getJsxSource = ( ) => jsxEditor . value
72+ let getCssSource = ( ) => cssEditor . value
6873let scheduled = null
6974let reactRoot = null
7075let reactRuntime = null
@@ -85,6 +90,54 @@ const styleLabels = {
8590 sass : 'Sass' ,
8691}
8792
93+ const getStyleEditorLanguage = mode => {
94+ if ( mode === 'less' ) return 'less'
95+ if ( mode === 'sass' ) return 'sass'
96+ return 'css'
97+ }
98+
99+ const createEditorHost = textarea => {
100+ const host = document . createElement ( 'div' )
101+ host . className = 'editor-host'
102+ textarea . before ( host )
103+ return host
104+ }
105+
106+ const initializeCodeEditors = async ( ) => {
107+ const jsxHost = createEditorHost ( jsxEditor )
108+ const cssHost = createEditorHost ( cssEditor )
109+
110+ try {
111+ const [ nextJsxEditor , nextCssEditor ] = await Promise . all ( [
112+ createCodeMirrorEditor ( {
113+ parent : jsxHost ,
114+ value : defaultJsx ,
115+ language : 'javascript-jsx' ,
116+ onChange : maybeRender ,
117+ } ) ,
118+ createCodeMirrorEditor ( {
119+ parent : cssHost ,
120+ value : defaultCss ,
121+ language : getStyleEditorLanguage ( styleMode . value ) ,
122+ onChange : maybeRender ,
123+ } ) ,
124+ ] )
125+
126+ jsxCodeEditor = nextJsxEditor
127+ cssCodeEditor = nextCssEditor
128+ getJsxSource = ( ) => jsxCodeEditor . getValue ( )
129+ getCssSource = ( ) => cssCodeEditor . getValue ( )
130+
131+ jsxEditor . classList . add ( 'source-textarea--hidden' )
132+ cssEditor . classList . add ( 'source-textarea--hidden' )
133+ } catch ( error ) {
134+ jsxHost . remove ( )
135+ cssHost . remove ( )
136+ const message = error instanceof Error ? error . message : String ( error )
137+ setStatus ( `Editor fallback: ${ message } ` )
138+ }
139+ }
140+
88141const ensureCoreRuntime = async ( ) => {
89142 if ( coreRuntime ) return coreRuntime
90143
@@ -423,7 +476,8 @@ const ensureLightningCssWasm = async () => {
423476const compileStyles = async ( ) => {
424477 const { cssFromSource } = await ensureCoreRuntime ( )
425478 const dialect = styleMode . value
426- const cacheKey = `${ dialect } \u0000${ cssEditor . value } `
479+ const cssSource = getCssSource ( )
480+ const cacheKey = `${ dialect } \u0000${ cssSource } `
427481 if ( compiledStylesCache . key === cacheKey && compiledStylesCache . value ) {
428482 return compiledStylesCache . value
429483 }
@@ -432,7 +486,7 @@ const compileStyles = async () => {
432486 setStyleCompiling ( shouldShowSpinner )
433487
434488 if ( ! shouldShowSpinner ) {
435- const output = { css : cssEditor . value , moduleExports : null }
489+ const output = { css : cssSource , moduleExports : null }
436490 compiledStylesCache = {
437491 key : cacheKey ,
438492 value : output ,
@@ -459,7 +513,7 @@ const compileStyles = async () => {
459513 options . lightningcss = await ensureLightningCssWasm ( )
460514 }
461515
462- const result = await cssFromSource ( cssEditor . value , options )
516+ const result = await cssFromSource ( cssSource , options )
463517 if ( ! result . ok ) {
464518 throw new Error ( result . error . message )
465519 }
@@ -486,7 +540,7 @@ const compileStyles = async () => {
486540
487541const evaluateUserModule = async ( helpers = { } ) => {
488542 const { jsx, transpileJsxSource } = await ensureCoreRuntime ( )
489- const userCode = jsxEditor . value
543+ const userCode = getJsxSource ( )
490544 . replace ( / ^ \s * e x p o r t \s + d e f a u l t \s + f u n c t i o n \b / gm, '__defaultExport = function' )
491545 . replace ( / ^ \s * e x p o r t \s + d e f a u l t \s + c l a s s \b / gm, '__defaultExport = class' )
492546 . replace ( / ^ \s * e x p o r t \s + d e f a u l t \s + / gm, '__defaultExport = ' )
@@ -633,7 +687,12 @@ const maybeRender = () => {
633687}
634688
635689renderMode . addEventListener ( 'change' , maybeRender )
636- styleMode . addEventListener ( 'change' , maybeRender )
690+ styleMode . addEventListener ( 'change' , ( ) => {
691+ if ( cssCodeEditor ) {
692+ cssCodeEditor . setLanguage ( getStyleEditorLanguage ( styleMode . value ) )
693+ }
694+ maybeRender ( )
695+ } )
637696shadowToggle . addEventListener ( 'change' , maybeRender )
638697autoRenderToggle . addEventListener ( 'change' , ( ) => {
639698 if ( autoRenderToggle . checked ) {
@@ -646,4 +705,5 @@ cssEditor.addEventListener('input', maybeRender)
646705
647706setStyleCompiling ( false )
648707setCdnLoading ( true )
708+ void initializeCodeEditors ( )
649709renderPreview ( )
0 commit comments