From c49b8017facc562a33cd26d2af2fc57d4199a27a Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Fri, 31 Oct 2025 11:52:32 -0400 Subject: [PATCH 01/13] Add defineConsts tests --- .../perf/fixtures/sizes.stylex.consts.js | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 packages/benchmarks/perf/fixtures/sizes.stylex.consts.js diff --git a/packages/benchmarks/perf/fixtures/sizes.stylex.consts.js b/packages/benchmarks/perf/fixtures/sizes.stylex.consts.js new file mode 100644 index 000000000..eaed1df85 --- /dev/null +++ b/packages/benchmarks/perf/fixtures/sizes.stylex.consts.js @@ -0,0 +1,42 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import * as stylex from '@stylexjs/stylex'; + +const SemanticSizes = { + borderRadiusSmall: '0.25rem', + borderRadiusMedium: '0.5rem', + borderRadiusLarge: '0.75rem', + borderRadiusXLarge: '1rem', + paddingTiny: '0.25rem', + paddingSmall: '0.5rem', + paddingMedium: '1rem', + paddingLarge: '1.5rem', + paddingXLarge: '2rem', + marginTiny: '0.25rem', + marginSmall: '0.5rem', + marginMedium: '1rem', + marginLarge: '1.5rem', + marginXLarge: '2rem', + gapTiny: '0.25rem', + gapSmall: '0.5rem', + gapMedium: '1rem', + gapLarge: '1.5rem', + iconSizeSmall: '1rem', + iconSizeMedium: '1.5rem', + iconSizeLarge: '2rem', + buttonHeightSmall: '2rem', + buttonHeightMedium: '2.5rem', + buttonHeightLarge: '3rem', + inputHeightSmall: '2rem', + inputHeightMedium: '2.5rem', + inputHeightLarge: '3rem', + containerWidthSmall: '20rem', + containerWidthMedium: '40rem', + containerWidthLarge: '60rem', +}; + +export const sizes = stylex.defineConsts(SemanticSizes); From f71bfcd7065fc8af6f2cb8e4b28be1337ee8e485 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Fri, 31 Oct 2025 11:56:25 -0400 Subject: [PATCH 02/13] Add defineConsts to the benchmark --- .../perf/fixtures/sizes.stylex.consts.js | 42 ------------------- 1 file changed, 42 deletions(-) delete mode 100644 packages/benchmarks/perf/fixtures/sizes.stylex.consts.js diff --git a/packages/benchmarks/perf/fixtures/sizes.stylex.consts.js b/packages/benchmarks/perf/fixtures/sizes.stylex.consts.js deleted file mode 100644 index eaed1df85..000000000 --- a/packages/benchmarks/perf/fixtures/sizes.stylex.consts.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ -import * as stylex from '@stylexjs/stylex'; - -const SemanticSizes = { - borderRadiusSmall: '0.25rem', - borderRadiusMedium: '0.5rem', - borderRadiusLarge: '0.75rem', - borderRadiusXLarge: '1rem', - paddingTiny: '0.25rem', - paddingSmall: '0.5rem', - paddingMedium: '1rem', - paddingLarge: '1.5rem', - paddingXLarge: '2rem', - marginTiny: '0.25rem', - marginSmall: '0.5rem', - marginMedium: '1rem', - marginLarge: '1.5rem', - marginXLarge: '2rem', - gapTiny: '0.25rem', - gapSmall: '0.5rem', - gapMedium: '1rem', - gapLarge: '1.5rem', - iconSizeSmall: '1rem', - iconSizeMedium: '1.5rem', - iconSizeLarge: '2rem', - buttonHeightSmall: '2rem', - buttonHeightMedium: '2.5rem', - buttonHeightLarge: '3rem', - inputHeightSmall: '2rem', - inputHeightMedium: '2.5rem', - inputHeightLarge: '3rem', - containerWidthSmall: '20rem', - containerWidthMedium: '40rem', - containerWidthLarge: '60rem', -}; - -export const sizes = stylex.defineConsts(SemanticSizes); From 295758436db8c4d3cc618d773860bcf51dab2f35 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Mon, 27 Oct 2025 16:09:23 -0400 Subject: [PATCH 03/13] Nested consts --- .../__fixtures__/constants.stylex.js | 8 + .../transform-stylex-defineConsts-test.js | 245 ++++++++++++++++++ .../src/shared/stylex-consts-utils.js | 5 +- .../src/shared/stylex-define-consts.js | 64 +++-- .../babel-plugin/src/utils/evaluate-path.js | 70 +++-- 5 files changed, 347 insertions(+), 45 deletions(-) diff --git a/packages/@stylexjs/babel-plugin/__tests__/__fixtures__/constants.stylex.js b/packages/@stylexjs/babel-plugin/__tests__/__fixtures__/constants.stylex.js index e3efa0661..ea458e1d2 100644 --- a/packages/@stylexjs/babel-plugin/__tests__/__fixtures__/constants.stylex.js +++ b/packages/@stylexjs/babel-plugin/__tests__/__fixtures__/constants.stylex.js @@ -21,3 +21,11 @@ export const colors = stylex.defineConsts({ background: 'white', foreground: 'black', }); + +export const nestedTokens = stylex.defineConsts({ + button: { + fill: { + primary: 'blue', + }, + }, +}); diff --git a/packages/@stylexjs/babel-plugin/__tests__/transform-stylex-defineConsts-test.js b/packages/@stylexjs/babel-plugin/__tests__/transform-stylex-defineConsts-test.js index a6a121d84..8e2266a67 100644 --- a/packages/@stylexjs/babel-plugin/__tests__/transform-stylex-defineConsts-test.js +++ b/packages/@stylexjs/babel-plugin/__tests__/transform-stylex-defineConsts-test.js @@ -617,5 +617,250 @@ describe('@stylexjs/babel-plugin', () => { } `); }); + test('nested constants object', () => { + const { code, metadata } = transform(` + import * as stylex from '@stylexjs/stylex'; + export const tokens = stylex.defineConsts({ + button: { + fill: { + primary: 'blue', + secondary: 'gray', + }, + }, + }); + `); + + expect(code).toMatchInlineSnapshot(` + "import * as stylex from '@stylexjs/stylex'; + export const tokens = { + button: { + fill: { + primary: "blue", + secondary: "gray" + } + } + };" + `); + expect(metadata).toMatchInlineSnapshot(` + { + "stylex": [ + [ + "xreo3at", + { + "constKey": "xreo3at", + "constVal": "blue", + "ltr": "", + "rtl": null, + }, + 0, + ], + [ + "x3rbt3c", + { + "constKey": "x3rbt3c", + "constVal": "gray", + "ltr": "", + "rtl": null, + }, + 0, + ], + ], + } + `); + }); + + test('uses nested constants in stylex.create', () => { + const { code, metadata } = transformWithInlineConsts(` + import * as stylex from '@stylexjs/stylex'; + export const tokens = stylex.defineConsts({ + button: { + fill: { + primary: 'blue', + }, + }, + }); + export const styles = stylex.create({ + root: { + backgroundColor: tokens.button.fill.primary, + }, + }); + `); + + expect(code).toMatchInlineSnapshot(` + "import * as stylex from '@stylexjs/stylex'; + export const tokens = { + button: { + fill: { + primary: "blue" + } + } + }; + export const styles = { + root: { + kWkggS: "x1t391ir", + $$css: true + } + };" + `); + + // Verify const entry and CSS rule with inlined value + expect(metadata).toMatchInlineSnapshot(` + { + "stylex": [ + [ + "x1wyxh8f", + { + "constKey": "x1wyxh8f", + "constVal": "blue", + "ltr": "", + "rtl": null, + }, + 0, + ], + [ + "x1t391ir", + { + "ltr": ".x1t391ir{background-color:blue}", + "rtl": null, + }, + 3000, + ], + ], + } + `); + }); + + test('deeply nested constants', () => { + const { code, metadata } = transform(` + import * as stylex from '@stylexjs/stylex'; + export const tokens = stylex.defineConsts({ + level1: { + level2: { + level3: { + level4: 'deep-value', + }, + }, + }, + }); + `); + + expect(code).toMatchInlineSnapshot(` + "import * as stylex from '@stylexjs/stylex'; + export const tokens = { + level1: { + level2: { + level3: { + level4: "deep-value" + } + } + } + };" + `); + + expect(metadata).toMatchInlineSnapshot(` + { + "stylex": [ + [ + "x67bk05", + { + "constKey": "x67bk05", + "constVal": "deep-value", + "ltr": "", + "rtl": null, + }, + 0, + ], + ], + } + `); + }); + + test('mixed flat and nested constants', () => { + const { code, metadata } = transform(` + import * as stylex from '@stylexjs/stylex'; + export const tokens = stylex.defineConsts({ + flatColor: 'red', + nested: { + color: 'blue', + }, + }); + `); + + expect(code).toMatchInlineSnapshot(` + "import * as stylex from '@stylexjs/stylex'; + export const tokens = { + flatColor: "red", + nested: { + color: "blue" + } + };" + `); + expect(metadata).toMatchInlineSnapshot(` + { + "stylex": [ + [ + "x19gcf6u", + { + "constKey": "x19gcf6u", + "constVal": "red", + "ltr": "", + "rtl": null, + }, + 0, + ], + [ + "x49cdii", + { + "constKey": "x49cdii", + "constVal": "blue", + "ltr": "", + "rtl": null, + }, + 0, + ], + ], + } + `); + }); + + test('deep chained imported constants work in stylex.create', () => { + const { code, metadata } = transformWithInlineConsts(` + import * as stylex from '@stylexjs/stylex'; + import { nestedTokens } from './constants.stylex'; + export const styles = stylex.create({ + root: { + backgroundColor: nestedTokens.button.fill.primary, + }, + }); + `); + + expect(code).toMatchInlineSnapshot(` + "import * as stylex from '@stylexjs/stylex'; + import { nestedTokens } from './constants.stylex'; + export const styles = { + root: { + kWkggS: "x13bhmi6", + $$css: true + } + };" + `); + + // Should produce a style rule for backgroundColor referencing a CSS variable + // (The const entries themselves are in the metadata of constants.stylex, not this file) + expect(metadata).toMatchInlineSnapshot(` + { + "stylex": [ + [ + "x13bhmi6", + { + "ltr": ".x13bhmi6{background-color:var(--x529nz8)}", + "rtl": null, + }, + 3000, + ], + ], + } + `); + }); }); }); diff --git a/packages/@stylexjs/babel-plugin/src/shared/stylex-consts-utils.js b/packages/@stylexjs/babel-plugin/src/shared/stylex-consts-utils.js index 2138336b0..cc5436a25 100644 --- a/packages/@stylexjs/babel-plugin/src/shared/stylex-consts-utils.js +++ b/packages/@stylexjs/babel-plugin/src/shared/stylex-consts-utils.js @@ -7,7 +7,10 @@ * @flow strict */ -export type ConstsConfigValue = string | number; +export type ConstsConfigValue = + | string + | number + | { [string]: ConstsConfigValue }; export type ConstsConfig = $ReadOnly<{ [string]: ConstsConfigValue, diff --git a/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js b/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js index 13451bab8..55930564b 100644 --- a/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js +++ b/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js @@ -15,11 +15,13 @@ import * as messages from './messages'; import createHash from './hash'; +type ConstsOutput = string | number | { [string]: ConstsOutput }; + export default function styleXDefineConsts( constants: Vars, options: $ReadOnly<{ ...Partial, exportId: string, ... }>, ): [ - { [string]: string | number }, // jsOutput JS output + { [string]: ConstsOutput }, // jsOutput JS output { [string]: InjectableConstStyle }, // metadata for registerinjectableStyles ] { const { classNamePrefix, exportId, debug, enableDebugClassNames } = { @@ -27,31 +29,55 @@ export default function styleXDefineConsts( ...options, }; - const jsOutput: { [string]: string | number } = {}; + const jsOutput: { [string]: ConstsOutput } = {}; const injectableStyles: { [string]: InjectableConstStyle } = {}; + const processEntry = ( + key: string, + value: ConstsOutput, + path: Array, + ): ConstsOutput => { + if (typeof value === 'object' && value !== null) { + const nested: { [string]: ConstsOutput } = {}; + for (const [k, v] of Object.entries(value)) { + nested[k] = processEntry(k, v, [...path, k]); + } + return nested; + } + + if (typeof value === 'string' || typeof value === 'number') { + const fullPath = path.join('.'); + const varSafeKey = path + .map((segment) => + segment[0] >= '0' && segment[0] <= '9' ? `_${segment}` : segment, + ) + .join('_') + .replace(/[^a-zA-Z0-9]/g, '_'); + + const constKey = + debug && enableDebugClassNames + ? `${varSafeKey}-${classNamePrefix}${createHash(`${exportId}.${fullPath}`)}` + : `${classNamePrefix}${createHash(`${exportId}.${fullPath}`)}`; + + injectableStyles[constKey] = { + constKey, + constVal: value, + priority: 0, + ltr: '', + rtl: null, + }; + return value; + } + + return value; + }; + for (const [key, value] of Object.entries(constants)) { if (key.startsWith('--')) { throw new Error(messages.INVALID_CONST_KEY); } - const varSafeKey = ( - key[0] >= '0' && key[0] <= '9' ? `_${key}` : key - ).replace(/[^a-zA-Z0-9]/g, '_'); - - const constKey = - debug && enableDebugClassNames - ? `${varSafeKey}-${classNamePrefix}${createHash(`${exportId}.${key}`)}` - : `${classNamePrefix}${createHash(`${exportId}.${key}`)}`; - - jsOutput[key] = value; - injectableStyles[constKey] = { - constKey, - constVal: value, - priority: 0, - ltr: '', - rtl: null, - }; + jsOutput[key] = processEntry(key, value, [key]); } return [jsOutput, injectableStyles]; diff --git a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js index 0c347815c..11d047aae 100644 --- a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js +++ b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js @@ -31,7 +31,7 @@ import { utils } from '../shared'; import * as errMsgs from './evaluation-errors'; // This file contains Babels metainterpreter that can evaluate static code. - +const PROXY_MARKER = '__isProxy__'; const VALID_CALLEES = ['String', 'Number', 'Math', 'Object', 'Array']; const INVALID_METHODS = [ 'random', @@ -172,7 +172,11 @@ function evaluateThemeRef( const strToHash = key === '__varGroupHash__' ? utils.genFileBasedIdentifier({ fileName, exportName }) - : utils.genFileBasedIdentifier({ fileName, exportName, key }); + : utils.genFileBasedIdentifier({ + fileName, + exportName, + key, + }); const { debug, enableDebugClassNames } = state.traversalState.options; @@ -197,30 +201,32 @@ function evaluateThemeRef( return `var(--${varName})`; }; - // A JS proxy that uses the key to generate a string value using the `resolveKey` function - const proxy = new Proxy( - {}, - { - get(_, key: string) { - if (key === '__IS_PROXY') { - return true; - } - if (key === 'toString') { - return () => - state.traversalState.options.classNamePrefix + - utils.hash(utils.genFileBasedIdentifier({ fileName, exportName })); - } - return resolveKey(key); - }, - set(_, key: string, value: string) { - throw new Error( - `Cannot set value ${value} to key ${key} in theme ${fileName}`, - ); + const createNestedProxy = (currentPath: Array = []): any => { + return new Proxy( + {}, + { + get(_, key: string) { + if (key === PROXY_MARKER) { + return true; + } + + if (key === 'valueOf' || key === 'toString') { + return () => resolveKey(currentPath.join('.')); + } + + const newPath = [...currentPath, key]; + return createNestedProxy(newPath); + }, + set(_, key: string, value: string) { + throw new Error( + `Cannot set value ${value} to key ${[...currentPath, key].join('.')} in theme ${fileName}`, + ); + }, }, - }, - ); + ); + }; - return proxy; + return createNestedProxy(); } /** @@ -398,7 +404,21 @@ function _evaluate(path: NodePath<>, state: State): any { return deopt(propPath, state, errMsgs.UNEXPECTED_MEMBER_LOOKUP); } - return object[property]; + const result = object[property]; + + // handle nested member expression + const parent = path.parentPath; + + const isChainedAccess = + parent != null && + parent.isMemberExpression() && + parent.get('object').node === path.node; + + if (result?.[PROXY_MARKER] && !isChainedAccess) { + return result.valueOf(); + } + + return result; } if (path.isReferencedIdentifier()) { From 6f76bef8792cdd621c91cd6b48979a008e409a83 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Mon, 27 Oct 2025 16:13:20 -0400 Subject: [PATCH 04/13] Update types, tests, use a symbol --- .../@stylexjs/babel-plugin/src/utils/evaluate-path.js | 5 +++-- packages/@stylexjs/stylex/src/types/StyleXTypes.d.ts | 8 +++----- packages/@stylexjs/stylex/src/types/StyleXTypes.js | 6 +++--- packages/typescript-tests/src/typetests.ts | 4 ++++ 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js index 11d047aae..81366c9d7 100644 --- a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js +++ b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js @@ -31,7 +31,6 @@ import { utils } from '../shared'; import * as errMsgs from './evaluation-errors'; // This file contains Babels metainterpreter that can evaluate static code. -const PROXY_MARKER = '__isProxy__'; const VALID_CALLEES = ['String', 'Number', 'Math', 'Object', 'Array']; const INVALID_METHODS = [ 'random', @@ -42,6 +41,7 @@ const INVALID_METHODS = [ 'seal', 'splice', ]; +const PROXY_MARKER = Symbol('StyleXProxyMarker'); function isValidCallee(val: string): boolean { return (VALID_CALLEES as $ReadOnlyArray).includes(val); @@ -406,7 +406,8 @@ function _evaluate(path: NodePath<>, state: State): any { const result = object[property]; - // handle nested member expression + // handle nested member expressions by converting proxy to + // its primitive value for the terminal access of this MemberExpression const parent = path.parentPath; const isChainedAccess = diff --git a/packages/@stylexjs/stylex/src/types/StyleXTypes.d.ts b/packages/@stylexjs/stylex/src/types/StyleXTypes.d.ts index a3af27b8e..6deee7fbf 100644 --- a/packages/@stylexjs/stylex/src/types/StyleXTypes.d.ts +++ b/packages/@stylexjs/stylex/src/types/StyleXTypes.d.ts @@ -268,11 +268,9 @@ type NestedVarObject = [key: AtRuleStr]: NestedVarObject; }>; -export type StyleX$DefineConsts = < - DefaultTokens extends { - [key: string]: number | string; - }, ->( +type DefineConstTokens = string | number | { [string]: DefineConstTokens }; + +export type StyleX$DefineConsts = ( tokens: DefaultTokens, ) => DefaultTokens; diff --git a/packages/@stylexjs/stylex/src/types/StyleXTypes.js b/packages/@stylexjs/stylex/src/types/StyleXTypes.js index 99898e2d6..b442b5121 100644 --- a/packages/@stylexjs/stylex/src/types/StyleXTypes.js +++ b/packages/@stylexjs/stylex/src/types/StyleXTypes.js @@ -225,9 +225,9 @@ export type StyleX$DefineVars = ( tokens: DefaultTokens, ) => VarGroup, ID>; -export type StyleX$DefineConsts = < - const DefaultTokens: { +[string]: number | string }, ->( +type DefineConstTokens = string | number | { +[string]: DefineConstTokens }; + +export type StyleX$DefineConsts = ( tokens: DefaultTokens, ) => DefaultTokens; diff --git a/packages/typescript-tests/src/typetests.ts b/packages/typescript-tests/src/typetests.ts index cb0e9e43a..0b6a0c282 100644 --- a/packages/typescript-tests/src/typetests.ts +++ b/packages/typescript-tests/src/typetests.ts @@ -300,7 +300,11 @@ stylex.props(styles8.foo); const consts = stylex.defineConsts({ foo: 'bar', bar: 123, + baz: { + qux: 'quux', + }, } as const); consts.foo satisfies 'bar'; consts.bar satisfies 123; +consts.baz satisfies { qux: 'quux' }; From f1a649c0ea9d5e7fd22f1df89860a46062f2d043 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Mon, 27 Oct 2025 17:11:23 -0400 Subject: [PATCH 05/13] comment --- packages/@stylexjs/stylex/src/stylex.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/@stylexjs/stylex/src/stylex.js b/packages/@stylexjs/stylex/src/stylex.js index ff5185734..feaf5a80c 100644 --- a/packages/@stylexjs/stylex/src/stylex.js +++ b/packages/@stylexjs/stylex/src/stylex.js @@ -72,8 +72,10 @@ export const createTheme: StyleX$CreateTheme = (_baseTokens, _overrides) => { throw errorForFn('createTheme'); }; +type DefineConstsTokens = string | number | { +[string]: DefineConstsTokens }; + export const defineConsts: StyleX$DefineConsts = function stylexDefineConsts< - const T: { +[string]: number | string }, + T: DefineConstsTokens, >(_styles: T): T { throw errorForFn('defineConsts'); }; From 732aabe07c0e79fc02cb91ecfb81bd829aef841d Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Mon, 27 Oct 2025 17:25:33 -0400 Subject: [PATCH 06/13] Small MDX update --- packages/docs/docs/api/javascript/defineConsts.mdx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/docs/docs/api/javascript/defineConsts.mdx b/packages/docs/docs/api/javascript/defineConsts.mdx index 812c7c0d7..dde3b8e87 100644 --- a/packages/docs/docs/api/javascript/defineConsts.mdx +++ b/packages/docs/docs/api/javascript/defineConsts.mdx @@ -45,7 +45,10 @@ export const zIndices = stylex.defineConsts({ export const animations = stylex.defineConsts({ easeInOut: 'cubic-bezier(0.4, 0, 0.2, 1)', - fast: '150ms', + speed: { + slow: '300ms', + fast: '150ms', + } }); ``` @@ -60,7 +63,7 @@ const styles = stylex.create({ position: 'relative', zIndex: zIndices.modal, transitionTimingFunction: animations.easeInOut, - transitionDuration: animations.fast, + transitionDuration: animations.speed.fast, color: { default: 'black', [breakpoints.small]: 'red', From cccf3e4dbd03d475e1c7464e38d295d94f265294 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Mon, 27 Oct 2025 17:44:12 -0400 Subject: [PATCH 07/13] Undo formatting change --- packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js index 81366c9d7..03ecebea9 100644 --- a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js +++ b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js @@ -172,11 +172,7 @@ function evaluateThemeRef( const strToHash = key === '__varGroupHash__' ? utils.genFileBasedIdentifier({ fileName, exportName }) - : utils.genFileBasedIdentifier({ - fileName, - exportName, - key, - }); + : utils.genFileBasedIdentifier({ fileName, exportName, key }); const { debug, enableDebugClassNames } = state.traversalState.options; From fe90627d7bae159fe4711091bfd3c848fb6b68da Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Wed, 29 Oct 2025 16:30:39 -0400 Subject: [PATCH 08/13] fix flow types --- .../@stylexjs/babel-plugin/src/shared/stylex-define-consts.js | 2 +- packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js b/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js index 55930564b..a4bd437e2 100644 --- a/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js +++ b/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js @@ -37,7 +37,7 @@ export default function styleXDefineConsts( value: ConstsOutput, path: Array, ): ConstsOutput => { - if (typeof value === 'object' && value !== null) { + if (typeof value === 'object' && value != null) { const nested: { [string]: ConstsOutput } = {}; for (const [k, v] of Object.entries(value)) { nested[k] = processEntry(k, v, [...path, k]); diff --git a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js index 03ecebea9..3d432ecdc 100644 --- a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js +++ b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js @@ -197,11 +197,11 @@ function evaluateThemeRef( return `var(--${varName})`; }; - const createNestedProxy = (currentPath: Array = []): any => { + const createNestedProxy = (currentPath: Array = []): any => { return new Proxy( {}, { - get(_, key: string) { + get(_, key: string | symbol) { if (key === PROXY_MARKER) { return true; } From a47d513e4d873fa16b1e36c8ee1bbec56de90985 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Thu, 30 Oct 2025 13:11:20 -0400 Subject: [PATCH 09/13] Evaluate the full path while walking the AST --- .../babel-plugin/src/utils/evaluate-path.js | 121 ++++++++++++------ 1 file changed, 82 insertions(+), 39 deletions(-) diff --git a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js index 3d432ecdc..112f4f2c0 100644 --- a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js +++ b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js @@ -41,8 +41,47 @@ const INVALID_METHODS = [ 'seal', 'splice', ]; + const PROXY_MARKER = Symbol('StyleXProxyMarker'); +function getFullMemberPath(path: NodePath) { + const parts: Array = []; + let current = path; + + while (current.isMemberExpression()) { + const prop = current.get('property'); + if (prop.isIdentifier()) { + parts.unshift(prop.node.name); + } else if (prop.isStringLiteral()) { + parts.unshift(prop.node.value); + } else if (current.node.computed) { + return null; + } + current = current.get('object'); + } + + return { + parts, + baseObject: current, + }; +} + +function getOuterMostMemberExpression(path: NodePath<>): NodePath<> { + let current = path; + while (current.parentPath) { + const parent = current.parentPath; + if ( + parent.isMemberExpression() && + parent.get('object').node === current.node + ) { + current = parent; + } else { + break; + } + } + return current; +} + function isValidCallee(val: string): boolean { return (VALID_CALLEES as $ReadOnlyArray).includes(val); } @@ -197,32 +236,32 @@ function evaluateThemeRef( return `var(--${varName})`; }; - const createNestedProxy = (currentPath: Array = []): any => { - return new Proxy( - {}, - { - get(_, key: string | symbol) { - if (key === PROXY_MARKER) { - return true; - } - - if (key === 'valueOf' || key === 'toString') { - return () => resolveKey(currentPath.join('.')); - } + // A JS proxy that uses the key to generate a string value using the `resolveKey` function + const proxy = new Proxy( + {}, + { + get(_, key: string) { + if ((key as any) === PROXY_MARKER) { + return true; + } + // for flattened member access, keys are converted to `a.b.c.d` with a __nested__ prefix + // prefixing avoids conflicts with literal keys that contain dots + if (key.startsWith('__nested__')) { + const actualKey = key.slice('__nested__'.length); + return resolveKey(actualKey); + } - const newPath = [...currentPath, key]; - return createNestedProxy(newPath); - }, - set(_, key: string, value: string) { - throw new Error( - `Cannot set value ${value} to key ${[...currentPath, key].join('.')} in theme ${fileName}`, - ); - }, + return resolveKey(key); }, - ); - }; + set(_, key: string, value: string) { + throw new Error( + `Cannot set value ${value} to key ${key} in theme ${fileName}`, + ); + }, + }, + ); - return createNestedProxy(); + return proxy; } /** @@ -379,6 +418,25 @@ function _evaluate(path: NodePath<>, state: State): any { path.isMemberExpression() && !path.parentPath.isCallExpression({ callee: path.node }) ) { + const outerMost = getOuterMostMemberExpression(path); + + // to handle nested member expressions, we wait until we are at the outer most member expression + // and then we can extract the full path and evaluate it via the object proxy + if (outerMost === path) { + const pathInfo = getFullMemberPath(path); + + if (pathInfo != null && pathInfo.parts.length > 0) { + const baseObject = evaluateCached(pathInfo.baseObject, state); + if (!state.confident) { + return; + } + + if (baseObject[PROXY_MARKER]) { + return baseObject[`__nested__${pathInfo.parts.join('.')}`]; + } + } + } + const object = evaluateCached(path.get('object'), state); if (!state.confident) { return; @@ -400,22 +458,7 @@ function _evaluate(path: NodePath<>, state: State): any { return deopt(propPath, state, errMsgs.UNEXPECTED_MEMBER_LOOKUP); } - const result = object[property]; - - // handle nested member expressions by converting proxy to - // its primitive value for the terminal access of this MemberExpression - const parent = path.parentPath; - - const isChainedAccess = - parent != null && - parent.isMemberExpression() && - parent.get('object').node === path.node; - - if (result?.[PROXY_MARKER] && !isChainedAccess) { - return result.valueOf(); - } - - return result; + return object[property]; } if (path.isReferencedIdentifier()) { From a359ce009be39268c5fb73780a8b265090722647 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Thu, 30 Oct 2025 14:06:31 -0400 Subject: [PATCH 10/13] Conflicts should just error --- .../__tests__/__fixtures__/constants.stylex.js | 1 + .../transform-stylex-defineConsts-test.js | 18 ++++++++++++++++++ .../src/shared/stylex-define-consts.js | 9 +++++++++ .../babel-plugin/src/utils/evaluate-path.js | 8 +------- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/@stylexjs/babel-plugin/__tests__/__fixtures__/constants.stylex.js b/packages/@stylexjs/babel-plugin/__tests__/__fixtures__/constants.stylex.js index ea458e1d2..da0a683ef 100644 --- a/packages/@stylexjs/babel-plugin/__tests__/__fixtures__/constants.stylex.js +++ b/packages/@stylexjs/babel-plugin/__tests__/__fixtures__/constants.stylex.js @@ -28,4 +28,5 @@ export const nestedTokens = stylex.defineConsts({ primary: 'blue', }, }, + 'button.fill.primary': 'red', }); diff --git a/packages/@stylexjs/babel-plugin/__tests__/transform-stylex-defineConsts-test.js b/packages/@stylexjs/babel-plugin/__tests__/transform-stylex-defineConsts-test.js index 8e2266a67..b2be5b6c0 100644 --- a/packages/@stylexjs/babel-plugin/__tests__/transform-stylex-defineConsts-test.js +++ b/packages/@stylexjs/babel-plugin/__tests__/transform-stylex-defineConsts-test.js @@ -862,5 +862,23 @@ describe('@stylexjs/babel-plugin', () => { } `); }); + + test('conflicting nested and flat constant names throws error', () => { + expect(() => { + transform(` + import * as stylex from '@stylexjs/stylex'; + export const tokens = stylex.defineConsts({ + button: { + fill: { + primary: 'blue', + }, + }, + 'button.fill.primary': 'red', + }); + `); + }).toThrow( + /Conflicting constant paths detected: "button\.fill\.primary"/, + ); + }); }); }); diff --git a/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js b/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js index a4bd437e2..de1bd7f82 100644 --- a/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js +++ b/packages/@stylexjs/babel-plugin/src/shared/stylex-define-consts.js @@ -31,6 +31,7 @@ export default function styleXDefineConsts( const jsOutput: { [string]: ConstsOutput } = {}; const injectableStyles: { [string]: InjectableConstStyle } = {}; + const seenPaths: Set = new Set(); const processEntry = ( key: string, @@ -47,6 +48,14 @@ export default function styleXDefineConsts( if (typeof value === 'string' || typeof value === 'number') { const fullPath = path.join('.'); + + if (seenPaths.has(fullPath)) { + throw new Error( + `Conflicting constant paths detected: "${fullPath}". This can happen when you have both nested properties (e.g., {a: {b: 'value'}}) and a literal dotted key (e.g., {'a.b': 'value'}) that resolve to the same path.`, + ); + } + seenPaths.add(fullPath); + const varSafeKey = path .map((segment) => segment[0] >= '0' && segment[0] <= '9' ? `_${segment}` : segment, diff --git a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js index 112f4f2c0..22560ada0 100644 --- a/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js +++ b/packages/@stylexjs/babel-plugin/src/utils/evaluate-path.js @@ -244,12 +244,6 @@ function evaluateThemeRef( if ((key as any) === PROXY_MARKER) { return true; } - // for flattened member access, keys are converted to `a.b.c.d` with a __nested__ prefix - // prefixing avoids conflicts with literal keys that contain dots - if (key.startsWith('__nested__')) { - const actualKey = key.slice('__nested__'.length); - return resolveKey(actualKey); - } return resolveKey(key); }, @@ -432,7 +426,7 @@ function _evaluate(path: NodePath<>, state: State): any { } if (baseObject[PROXY_MARKER]) { - return baseObject[`__nested__${pathInfo.parts.join('.')}`]; + return baseObject[pathInfo.parts.join('.')]; } } } From 286ca2a367f2920e230c47eb5342ddb6ad0bcc54 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Fri, 31 Oct 2025 12:19:13 -0400 Subject: [PATCH 11/13] Nesting benchmark --- .../perf/fixtures/create-complex.js | 228 +++++++++++++++++- .../benchmarks/perf/fixtures/sizes.stylex.js | 61 +++++ 2 files changed, 277 insertions(+), 12 deletions(-) diff --git a/packages/benchmarks/perf/fixtures/create-complex.js b/packages/benchmarks/perf/fixtures/create-complex.js index 0866e953f..fb0227c0e 100644 --- a/packages/benchmarks/perf/fixtures/create-complex.js +++ b/packages/benchmarks/perf/fixtures/create-complex.js @@ -6,7 +6,7 @@ */ import * as stylex from '@stylexjs/stylex'; -import { sizes } from './sizes.stylex'; +import { sizes, spacing } from './sizes.stylex'; export const styles = stylex.create({ root: { @@ -122,19 +122,223 @@ export const styles = stylex.create({ }, }, panel: { - borderRadius: sizes.borderRadiusLarge, - gap: sizes.gapMedium, - margin: sizes.marginLarge, - padding: sizes.paddingLarge, - paddingBlock: sizes.paddingMedium, - paddingInline: sizes.paddingLarge, + borderRadius: spacing.border.radius.large, + gap: spacing.gap.medium, + margin: spacing.margin.large, + padding: spacing.padding.large, + paddingBlock: spacing.padding.medium, + paddingInline: spacing.padding.large, }, panelHeader: { - borderRadius: sizes.borderRadiusMedium, - gap: sizes.gapSmall, - margin: sizes.marginSmall, - marginBlockEnd: sizes.marginMedium, - padding: sizes.paddingMedium, + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.small, + margin: spacing.margin.small, + marginBlockEnd: spacing.margin.medium, + padding: spacing.padding.medium, + }, + panelBody: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.medium, + margin: spacing.margin.small, + padding: spacing.padding.medium, + }, + panelFooter: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.small, + margin: spacing.margin.small, + marginBlockStart: spacing.margin.medium, + padding: spacing.padding.medium, + }, + card: { + borderRadius: spacing.border.radius.large, + gap: spacing.gap.medium, + margin: spacing.margin.medium, + padding: spacing.padding.large, + paddingBlock: spacing.padding.medium, + paddingInline: spacing.padding.large, + }, + cardSmall: { + borderRadius: spacing.border.radius.small, + gap: spacing.gap.small, + margin: spacing.margin.small, + padding: spacing.padding.small, + paddingBlock: spacing.padding.tiny, + paddingInline: spacing.padding.medium, + }, + cardLarge: { + borderRadius: spacing.border.radius.xLarge, + gap: spacing.gap.large, + margin: spacing.margin.large, + padding: spacing.padding.xLarge, + paddingBlock: spacing.padding.large, + paddingInline: spacing.padding.xLarge, + }, + icon: { + height: spacing.icon.size.medium, + margin: spacing.margin.tiny, + width: spacing.icon.size.medium, + }, + iconSmall: { + height: spacing.icon.size.small, + margin: spacing.margin.tiny, + width: spacing.icon.size.small, + }, + iconLarge: { + height: spacing.icon.size.large, + margin: spacing.margin.small, + width: spacing.icon.size.large, + }, + input: { + borderRadius: spacing.border.radius.medium, + height: spacing.input.height.medium, + margin: spacing.margin.small, + padding: spacing.padding.small, + paddingBlock: spacing.padding.tiny, + paddingInline: spacing.padding.medium, + }, + inputSmall: { + borderRadius: spacing.border.radius.small, + height: spacing.input.height.small, + margin: spacing.margin.tiny, + padding: spacing.padding.tiny, + paddingBlock: spacing.padding.tiny, + paddingInline: spacing.padding.small, + }, + inputLarge: { + borderRadius: spacing.border.radius.large, + height: spacing.input.height.large, + margin: spacing.margin.medium, + padding: spacing.padding.medium, + paddingBlock: spacing.padding.small, + paddingInline: spacing.padding.large, + }, + container: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.small, + margin: spacing.margin.medium, + padding: spacing.padding.medium, + width: spacing.container.width.medium, + }, + containerSmall: { + borderRadius: spacing.border.radius.small, + gap: spacing.gap.tiny, + margin: spacing.margin.small, + padding: spacing.padding.small, + width: spacing.container.width.small, + }, + containerLarge: { + borderRadius: spacing.border.radius.xLarge, + gap: spacing.gap.large, + margin: spacing.margin.xLarge, + padding: spacing.padding.xLarge, + width: spacing.container.width.large, + }, + badge: { + borderRadius: spacing.border.radius.small, + gap: spacing.gap.tiny, + margin: spacing.margin.tiny, + padding: spacing.padding.tiny, + paddingBlock: spacing.padding.tiny, + paddingInline: spacing.padding.small, + }, + modal: { + borderRadius: spacing.border.radius.xLarge, + gap: spacing.gap.large, + margin: spacing.margin.xLarge, + padding: spacing.padding.xLarge, + paddingBlock: spacing.padding.large, + paddingInline: spacing.padding.xLarge, + }, + dropdown: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.small, + margin: spacing.margin.small, + padding: spacing.padding.small, + }, + dropdownItem: { + borderRadius: spacing.border.radius.small, + gap: spacing.gap.tiny, + margin: spacing.margin.tiny, + padding: spacing.padding.tiny, + paddingBlock: spacing.padding.tiny, + paddingInline: spacing.padding.small, + }, + tooltip: { + borderRadius: spacing.border.radius.small, + margin: spacing.margin.tiny, + padding: spacing.padding.tiny, + paddingBlock: spacing.padding.tiny, + paddingInline: spacing.padding.small, + }, + nav: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.medium, + margin: spacing.margin.medium, + padding: spacing.padding.medium, + }, + navItem: { + borderRadius: spacing.border.radius.small, + gap: spacing.gap.small, + margin: spacing.margin.small, + padding: spacing.padding.small, + paddingBlock: spacing.padding.tiny, + paddingInline: spacing.padding.medium, + }, + grid: { + gap: spacing.gap.large, + margin: spacing.margin.large, + padding: spacing.padding.large, + }, + gridItem: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.small, + margin: spacing.margin.small, + padding: spacing.padding.medium, + }, + stack: { + gap: spacing.gap.medium, + margin: spacing.margin.medium, + padding: spacing.padding.medium, + }, + stackItem: { + borderRadius: spacing.border.radius.small, + gap: spacing.gap.tiny, + margin: spacing.margin.tiny, + padding: spacing.padding.small, + }, + sidebar: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.medium, + margin: spacing.margin.medium, + padding: spacing.padding.large, + paddingBlock: spacing.padding.medium, + paddingInline: spacing.padding.large, + }, + sidebarItem: { + borderRadius: spacing.border.radius.small, + gap: spacing.gap.small, + margin: spacing.margin.tiny, + padding: spacing.padding.small, + paddingBlock: spacing.padding.tiny, + paddingInline: spacing.padding.medium, + }, + header: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.medium, + margin: spacing.margin.medium, + marginBlockEnd: spacing.margin.large, + padding: spacing.padding.large, + paddingBlock: spacing.padding.medium, + paddingInline: spacing.padding.large, + }, + footer: { + borderRadius: spacing.border.radius.medium, + gap: spacing.gap.medium, + margin: spacing.margin.medium, + marginBlockStart: spacing.margin.large, + padding: spacing.padding.large, + paddingBlock: spacing.padding.medium, + paddingInline: spacing.padding.large, }, dynamicHeight: (height) => ({ height }), dynamicPadding: (paddingTop, paddingBottom) => ({ diff --git a/packages/benchmarks/perf/fixtures/sizes.stylex.js b/packages/benchmarks/perf/fixtures/sizes.stylex.js index eaed1df85..446c86006 100644 --- a/packages/benchmarks/perf/fixtures/sizes.stylex.js +++ b/packages/benchmarks/perf/fixtures/sizes.stylex.js @@ -40,3 +40,64 @@ const SemanticSizes = { }; export const sizes = stylex.defineConsts(SemanticSizes); + +const SpacingTokens = { + border: { + radius: { + small: '0.25rem', + medium: '0.5rem', + large: '0.75rem', + xLarge: '1rem', + }, + }, + padding: { + tiny: '0.25rem', + small: '0.5rem', + medium: '1rem', + large: '1.5rem', + xLarge: '2rem', + }, + margin: { + tiny: '0.25rem', + small: '0.5rem', + medium: '1rem', + large: '1.5rem', + xLarge: '2rem', + }, + gap: { + tiny: '0.25rem', + small: '0.5rem', + medium: '1rem', + large: '1.5rem', + }, + icon: { + size: { + small: '1rem', + medium: '1.5rem', + large: '2rem', + }, + }, + button: { + height: { + small: '2rem', + medium: '2.5rem', + large: '3rem', + }, + }, + input: { + height: { + small: '2rem', + medium: '2.5rem', + large: '3rem', + }, + }, + container: { + width: { + small: '20rem', + medium: '40rem', + large: '60rem', + }, + }, +}; + +export const spacing = stylex.defineConsts(SpacingTokens); From 22ae11c8228d34e4decaa4c8e0004ed5c77850fe Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Wed, 5 Nov 2025 13:35:03 -0500 Subject: [PATCH 12/13] way less --- .../perf/fixtures/create-complex.js | 191 ------------------ 1 file changed, 191 deletions(-) diff --git a/packages/benchmarks/perf/fixtures/create-complex.js b/packages/benchmarks/perf/fixtures/create-complex.js index fb0227c0e..79c862aac 100644 --- a/packages/benchmarks/perf/fixtures/create-complex.js +++ b/packages/benchmarks/perf/fixtures/create-complex.js @@ -149,197 +149,6 @@ export const styles = stylex.create({ marginBlockStart: spacing.margin.medium, padding: spacing.padding.medium, }, - card: { - borderRadius: spacing.border.radius.large, - gap: spacing.gap.medium, - margin: spacing.margin.medium, - padding: spacing.padding.large, - paddingBlock: spacing.padding.medium, - paddingInline: spacing.padding.large, - }, - cardSmall: { - borderRadius: spacing.border.radius.small, - gap: spacing.gap.small, - margin: spacing.margin.small, - padding: spacing.padding.small, - paddingBlock: spacing.padding.tiny, - paddingInline: spacing.padding.medium, - }, - cardLarge: { - borderRadius: spacing.border.radius.xLarge, - gap: spacing.gap.large, - margin: spacing.margin.large, - padding: spacing.padding.xLarge, - paddingBlock: spacing.padding.large, - paddingInline: spacing.padding.xLarge, - }, - icon: { - height: spacing.icon.size.medium, - margin: spacing.margin.tiny, - width: spacing.icon.size.medium, - }, - iconSmall: { - height: spacing.icon.size.small, - margin: spacing.margin.tiny, - width: spacing.icon.size.small, - }, - iconLarge: { - height: spacing.icon.size.large, - margin: spacing.margin.small, - width: spacing.icon.size.large, - }, - input: { - borderRadius: spacing.border.radius.medium, - height: spacing.input.height.medium, - margin: spacing.margin.small, - padding: spacing.padding.small, - paddingBlock: spacing.padding.tiny, - paddingInline: spacing.padding.medium, - }, - inputSmall: { - borderRadius: spacing.border.radius.small, - height: spacing.input.height.small, - margin: spacing.margin.tiny, - padding: spacing.padding.tiny, - paddingBlock: spacing.padding.tiny, - paddingInline: spacing.padding.small, - }, - inputLarge: { - borderRadius: spacing.border.radius.large, - height: spacing.input.height.large, - margin: spacing.margin.medium, - padding: spacing.padding.medium, - paddingBlock: spacing.padding.small, - paddingInline: spacing.padding.large, - }, - container: { - borderRadius: spacing.border.radius.medium, - gap: spacing.gap.small, - margin: spacing.margin.medium, - padding: spacing.padding.medium, - width: spacing.container.width.medium, - }, - containerSmall: { - borderRadius: spacing.border.radius.small, - gap: spacing.gap.tiny, - margin: spacing.margin.small, - padding: spacing.padding.small, - width: spacing.container.width.small, - }, - containerLarge: { - borderRadius: spacing.border.radius.xLarge, - gap: spacing.gap.large, - margin: spacing.margin.xLarge, - padding: spacing.padding.xLarge, - width: spacing.container.width.large, - }, - badge: { - borderRadius: spacing.border.radius.small, - gap: spacing.gap.tiny, - margin: spacing.margin.tiny, - padding: spacing.padding.tiny, - paddingBlock: spacing.padding.tiny, - paddingInline: spacing.padding.small, - }, - modal: { - borderRadius: spacing.border.radius.xLarge, - gap: spacing.gap.large, - margin: spacing.margin.xLarge, - padding: spacing.padding.xLarge, - paddingBlock: spacing.padding.large, - paddingInline: spacing.padding.xLarge, - }, - dropdown: { - borderRadius: spacing.border.radius.medium, - gap: spacing.gap.small, - margin: spacing.margin.small, - padding: spacing.padding.small, - }, - dropdownItem: { - borderRadius: spacing.border.radius.small, - gap: spacing.gap.tiny, - margin: spacing.margin.tiny, - padding: spacing.padding.tiny, - paddingBlock: spacing.padding.tiny, - paddingInline: spacing.padding.small, - }, - tooltip: { - borderRadius: spacing.border.radius.small, - margin: spacing.margin.tiny, - padding: spacing.padding.tiny, - paddingBlock: spacing.padding.tiny, - paddingInline: spacing.padding.small, - }, - nav: { - borderRadius: spacing.border.radius.medium, - gap: spacing.gap.medium, - margin: spacing.margin.medium, - padding: spacing.padding.medium, - }, - navItem: { - borderRadius: spacing.border.radius.small, - gap: spacing.gap.small, - margin: spacing.margin.small, - padding: spacing.padding.small, - paddingBlock: spacing.padding.tiny, - paddingInline: spacing.padding.medium, - }, - grid: { - gap: spacing.gap.large, - margin: spacing.margin.large, - padding: spacing.padding.large, - }, - gridItem: { - borderRadius: spacing.border.radius.medium, - gap: spacing.gap.small, - margin: spacing.margin.small, - padding: spacing.padding.medium, - }, - stack: { - gap: spacing.gap.medium, - margin: spacing.margin.medium, - padding: spacing.padding.medium, - }, - stackItem: { - borderRadius: spacing.border.radius.small, - gap: spacing.gap.tiny, - margin: spacing.margin.tiny, - padding: spacing.padding.small, - }, - sidebar: { - borderRadius: spacing.border.radius.medium, - gap: spacing.gap.medium, - margin: spacing.margin.medium, - padding: spacing.padding.large, - paddingBlock: spacing.padding.medium, - paddingInline: spacing.padding.large, - }, - sidebarItem: { - borderRadius: spacing.border.radius.small, - gap: spacing.gap.small, - margin: spacing.margin.tiny, - padding: spacing.padding.small, - paddingBlock: spacing.padding.tiny, - paddingInline: spacing.padding.medium, - }, - header: { - borderRadius: spacing.border.radius.medium, - gap: spacing.gap.medium, - margin: spacing.margin.medium, - marginBlockEnd: spacing.margin.large, - padding: spacing.padding.large, - paddingBlock: spacing.padding.medium, - paddingInline: spacing.padding.large, - }, - footer: { - borderRadius: spacing.border.radius.medium, - gap: spacing.gap.medium, - margin: spacing.margin.medium, - marginBlockStart: spacing.margin.large, - padding: spacing.padding.large, - paddingBlock: spacing.padding.medium, - paddingInline: spacing.padding.large, - }, dynamicHeight: (height) => ({ height }), dynamicPadding: (paddingTop, paddingBottom) => ({ paddingTop, From 5ce36df335511d57fc0716ec56786b2b0bc1bdf5 Mon Sep 17 00:00:00 2001 From: Jesse Maltese Date: Wed, 5 Nov 2025 13:36:28 -0500 Subject: [PATCH 13/13] Less example code --- .../benchmarks/perf/fixtures/sizes.stylex.js | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/packages/benchmarks/perf/fixtures/sizes.stylex.js b/packages/benchmarks/perf/fixtures/sizes.stylex.js index 446c86006..354a9f248 100644 --- a/packages/benchmarks/perf/fixtures/sizes.stylex.js +++ b/packages/benchmarks/perf/fixtures/sizes.stylex.js @@ -70,34 +70,6 @@ const SpacingTokens = { medium: '1rem', large: '1.5rem', }, - icon: { - size: { - small: '1rem', - medium: '1.5rem', - large: '2rem', - }, - }, - button: { - height: { - small: '2rem', - medium: '2.5rem', - large: '3rem', - }, - }, - input: { - height: { - small: '2rem', - medium: '2.5rem', - large: '3rem', - }, - }, - container: { - width: { - small: '20rem', - medium: '40rem', - large: '60rem', - }, - }, }; export const spacing = stylex.defineConsts(SpacingTokens);