66 */
77
88const path = require ( 'path' ) ;
9- const { addNamed, addNamespace } = require ( '@babel/helper-module-imports' ) ;
9+ const { addNamed } = require ( '@babel/helper-module-imports' ) ;
10+ const styleXPlugin = require ( '@stylexjs/babel-plugin' ) ;
1011
1112function createShortFilename ( absolutePath , baseDir = process . cwd ( ) ) {
1213 if ( ! path . isAbsolute ( baseDir ) ) {
@@ -18,7 +19,7 @@ function createShortFilename(absolutePath, baseDir = process.cwd()) {
1819 return shortPath ;
1920}
2021
21- module . exports = function ( { types : t } , options = { } ) {
22+ function reactStrictPlugin ( { types : t } , options = { } ) {
2223 const packageName = 'react-strict-dom' ;
2324 const packageRuntime = 'react-strict-dom/runtime' ;
2425 const findImportDeclaration = ( body , sourceValue ) =>
@@ -31,12 +32,13 @@ module.exports = function ({ types: t }, options = {}) {
3132 ? specifiers . filter ( ( specifier ) => specifier . imported . name === 'html' )
3233 : [ ] ;
3334 let defaultStylesImportIdentifier ;
34- let stylexImportIdentifier ;
35+ let styleResolverImportIdentifier ;
3536
3637 return {
3738 visitor : {
3839 Program : {
3940 enter ( path ) {
41+ // Add runtime imports
4042 const importDeclarations = findImportDeclaration (
4143 path . node . body ,
4244 packageName
@@ -47,18 +49,24 @@ module.exports = function ({ types: t }, options = {}) {
4749 'defaultStyles' ,
4850 packageRuntime
4951 ) ;
50- stylexImportIdentifier = addNamespace ( path , '@stylexjs/stylex' , {
51- nameHint : 'stylex'
52- } ) ;
52+ styleResolverImportIdentifier = addNamed (
53+ path ,
54+ 'resolveStyle' ,
55+ packageRuntime
56+ ) ;
5357 path . scope . rename (
5458 'defaultStyles' ,
5559 defaultStylesImportIdentifier . name
5660 ) ;
57- path . scope . rename ( 'stylex' , stylexImportIdentifier . name ) ;
61+ path . scope . rename (
62+ 'resolveStyle' ,
63+ styleResolverImportIdentifier . name
64+ ) ;
5865 }
5966 }
6067 } ,
6168 JSXMemberExpression ( path , state ) {
69+ //
6270 const importDeclarations = findImportDeclaration (
6371 state . file . ast . program . body ,
6472 packageName
@@ -96,16 +104,19 @@ module.exports = function ({ types: t }, options = {}) {
96104 let dirAttributeExists = false ;
97105
98106 path . node . attributes . forEach ( ( attribute , index ) => {
107+ // React DOM compat: 'for' replaced by 'htmlFor'
99108 if ( t . isJSXAttribute ( attribute ) && attribute . name . name === 'for' ) {
100109 attribute . name . name = 'htmlFor' ;
101110 }
111+ // Browser compat: 'role=none' replaced by 'role=presentation'
102112 if (
103113 t . isJSXAttribute ( attribute ) &&
104114 attribute . name . name === 'role' &&
105115 attribute . value . value === 'none'
106116 ) {
107117 attribute . value . value = 'presentation' ;
108118 }
119+ // React DOM compat: 'style' replaced by resolver that produces React DOM props
109120 if (
110121 t . isJSXAttribute ( attribute ) &&
111122 attribute . name . name === 'style'
@@ -119,10 +130,7 @@ module.exports = function ({ types: t }, options = {}) {
119130 ) ;
120131 path . node . attributes [ index ] = t . jsxSpreadAttribute (
121132 t . callExpression (
122- t . memberExpression (
123- t . identifier ( stylexImportIdentifier . name ) ,
124- t . identifier ( 'props' )
125- ) ,
133+ t . identifier ( styleResolverImportIdentifier . name ) ,
126134 [ defaultStyles ] . concat (
127135 Array . isArray ( styleValue . elements )
128136 ? styleValue . elements
@@ -139,13 +147,15 @@ module.exports = function ({ types: t }, options = {}) {
139147 }
140148 } ) ;
141149
150+ // Set type=button on <button> by default
142151 const elementName = path . node . name . property . name ;
143152 if ( elementName === 'button' && ! typeAttributeExists ) {
144153 path . node . attributes . push (
145154 t . jsxAttribute ( t . jsxIdentifier ( 'type' ) , t . stringLiteral ( 'button' ) )
146155 ) ;
147156 }
148157
158+ // Set dir=auto by default on text inputs
149159 if (
150160 ( elementName === 'input' || elementName === 'textarea' ) &&
151161 ! dirAttributeExists
@@ -155,6 +165,7 @@ module.exports = function ({ types: t }, options = {}) {
155165 ) ;
156166 }
157167
168+ // Inline the style resolving logic
158169 if ( ! styleAttributeExists ) {
159170 const elementName = path . node . name . property . name ;
160171 const defaultStyles = t . memberExpression (
@@ -164,10 +175,7 @@ module.exports = function ({ types: t }, options = {}) {
164175 path . node . attributes . push (
165176 t . jsxSpreadAttribute (
166177 t . callExpression (
167- t . memberExpression (
168- t . identifier ( stylexImportIdentifier . name ) ,
169- t . identifier ( 'props' )
170- ) ,
178+ t . identifier ( styleResolverImportIdentifier . name ) ,
171179 [ defaultStyles ]
172180 )
173181 )
@@ -195,7 +203,7 @@ module.exports = function ({ types: t }, options = {}) {
195203 // displays filename and line number of the source element
196204 path . node . attributes . unshift (
197205 t . jsxAttribute (
198- t . jsxIdentifier ( 'data-react -src' ) ,
206+ t . jsxIdentifier ( 'data-element -src' ) ,
199207 t . stringLiteral ( `${ shortFilename } :${ originalLineNumber } ` )
200208 )
201209 ) ;
@@ -204,4 +212,44 @@ module.exports = function ({ types: t }, options = {}) {
204212 }
205213 }
206214 } ;
215+ }
216+
217+ const defaultOptions = {
218+ dev : true ,
219+ debug : true ,
220+ rootDir : process . cwd ( )
207221} ;
222+
223+ function reactStrictPreset ( _ , options = { } ) {
224+ const opts = { ...defaultOptions , ...options } ;
225+
226+ return {
227+ plugins : [
228+ [
229+ reactStrictPlugin ,
230+ {
231+ debug : opts . debug
232+ }
233+ ] ,
234+ [
235+ styleXPlugin ,
236+ {
237+ dev : opts . dev ,
238+ importSources : [ { from : 'react-strict-dom' , as : 'css' } ] ,
239+ runtimeInjection : opts . dev , // temporary until Expo/Metro can support built-time
240+ styleResolution : 'property-specificity' ,
241+ unstable_moduleResolution : {
242+ type : 'commonJS' ,
243+ rootDir : opts . rootDir
244+ //themeFileExtension: '.cssvars.js',
245+ } ,
246+ useRemForFontSize : false
247+ }
248+ ]
249+ ]
250+ } ;
251+ }
252+
253+ reactStrictPreset . generateStyles = styleXPlugin . processStylexRules ;
254+
255+ module . exports = reactStrictPreset ;
0 commit comments