From eb1e4a24c84f19db7180687f324051fbaf66d4b2 Mon Sep 17 00:00:00 2001 From: Naman Goel Date: Wed, 4 Dec 2024 13:45:54 -0800 Subject: [PATCH 1/6] fix: add support for view-transition-name in ESLint valid-styles rule (#789) --- packages/eslint-plugin/src/stylex-valid-styles.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/eslint-plugin/src/stylex-valid-styles.js b/packages/eslint-plugin/src/stylex-valid-styles.js index a1bf0f71..2f36eddf 100644 --- a/packages/eslint-plugin/src/stylex-valid-styles.js +++ b/packages/eslint-plugin/src/stylex-valid-styles.js @@ -2185,6 +2185,7 @@ const CSSProperties = { unicodeBidi: unicodeBidi, unicodeRange: unicodeRange, userSelect: userSelect, + viewTransitionName: makeUnionRule(all, isString), verticalAlign: verticalAlign, visibility: visibility, voiceBalance: voiceBalance, From 30b530070b181aee74e8b785acc811a1a361d457 Mon Sep 17 00:00:00 2001 From: Samantha <40647818+Samantha-Zhan@users.noreply.github.com> Date: Wed, 4 Dec 2024 15:31:43 -0800 Subject: [PATCH 2/6] feat: dynamic styles set inherits to false (#794) * feat: dynamic styles set inherits to false * update tests --- .../evaluation/stylex-import-evaluation-test.js | 9 +++++++++ .../__tests__/stylex-transform-create-test.js | 13 +++++++++++++ .../src/visitors/stylex-create/index.js | 17 +++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/packages/babel-plugin/__tests__/evaluation/stylex-import-evaluation-test.js b/packages/babel-plugin/__tests__/evaluation/stylex-import-evaluation-test.js index 745bfb40..c7034ba5 100644 --- a/packages/babel-plugin/__tests__/evaluation/stylex-import-evaluation-test.js +++ b/packages/babel-plugin/__tests__/evaluation/stylex-import-evaluation-test.js @@ -369,6 +369,7 @@ describe('Evaluation of imported values works based on configuration', () => { import 'otherFile.stylex'; import { MyTheme } from 'otherFile.stylex'; _inject2(".__hashed_var__b69i2g{--__hashed_var__1jqb1tb:var(----__hashed_var__1jqb1tb)}", 1); + _inject2("@property ----__hashed_var__1jqb1tb { inherits: false }", 0); const styles = { color: color => [{ "--__hashed_var__1jqb1tb": color == null ? null : "__hashed_var__b69i2g", @@ -389,6 +390,14 @@ describe('Evaluation of imported values works based on configuration', () => { }, 1, ], + [ + "----__hashed_var__1jqb1tb", + { + "ltr": "@property ----__hashed_var__1jqb1tb { inherits: false }", + "rtl": null, + }, + 0, + ], ] `); }); diff --git a/packages/babel-plugin/__tests__/stylex-transform-create-test.js b/packages/babel-plugin/__tests__/stylex-transform-create-test.js index d60e3f06..985a3f0e 100644 --- a/packages/babel-plugin/__tests__/stylex-transform-create-test.js +++ b/packages/babel-plugin/__tests__/stylex-transform-create-test.js @@ -1323,6 +1323,7 @@ describe('@stylexjs/babel-plugin', () => { import stylex from 'stylex'; _inject2(".xrkmrrc{background-color:red}", 3000); _inject2(".xfx01vb{color:var(--color)}", 3000); + _inject2("@property --color { inherits: false }", 0); export const styles = { default: color => [{ backgroundColor: "xrkmrrc", @@ -1352,6 +1353,7 @@ describe('@stylexjs/babel-plugin', () => { import stylex from 'stylex'; _inject2(".xrkmrrc{background-color:red}", 3000); _inject2(".x1bl4301{width:var(--width)}", 4000); + _inject2("@property --width { inherits: false }", 0); export const styles = { default: width => [{ backgroundColor: "xrkmrrc", @@ -1385,6 +1387,7 @@ describe('@stylexjs/babel-plugin', () => { _inject2(".xrkmrrc{background-color:red}", 3000); _inject2(".xfx01vb{color:var(--color)}", 3000); _inject2(".x1mqxbix{color:black}", 3000); + _inject2("@property --color { inherits: false }", 0); export const styles = { default: color => [{ backgroundColor: "xrkmrrc", @@ -1416,6 +1419,7 @@ describe('@stylexjs/babel-plugin', () => { var _inject2 = _inject; import stylex from 'stylex'; _inject2(".x15mgraa{--background-color:var(----background-color)}", 1); + _inject2("@property ----background-color { inherits: false }", 0); export const styles = { default: bgColor => [{ "--background-color": bgColor == null ? null : "x15mgraa", @@ -1445,6 +1449,7 @@ describe('@stylexjs/babel-plugin', () => { import stylex from 'stylex'; _inject2(".x1gykpug:hover{background-color:red}", 3130); _inject2(".xtyu0qe:hover{color:var(--1ijzsae)}", 3130); + _inject2("@property --1ijzsae { inherits: false }", 0); export const styles = { default: color => [{ ":hover_backgroundColor": "x1gykpug", @@ -1477,6 +1482,7 @@ describe('@stylexjs/babel-plugin', () => { _inject2(".xrkmrrc{background-color:red}", 3000); _inject2(".xfx01vb{color:var(--color)}", 3000); _inject2(".x1mqxbix{color:black}", 3000); + _inject2("@property --color { inherits: false }", 0); export const styles = { default: color => [{ backgroundColor: "xrkmrrc", @@ -1508,6 +1514,7 @@ describe('@stylexjs/babel-plugin', () => { var _inject2 = _inject; import stylex from 'stylex'; _inject2(".x15mgraa{--background-color:var(----background-color)}", 1); + _inject2("@property ----background-color { inherits: false }", 0); export const styles = { default: bgColor => [{ "--background-color": bgColor == null ? null : "x15mgraa", @@ -1543,6 +1550,7 @@ describe('@stylexjs/babel-plugin', () => { _inject2(".x1n25116{color:var(--4xs81a)}", 3000); _inject2("@media (min-width: 1000px){.xtljkjt.xtljkjt:hover{color:green}}", 3330); _inject2(".x17z2mba:hover{color:blue}", 3130); + _inject2("@property --4xs81a { inherits: false }", 0); export const styles = { default: color => [{ backgroundColor: "xrkmrrc", @@ -1579,6 +1587,8 @@ describe('@stylexjs/babel-plugin', () => { _inject2(".x1n25116{color:var(--4xs81a)}", 3000); _inject2("@media (min-width: 1000px){.xtljkjt.xtljkjt:hover{color:green}}", 3330); _inject2(".x1d4gdy3:hover{color:var(--w5m4kq)}", 3130); + _inject2("@property --4xs81a { inherits: false }", 0); + _inject2("@property --w5m4kq { inherits: false }", 0); export const styles = { default: color => [{ backgroundColor: "xrkmrrc", @@ -1622,6 +1632,9 @@ describe('@stylexjs/babel-plugin', () => { _inject2(".x1k44ad6{margin-left:var(--14mfytm)}", 3000, ".x1k44ad6{margin-right:var(--14mfytm)}"); _inject2(".x10ktymb:hover{margin-left:var(--yepcm9)}", 3130, ".x10ktymb:hover{margin-right:var(--yepcm9)}"); _inject2(".x17zef60{margin-top:var(--marginTop)}", 4000); + _inject2("@property --14mfytm { inherits: false }", 0); + _inject2("@property --yepcm9 { inherits: false }", 0); + _inject2("@property --marginTop { inherits: false }", 0); export const styles = { default: margin => [{ backgroundColor: "xrkmrrc", diff --git a/packages/babel-plugin/src/visitors/stylex-create/index.js b/packages/babel-plugin/src/visitors/stylex-create/index.js index 4b8819bd..22fd1f2e 100644 --- a/packages/babel-plugin/src/visitors/stylex-create/index.js +++ b/packages/babel-plugin/src/visitors/stylex-create/index.js @@ -117,6 +117,22 @@ export default function transformStyleXCreate( throw path.buildCodeFrameError(messages.NON_STATIC_VALUE, SyntaxError); } const plainObject = value; + + // add injection that mark variables used for dynamic styles as `inherits: false` + const injectedInheritStyles: { [string]: InjectableStyle } = {}; + if (fns != null) { + const dynamicFnsNames = Object.values(fns) + ?.map((entry) => Object.keys(entry[1])) + .flat(); + dynamicFnsNames.forEach((fnsName) => { + injectedInheritStyles[fnsName] = { + priority: 0, + ltr: `@property ${fnsName} { inherits: false }`, + rtl: null, + }; + }); + } + // eslint-disable-next-line prefer-const let [compiledStyles, injectedStylesSansKeyframes, classPathsPerNamespace] = stylexCreate(plainObject, state.options); @@ -124,6 +140,7 @@ export default function transformStyleXCreate( const injectedStyles = { ...injectedKeyframes, ...injectedStylesSansKeyframes, + ...injectedInheritStyles, }; let varName = null; From 89d91e41d3844cc5375bfbd2b8962534fb3cb793 Mon Sep 17 00:00:00 2001 From: Naman Goel Date: Wed, 4 Dec 2024 15:34:05 -0800 Subject: [PATCH 3/6] fix: Use POSIX paths when inserting import statements (#795) --- packages/cli/src/files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/files.js b/packages/cli/src/files.js index 83f1c3c9..a714ed92 100644 --- a/packages/cli/src/files.js +++ b/packages/cli/src/files.js @@ -72,7 +72,7 @@ export function isJSFile(filePath: string): boolean { // e.g. ./pages/home/index.js -> ../../stylex_bundle.css export function getRelativePath(from: string, to: string): string { - const relativePath = path.relative(path.parse(from).dir, to); + const relativePath = path.posix.relative(path.parse(from).dir, to); return formatRelativePath(relativePath); } From 52e484656954c9ee80a909ab2d2dfa12c06894d5 Mon Sep 17 00:00:00 2001 From: melissa Date: Wed, 4 Dec 2024 19:38:20 -0800 Subject: [PATCH 4/6] [feat] add support for custom CLI cache path (#792) --- .../__tests__/compile-stylex-folder-test.js | 57 ++++++++++++++++++- packages/cli/src/config.js | 1 + packages/cli/src/transform.js | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/packages/cli/__tests__/compile-stylex-folder-test.js b/packages/cli/__tests__/compile-stylex-folder-test.js index 566c762a..aee94059 100644 --- a/packages/cli/__tests__/compile-stylex-folder-test.js +++ b/packages/cli/__tests__/compile-stylex-folder-test.js @@ -77,7 +77,7 @@ describe('compiling __mocks__/source to __mocks__/src correctly such that it mat }); test(config.output, async () => { - fs.mkdirSync(config.output); + fs.mkdirSync(config.output, { recursive: true }); expect(isDir(config.output)).toBe(true); await compileDirectory(config); const outputDir = fs.readdirSync(config.output, { recursive: true }); @@ -283,3 +283,58 @@ describe('cache mechanism works as expected', () => { writeSpy.mockRestore(); }); }); + +describe('CLI works with a custom cache path', () => { + const customCachePath = path.join(__dirname, '__custom_cache__'); + const config: TransformConfig = { + input: path.resolve('./source'), + output: path.resolve('./src'), + styleXBundleName: 'stylex_bundle.css', + modules_EXPERIMENTAL: [] as Array, + watch: false, + babelPresets: [], + cachePath: customCachePath, + state: { + compiledCSSDir: null, + compiledNodeModuleDir: null, + compiledJS: new Map(), + styleXRules: new Map(), + copiedNodeModules: false, + }, + }; + config.cachePath = customCachePath; + + beforeEach(() => { + if (fs.existsSync(customCachePath)) { + fs.rmSync(customCachePath, { recursive: true, force: true }); + } + }); + + afterAll(() => { + fs.rmSync(config.output, { recursive: true, force: true }); + if (fs.existsSync(customCachePath)) { + fs.rmSync(customCachePath, { recursive: true, force: true }); + } + }); + + test('uses the custom cache path for caching', async () => { + await compileDirectory(config); + + const customFilePath = path.join(config.input, 'index.js'); + + const cacheFilePath = path.join( + customCachePath, + path.relative(config.input, customFilePath) + '.json', + ); + + expect(fs.existsSync(customCachePath)).toBe(true); + expect(fs.existsSync(cacheFilePath)).toBe(true); + + const cacheData = JSON.parse(fs.readFileSync(cacheFilePath, 'utf-8')); + expect(cacheData).toHaveProperty('inputHash'); + expect(cacheData).toHaveProperty('outputHash'); + expect(cacheData).toHaveProperty('collectedCSS'); + + fs.rmSync(cacheFilePath, { recursive: true, force: true }); + }); +}); diff --git a/packages/cli/src/config.js b/packages/cli/src/config.js index ec46ba05..15ad9bd6 100644 --- a/packages/cli/src/config.js +++ b/packages/cli/src/config.js @@ -31,6 +31,7 @@ export type TransformConfig = { ...CliConfig, input: string, output: string, + cachePath?: string, state: { compiledCSSDir: ?string, compiledNodeModuleDir: ?string, diff --git a/packages/cli/src/transform.js b/packages/cli/src/transform.js index b4c73712..81757b98 100644 --- a/packages/cli/src/transform.js +++ b/packages/cli/src/transform.js @@ -100,7 +100,7 @@ export async function compileFile( ): Promise { const inputFilePath = path.join(config.input, filePath); const outputFilePath = path.join(config.output, filePath); - const cachePath = getDefaultCachePath(); + const cachePath = config.cachePath || getDefaultCachePath(); const inputHash = await computeHash(inputFilePath); let oldOutputHash = null; From 3e5a22932fc507f44701e2a14d9d42981b319685 Mon Sep 17 00:00:00 2001 From: Naman Goel Date: Thu, 5 Dec 2024 04:06:33 -0800 Subject: [PATCH 5/6] fix: Use POSIX paths when inserting import statements correctly this time (#797) --- packages/cli/src/files.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/files.js b/packages/cli/src/files.js index a714ed92..ffd5a9db 100644 --- a/packages/cli/src/files.js +++ b/packages/cli/src/files.js @@ -73,7 +73,11 @@ export function isJSFile(filePath: string): boolean { // e.g. ./pages/home/index.js -> ../../stylex_bundle.css export function getRelativePath(from: string, to: string): string { const relativePath = path.posix.relative(path.parse(from).dir, to); - return formatRelativePath(relativePath); + return formatRelativePath(toPosixPath(relativePath)); +} + +function toPosixPath(filePath: string): string { + return filePath.split(path.sep).join(path.posix.sep); } function formatRelativePath(filePath: string) { From c882412e548e6706be29deb727beaa3fc5e28839 Mon Sep 17 00:00:00 2001 From: Naman Goel Date: Thu, 5 Dec 2024 15:14:40 -0800 Subject: [PATCH 6/6] fix: do not use path.posix.relative (#801) * fix: do not use path.posix.relative * prettier --- packages/babel-plugin/src/visitors/stylex-create/index.js | 2 +- packages/cli/src/files.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/babel-plugin/src/visitors/stylex-create/index.js b/packages/babel-plugin/src/visitors/stylex-create/index.js index 22fd1f2e..a3511f61 100644 --- a/packages/babel-plugin/src/visitors/stylex-create/index.js +++ b/packages/babel-plugin/src/visitors/stylex-create/index.js @@ -132,7 +132,7 @@ export default function transformStyleXCreate( }; }); } - + // eslint-disable-next-line prefer-const let [compiledStyles, injectedStylesSansKeyframes, classPathsPerNamespace] = stylexCreate(plainObject, state.options); diff --git a/packages/cli/src/files.js b/packages/cli/src/files.js index ffd5a9db..97087022 100644 --- a/packages/cli/src/files.js +++ b/packages/cli/src/files.js @@ -72,7 +72,7 @@ export function isJSFile(filePath: string): boolean { // e.g. ./pages/home/index.js -> ../../stylex_bundle.css export function getRelativePath(from: string, to: string): string { - const relativePath = path.posix.relative(path.parse(from).dir, to); + const relativePath = path.relative(path.parse(from).dir, to); return formatRelativePath(toPosixPath(relativePath)); }