diff --git a/packages/babel-plugin/__tests__/stylex-transform-create-test.js b/packages/babel-plugin/__tests__/stylex-transform-create-test.js index 1f8fbeba..5d616cdf 100644 --- a/packages/babel-plugin/__tests__/stylex-transform-create-test.js +++ b/packages/babel-plugin/__tests__/stylex-transform-create-test.js @@ -36,6 +36,26 @@ function transform(source, opts = {}) { }).code; } +function transformTypescript(source, opts = {}) { + return transformSync(source, { + filename: opts.filename, + parserOpts: { + plugins: ['typescript'], + }, + babelrc: false, + plugins: [ + [ + stylexPlugin, + { + runtimeInjection: true, + unstable_moduleResolution: { type: 'haste' }, + ...opts, + }, + ], + ], + }).code; +} + describe('@stylexjs/babel-plugin', () => { describe('[transform] stylex.create()', () => { test('transforms style object', () => { @@ -1303,6 +1323,36 @@ describe('@stylexjs/babel-plugin', () => { };" `); }); + + test('typescript namespace transform', () => { + expect( + transformTypescript(` + import stylex from 'stylex'; + namespace A { + export const styles = stylex.create({ + default: { + color: 'red', + } + }) + } + stylex.props(A.styles); + `), + ).toMatchInlineSnapshot(` + "import _inject from "@stylexjs/stylex/lib/stylex-inject"; + var _inject2 = _inject; + import stylex from 'stylex'; + _inject2(".x1e2nbdu{color:red}", 3000); + namespace A { + export const styles = { + default: { + color: "x1e2nbdu", + $$css: true + } + }; + } + stylex.props(A.styles);" + `); + }); }); describe('[transform] stylex.create() with functions', () => { diff --git a/packages/babel-plugin/__tests__/stylex-transform-create-theme-test.js b/packages/babel-plugin/__tests__/stylex-transform-create-theme-test.js index a77f8190..020a2df4 100644 --- a/packages/babel-plugin/__tests__/stylex-transform-create-theme-test.js +++ b/packages/babel-plugin/__tests__/stylex-transform-create-theme-test.js @@ -35,6 +35,18 @@ function transform(source, opts = defaultOpts) { plugins: [[stylexPlugin, { ...defaultOpts, ...opts }]], }).code; } + +function transformTypescript(source, opts = {}) { + return transformSync(source, { + filename: opts.filename || '/stylex/packages/TestTheme.stylex.js', + parserOpts: { + plugins: ['typescript'], + }, + babelrc: false, + plugins: [[stylexPlugin, { ...defaultOpts, ...opts }]], + }).code; +} + let defineVarsOutput = ''; const createTheme = `{ @@ -692,4 +704,31 @@ describe('@stylexjs/babel-plugin stylex.createTheme with literals', () => { `); }); }); + + describe('[transform] typescript namespace', () => { + expect( + transformTypescript(` + import stylex from 'stylex'; + namespace A { + export const buttonTheme = stylex.defineVars(${createTheme}); + export const buttonThemePositive = stylex.createTheme(buttonTheme, ${createThemeWithDifferentOrder}); + } + `), + ).toMatchInlineSnapshot(` + "import stylex from 'stylex'; + namespace A { + export const buttonTheme = { + bgColor: "var(--xgck17p)", + bgColorDisabled: "var(--xpegid5)", + cornerRadius: "var(--xrqfjmn)", + fgColor: "var(--x4y59db)", + __themeName__: "x568ih9" + }; + export const buttonThemePositive = { + $$css: true, + x568ih9: "xtrlmmh x568ih9" + }; + }" + `); + }); }); diff --git a/packages/babel-plugin/__tests__/stylex-transform-define-vars-test.js b/packages/babel-plugin/__tests__/stylex-transform-define-vars-test.js index 1542b98d..5f0757c6 100644 --- a/packages/babel-plugin/__tests__/stylex-transform-define-vars-test.js +++ b/packages/babel-plugin/__tests__/stylex-transform-define-vars-test.js @@ -36,6 +36,17 @@ function transform(source, opts = defaultOpts) { }); } +function transformTypescript(source, opts = {}) { + return transformSync(source, { + filename: opts.filename || '/stylex/packages/TestTheme.stylex.js', + parserOpts: { + plugins: ['typescript'], + }, + babelrc: false, + plugins: [[stylexPlugin, { ...defaultOpts, ...opts }]], + }).code; +} + describe('@stylexjs/babel-plugin', () => { describe('[transform] stylex.defineVars()', () => { test('transforms variables object', () => { @@ -771,5 +782,34 @@ describe('@stylexjs/babel-plugin', () => { };" `); }); + + test('transform typescript namespace', () => { + expect( + transformTypescript( + ` + import stylex from 'stylex'; + namespace A { + export const buttonTheme = stylex.defineVars({ + bgColor: { + default: 'grey' + } + }) + } + `, + { dev: true, ...defaultOpts }, + ), + ).toMatchInlineSnapshot(` + "import _inject from "@stylexjs/stylex/lib/stylex-inject"; + var _inject2 = _inject; + import stylex from 'stylex'; + _inject2(":root, .x568ih9{--xgck17p:grey;}", 0); + namespace A { + export const buttonTheme = { + bgColor: "var(--xgck17p)", + __themeName__: "x568ih9" + }; + }" + `); + }); }); }); diff --git a/packages/babel-plugin/src/visitors/stylex-create/index.js b/packages/babel-plugin/src/visitors/stylex-create/index.js index 27713950..ba4caf73 100644 --- a/packages/babel-plugin/src/visitors/stylex-create/index.js +++ b/packages/babel-plugin/src/visitors/stylex-create/index.js @@ -343,7 +343,8 @@ function validateStyleXCreate(path: NodePath) { const nearestStatement = findNearestStatementAncestor(path); if ( !pathUtils.isProgram(nearestStatement.parentPath) && - !pathUtils.isExportNamedDeclaration(nearestStatement.parentPath) + !pathUtils.isExportNamedDeclaration(nearestStatement.parentPath) && + !pathUtils.isTSModuleBlock(nearestStatement.parentPath) ) { throw path.buildCodeFrameError(messages.ONLY_TOP_LEVEL, SyntaxError); }