stylex icon indicating copy to clipboard operation
stylex copied to clipboard

[feat] Simple `sx={}` syntax as an alternative to stylex.props

Open nmn opened this issue 3 months ago • 9 comments

What changed / motivation ?

This adds a small syntactic sugar to allow using a sx= prop on lower-case html JSX elements as an alternative to {...stylex.props}

So you can write:

<div sx={[styles.foo, styles.bar]} />

instead of

<div {...stylex.props(styles.foo, styles.bar)} />

if you want.

This addresses a very common complaint.

Additional Context

A single test has been added.

This PR is not quite ready to merge yet. The transformation is currently hardcoded.

Pre-flight checklist

nmn avatar Sep 07 '25 05:09 nmn

workflow: benchmarks/perf

Comparison of performance test results, measured in operations per second. Larger is better.

[email protected] compare node ./compare.js /tmp/tmp.LpDEPTYkie /tmp/tmp.HqZx70gR44

Results Base Patch Ratio
babel-plugin: stylex.create
· basic create 653 635 0.97 -
· complex create 192 187 0.97 -
babel-plugin: stylex.createTheme
· basic themes 458 450 0.98 -
· complex themes 43 42 0.98 -

github-actions[bot] avatar Sep 07 '25 05:09 github-actions[bot]

workflow: benchmarks/size

Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better.

[email protected] compare node ./compare.js /tmp/tmp.efLTW28HRL /tmp/tmp.w4ewnaZt6s

Results Base Patch Ratio
@stylexjs/stylex/lib/cjs/stylex.js
· compressed 1,190 1,190 1.00
· minified 3,541 3,541 1.00
@stylexjs/stylex/lib/cjs/inject.js
· compressed 1,223 1,223 1.00
· minified 3,216 3,216 1.00
benchmarks/size/.build/bundle.js
· compressed 496,650 496,650 1.00
· minified 4,847,840 4,847,840 1.00
benchmarks/size/.build/stylex.css
· compressed 99,853 99,853 1.00
· minified 747,541 747,541 1.00

github-actions[bot] avatar Sep 07 '25 05:09 github-actions[bot]

not sure if we could use this internally with Flow etc, but will try to collect feedback on naming regardless

mellyeliu avatar Sep 08 '25 18:09 mellyeliu

This would be amazing, if you could get it working on flow especially. We're migrating to stylex at the moment and this is one of my personal pet peeves. We're also on flow (and relay), could you get the flow team to add a custom config like relay has relay_integration=true so it becomes stylex aware, and handles it accordingly?

matclayton avatar Sep 19 '25 14:09 matclayton

This would be a big help. Would love to see this so I don't have to alternate between {...stylex.props(…)} and sx={…} depending on if it's an intrinsic element or a component.

zaydek avatar Oct 09 '25 22:10 zaydek

Will sync with the Flow team on support for this

mellyeliu avatar Oct 15 '25 16:10 mellyeliu

@mellyeliu did you hear from the flow team. Super interested as we’re starting a large styled components to stylex conversion on a flow code base. This was one of the major sticking points internally and it would be great to know the direction you guys are thinking about.

matclayton avatar Oct 29 '25 20:10 matclayton

<div stylex={[styles.foo, styles.bar]} />

It's a naming problem, but in the case of sx={}, I feel like it's easy to confuse it with the method of directly describing the object of the component library. Intuitively, I thought of stylex={} as an upgraded version of React's style={}.
That said, I understand the ergonomics argument. If typos are a concern, they could be caught with ESLint rules.

Just wanted to share this perspective.

refirst11 avatar Nov 05 '25 11:11 refirst11

@matclayton will prioritize this soon! hoping to get some broader Flow integration help from the team

mellyeliu avatar Nov 05 '25 16:11 mellyeliu

So with TypeScript would consumers have to do something like this or would the StyleX typedefs set it?

declare module 'react' {
  interface HTMLAttributes<T> {
    sx?: StyleXStyles 
  }  
}

henryqdineen avatar Dec 03 '25 19:12 henryqdineen