stylex icon indicating copy to clipboard operation
stylex copied to clipboard

can we get a more ergonomic api for devx coming from styled components / emotion

Open maz-phantom opened this issue 4 months ago • 6 comments

Describe the feature request

hey guys im coming from emotion and i HATE tailwind because it clutters my jsx !!! i love having a readable jsx and im a big fan of css in js.

stylex is almost perfect for everything i want. plus if it's good enough for figma it's good enough for me xD

can you guys please consider a slightly more ergonomic api like the styled api ?

otherwise do you recommend writing a wrapper like this ?

// sx-elements.tsx
import * as React from 'react';
import * as stylex from '@stylexjs/stylex';

// allow sx as a single rule or an array
const toArr = (x: any) => (Array.isArray(x) ? x : x ? [x] : []);

function make<T extends keyof JSX.IntrinsicElements>(tag: T) {
  type Props = JSX.IntrinsicElements[T] & { sx?: any | any[] };
  return React.forwardRef<any, Props>(({ sx, className, style, ...rest }, ref) => {
    const out = sx ? stylex.props(...toArr(sx)) : undefined;
    const mergedClass =
      [out?.className, className].filter(Boolean).join(' ') || undefined;
    const mergedStyle = out?.style ? { ...out.style, ...style } : style;

    return React.createElement(tag, {
      ref,
      className: mergedClass,
      style: mergedStyle,
      ...rest,
    });
  });
}

// Export the tags
export const Div = make('div');
export const Span = make('span');
export const Button = make('button');
// ...add others as needed
import { Div, Button } from './sx-elements';
import * as stylex from '@stylexjs/stylex';

const styles = stylex.create({
  base: { padding: 12, borderRadius: 8 },
  blue: { backgroundColor: 'dodgerblue', color: 'white' },
  gray: { backgroundColor: '#eee', color: '#111' },
  btn: { fontWeight: 600, paddingInline: 14, paddingBlock: 8 },
  primary: { backgroundColor: 'black', color: 'white' },
});

export function Card() {
  const isBlue = true;
  return (
    <Div sx={[styles.base, isBlue && styles.blue]}>
      Hello
      <Button sx={[styles.btn, styles.primary]}>Go</Button>
    </Div>
  );
}

just would like to get some guidance here i dont really want to litter my jsx with ...stylex.props everywhere

is there a 3rd part library you recommend to do this for me ?

found this on that seems related: https://github.com/facebook/stylex/discussions/332

maz-phantom avatar Aug 28 '25 06:08 maz-phantom

please !

xrzhuang avatar Aug 29 '25 20:08 xrzhuang

Yes! This is in the backlog to address, a small babel plugin can abstract out the spread. Mainly figuring out (1) naming that doesn't conflict with other props/functions, (2) whether it should live within the main package or as an extension

mellyeliu avatar Sep 02 '25 02:09 mellyeliu

Yes! This is in the backlog to address, a small babel plugin can abstract out the spread. Mainly figuring out (1) naming that doesn't conflict with other props/functions, (2) whether it should live within the main package or as an extension

my hero !!! can u pls lmk when it will go live or if there is some way i can start using it ?

maz-phantom avatar Sep 03 '25 08:09 maz-phantom

Keep an eye on https://github.com/nmn/stylextras

It has a babel plugin for Tailwind that is fully functional already. The only parts that remain are to support more rich tailwind config. You should be able to use that as a foundation to build a babel plugin for your own syntax extensions.

nmn avatar Sep 07 '25 03:09 nmn

@nmn put up something in https://github.com/facebook/stylex/pull/1218 - feel free to give feedback on naming as it's up for discussion

mellyeliu avatar Sep 07 '25 09:09 mellyeliu

@nmn put up something in #1218 - feel free to give feedback on naming as it's up for discussion

honestly it's beautiful i have no complaints

xrzhuang avatar Sep 07 '25 18:09 xrzhuang

tracking in https://github.com/facebook/stylex/issues/1357 and https://github.com/facebook/stylex/issues/1359 updates soon!!

mellyeliu avatar Dec 03 '25 06:12 mellyeliu