stylex
stylex copied to clipboard
[RFC] Defining styles inline
Describe the feature request
Motivation
It has often been suggested that it should be possible to define styles inline. There are many reasons why such a feature might be desirable:
- Defining styles with
stylex.create
is too much ceremony for one-off styles -
stylex.create
doesn't benefit for Prop type constrains when passing styles as props. - Developer preference for more co-location.
Naming Bikeshed
There has been much discussion about what the function name for this API should be.
-
stylex.inline
- Slightly verbose, slightly unclear. -
stylex.atom
- Terse but unclear -
stylex.createOne
- Very verbose but clear -
stylex.make
- Short and clear, but confusing alongsidestylex.create
.
I would love feedback to help make a decision here. Please leave a 👍 on one of the first four comments below to register your vote.
Proposed API
Assuming the stylex.inline
name, the usage would still be what you would expect from a hypothetical stylex.createOne
function. i.e. Instead of defining:
const styles = stylex.create({
base: {color: 'red'}
});
You'd be able to do:
const red = stylex.inline({color: 'red'})
Of course, it would also be possible to use this function call directly
with a stylex.props()
call or a component prop.
<div {...stylex.props(
stylex.inline({color: 'red'})
)} />;
<MyButton styles={stylex.inline({color: 'red'})} />;
Since the function accepts an object, it would be possible to define a whole object of styles.
stylex.inline({
color: 'red',
backgroundColor: 'black',
textDecoration: {
default: 'none',
':hover': 'underline',
':focus-visible': 'underline',
},
...
})
It would be possible to apply the styles conditionally:
<MyButton styles={[
isRed && stylex.inline({color: 'red'}),
isBlue && stylex.inline({color: 'blue'}),
]} />;
And it would be be possible to reduce verbosity with the import.
import {inline as _} from '@stylexjs/stylex';
<MyButton styles={[
isRed && _({color: 'red'}),
isBlue && _({color: 'blue'}),
]} />;
Constrains and Considerations
One of the biggest concerns when implementing this feature is dynamic styles. stylex.create
enforces the usage of functions to define styles that can be dynamic. However, doing the same with the new API would be awkward.
<MyButton styles={stylex.inline((color) => ({color}))(dynamicColor)} />;
Instead, the developer expectation would be the ability to use dynamic values directly within the objects
<MyButton styles={stylex.inline({color: dynamicColor})} />;
This has two issues:
One: It is difficult to implement this correctly and detect all the ways the value of the styles may be known statically. We don't accidentally want to generate dynamic styles when the styles are actually statically know.
Two: It makes it far too easy to define dynamic styles. One of the reasons for requiring functions within stylex.create
to define dynamic styles is that the vast majority of use-cases should not depend on dynamic styles. Instead conditional styles, and compositions should be sufficient. Requiring functions makes the need for truly dynamic styles explicit and enforces intentionality. Automatically generating dynamic styles with the new API would encourage patterns that would lead to bloated and slower styles.
Therefore, the current proposal would disallow the usage of dynamic styles within the new API entirely. Using dynamic values of styles within a stylex.inline()
(or whatever we call it) call would be a compile-time error. It would still be possible to define constants and use them, but the amount expressivity possible would be limited by the capabilities of the compiler.
Reasons against implementing this API
There are also many great reasons why this API should not implemented. To name a few:
- Increased maintenance burden - A bigger API is harder to maintain takes focus away from other improvements.
- Increased API surface area - Makes StyleX harder to understand
- Leads to less readable code - Enforcing all styles be defined in
stylex.create
arguably creates more readable and maintainable code in the long run at the cost of some minor inconvenience upfront. - The lack of dynamic styles in the API could become a pitfall.
Thoughts?
I'm posting this proposal early to gather feedback and help improve this idea before implementation.
To vote for the API name, simply react with a 👍 on one of the first four comments on this issue. For any feedback about how the API works, respond with a comment.
stylex.inline
stylex.atom
stylex.createOne
stylex.make
This is exciting. My only hesitation with inline
is that it could unintentionally lead users to believe that pseudos are not supported. Something like atom
makes sense to me for this reason. Then you can think of StyleX as a composition of Style atoms. ~Either way, excited for this to land.~
The proposed API would add significant maintenance complexity and needless surface area to StyleX. We have a design principle in React which is to only have one way to do things, even if it is more verbose in some cases. Defining styles directly on an element only looks readable in the most simple of cases. We already have 3 functions to resolve styles (one is legacy) and 2 ways to merge them (include and arrays). We could be simplifying the API rather than adding more ways to do the same thing
The proposed API would add significant maintenance complexity and needless surface area to StyleX. We have a design principle in React which is to only have one way to do things, even if it is more verbose in some cases. Defining styles directly on an element only looks readable in the most simple of cases. We already have 3 functions to resolve styles (one is legacy) and 2 ways to merge them (include and arrays). We could be simplifying the API rather than adding more ways to do the same thing
If flexibility is paramount would it not make sense to implement your concerns as ESLint warnings? The reality of not implementing inline
means that users will defer to using inline styles rather than something that StyleX controls. I'd argue between those two choices, support for inline
is probably preferable over users implementing inline styles themselves. Of course, users will probably still implement inline styles (unintentionally), but at least this way there's a small, incremental path to refactoring their code which is still correct.
Another implementation would be having strict mode, which disciplines developers to write code one way, like @necolas is suggesting. But not having a need for strict mode is even better.
For what it's worth I'd be willing to give up stylex.include
for support for inline
. I found I can lean into some kind of pattern like this (particularly with typography), when I want to compose styles:
import * as stylex from "@stylexjs/stylex";
export type ExtendProps = { extend?: stylex.StyleXStyles };
export function Title({ extend, ...props }: ExtendProps & JSX.IntrinsicElements["div"]) {
return <div {...props} {...stylex.props(styles.title, extend)} />;
}
Then I can simply use <Title extend={styles.foo} />
. I imagine RSD has some way of making this simpler, still.
Anyway, if StyleX makes inline
or something like it a first-class primitive, I can imagine it being easily abused. A lot of people would love to implement styles orthogonal to the way they write Emotion CSS and Tailwind, which is usually more productive in the short term and easily becomes a clusterfuck of unreadable code down the road.
For this reason, the StyleSheet API, although somewhat ceremonious at times, reinforces the idea that correctness is about narrowing decisions, which I certainly appreciate. A little bit of pain up front can be worth if it if it narrows the overall complexity space of what you're trying to achieve.
@nmn Does inline
also work in React Native? Another question would be, would this be possible to implement as a standalone package experiment?
The proposed API would add significant maintenance complexity and needless surface area to StyleX.
I share this concern. I have received repeated requests for something on these lines and so I'm trying to gather feedback to see if makes sense. The "Constrains & Considerations" section also describes some limitations that make me way of implementing this API.
@zaydek This RFC should not yet be considered as something we're about to land. This issue exists to gather feedback. There are still many reasons against doing this. The benefits would need to great outweigh those downsides.
if StyleX makes inline or something like it a first-class primitive, I can imagine it being easily abused.
This is another valid reason against adding this API. Although a bit subjective, I believe enforcing the usage of stylex.create
for all styles results in more readable styles in the long run.
would this be possible to implement as a standalone package experiment?
This is possible and what I'm working towards. I don't want to bring this into "core" anytime soon.
Does inline also work in React Native?
Did you mean RSD? RN supports inline style objects. RSD does not support this API.
Did you mean RSD? RN supports inline style objects. RSD does not support this API.
@nmn I actually meant RN but I didn't know RN supports inline style objects already. Also, it sounds like RSD is effectively strict mode for StyleX so that seems aligned.
Thanks for clarifying this is not 'about to land' as I assumed. FWIW everytime I've tried to write inline style-based UIs first it's always come back to haunt me. It tooks some getting used to StyleX's StyleSheet approach but honestly it's really just like CSS Modules but typed and colocated. Now it's a no brainer for me to use StyleX and I love the API. So a little friction is fine and totally valid if you're trying to do something different, which StyleX is.
Experiments help gather information, so perhaps there's some opportunity that inline
unlocks, but given the choice, I think I'm indifferent. I already learned my lesson with stylex.include
that I don't really need it, even though originally I thought I did. I suspect the same could be true for inline
.
I do use inline styles alongside StyleX at present, but it's simply because I'm too lazy. It's probably only 2-5% so it doesn't really matter either way. I genuinely appreciate there are so few ways to do things in StyleX, as this tweet reads:
The only concepts you need to understand in StyleX:
- Style Objects - apply them, merge them, use them conditionally whatever
- Variable Objects - use them within styles
- Themes - set values for variables on a UI sub-tree
That’s it. Seriously.
This is very good 'north star' for StyleX.
I have been using stylex for a long time,To be honest, the current method is too cumbersome for react, So i mad a babel-plugin for this problem. test-case
You might notice i'm using JSXAttributes
, In my opinion this is simpler to use.
inspired by style9-jsx-prop
AFAIK. The dynamic values are very difficult to calculate, So i have to treat each attribute as a token. But i don't think is a good way. I try to merge static token to a whole object until the token meet dynamic or SpreadElement
node. But I don't know if it's worth it.
- Why can't you put style objects directly in the
stylex.props
call?
<div {...stylex.props({display: 'flex', flexDirection: 'column'}, ...)}>
...
</div>
- One way this feature could be abused is by creating a library of tailwind like utility inline styles.
const flex = stylex.inline({display: 'flex'})
const flexCol = stylex.inline({flexDirection: 'column'})
<div {...stylex.props(flex, flexCol)}>
...
</div>
I feel like 2 can be solved, if only 1 is allowed. if you want to reuse styles, then you should put them in a stylex.create
stylesheet.
Why can't you put style objects directly in the stylex.props call? @aspizu This isn't feasible for a couple of reasons:
- It only works for styles being applied directly on an element and not props to custom components
- Since conditions can be used within
stylex.props
detecting inline styles without a function call wrapper can be error prone.
The reality of not implementing inline means that users will defer to using inline styles rather than something that StyleX controls
Is the proposed name (inline
) is confusing you (or me)? This isn't an RFC for adding what is traditionally referred to as "inline styles", we already support those using the function syntax within create()
.
Then I can simply use <Title extend={styles.foo} />. I imagine RSD has some way of making this simpler, still.
No need for a new prop name, we just pass styles down using the style
prop.
removed to keep this RFC concise
@BMCwebdev This is a broader discussion that should live in "discussions". This issue is for discussing the possibility of adding an API for defining styles "inline" only.
I like the name inline
but I agree that this might not be a good feature to take on at the moment - maybe in the future? I share the same concerns and also like having only one way of doing things as much as possible.
This is interesting. I'm not sure that it's needed but I can see it would add a bit of convenience.
As for names, what about stylex.one
- that seems both terse and clear (to me at least!) :)
The reality of not implementing inline means that users will defer to using inline styles rather than something that StyleX controls
Is the proposed name (
inline
) is confusing you (or me)? This isn't an RFC for adding what is traditionally referred to as "inline styles", we already support those using the function syntax withincreate()
.Then I can simply use <Title extend={styles.foo} />. I imagine RSD has some way of making this simpler, still.
No need for a new prop name, we just pass styles down using the
style
prop.
The name is only confusing to me because stylex.inline
doesn't necessarily communicate that stylex.inline
can do more than inline styles traditionally can (pseudos). But this is a minor point.
I think the question to ask is, is something like this:
<div {...stylex.props(styles.foo, stylex.inline({ color: red }))} />
worth not having the confidence that all styles are implementing using stylex.create
?
I admit you changed my mind that having multiple ways to do the same thing is probably not worth it. You could end up with code bases that are 90% stylex.create
or conversely 90% stylex.inline
, which I think could be worse than just not supporting stylex.inline
at all.
I personally really appreciate the idea that there's only one correct way to do things. Even if it's more painful to learn the API initially, it's worth it in the long run to constrain unnecessary complexity.
I'm curious to experience it as an experiment but not more than that for the time being.
Leads to less readable code - Enforcing all styles be defined in stylex.create arguably creates more readable and maintainable code in the long run at the cost of some minor inconvenience upfront.
I think this can be enforced by linter setup and decided by end users if they want to block it or not.
Maybe also some size checking if it exceeds x rows/styles then it should throw an error Error: Use stylex.create for larger style collections
?
There is some potential in this util for bringing custom logic in the codebases for handling some cases where we don't really need defining the variants.
I think especially about creating ui-kits with stylex, where if you use the cva
approach, this becomes a bit of a problem.
For example, desired usage with cva could be:
const ButtonStyles = cva({
base: stylex.inline({
// ...some basic styles, that do not change
}),
variants: {
variant: stylex.create({
solid: {
// some styles
},
outlined: {
// some styles
}
// ...
}),
color: stylex.create({
// ...
})
},
compundVariants: [
variant: "outlined"
color: "primary",
css: stylex.inline({
background: "transparent",
borderColor: "blue"
})
}]
})
So in my opinion this will enable much easier and better composing of the logic, bringing greater flexibility and options for integrating it with custom logic in the codebase/libraries.
@prc5 Using cva
with StyleX is an anti-pattern as the extra complexity isn't needed. We've covered alternatives that fit with StyleX better before.
Here's some reference in the docs https://stylexjs.com/docs/learn/styling-ui/using-styles/#style-variants @prc5 think that's what Naman is referring to
@CanRau Thank you reference. I used cva here as a bit of a shortcut to show that it is possible to use the given logic in some way. I myself think that since Stylex itself allows you to build various types of abstractions around it - after all, it is JS that we know well - maybe it's just fine to allow it?
@nmn My observations are that with larger components, some logic overhead may be let's say "useful". After some time, initializing everything manually and assigning becomes just tiring, there are a lot of disconnected variables around - hence my experiments with some logic to organize it (and force it). I guess, I still haven't found the sweet spot for organizing these styles. I understand that this approach may cause unpredictable side-effects, hence the name "anti-pattern".
I see stylex.inline
at the same time as a method to easily abuse the way of using Stylex and the method that can increase the ease of use.
Nevertheless, I hope that this will bring you at least a little closer to the final decision. Good luck!
after all, it is JS that we know well - maybe it's just fine to allow it?
- It's important to remember that StyleX is a compiler and does not allow arbitrary Javascript. All patterns need to static.
- Secondarily, our core principle is to keep the API simple and provide one flexible API rather than every possible API that someone might want. We're very happy with the variants patterns that can be achieved with a simple object and don't want to introduce the non-standard "cva" pattern just because it's currently a popular pattern in other styling solutions. (Objects are forever!)
I guess, I still haven't found the sweet spot for organizing these styles
Please open a discussion topic with your questions. In our experience using StyleX at Meta for about 5 years now, we find that while sometimes StyleX can be a bit more verbose up-front, it can be used to create readable, maintainable styling with very complex logic.
The requirement to name styles also helps readability as you can focus on "what" rather than "how" when reading the styles of a component and focus on the logic to apply styles conditionally.
I wanted to follow-up because I've been thinking about this a lot. There's a lot in this but I think this is the appropriate place, here or as a discussion. In any case, this is why I think stylex.inline
or stylex.atom
is a very good idea for StyleX.
At present, when implementing StyleX, you are expected to exclusively use the stylesheet API, also known as stylex.create
. This is good because there are few ways to do things, but it can become very problematic because it requires you to step back and think about the taxonomy of your application as opposed to just building it. It's pretty obvious that libraries like Tailwind are popular because they don't force you to think, but they do lead to pretty obfuscated code that gets gnarlier the more the project grows.
So I did an experiment last night where I attempted to combine the benefits of Tailwind and StyleX and I'm really happy with the results. This is about my process of trying to combine StyleX and utilities together and what epiphanies came from the exercise.
In short, you can express utilities in StyleX by enumerating all the properties and values-per-property that you care about.
For example:
export const display = stylex.create({
flex: { display: "flex" },
grid: { display: "grid" },
arbitrary: (value: CSSProperties["display"]) => ({ display: value }),
});
export const flexDirection = stylex.create({
row: { flexDirection: "row" },
column: { flexDirection: "column" },
rowReverse: { flexDirection: "row-reverse" },
columnReverse: { flexDirection: "column-reverse" },
arbitrary: (value: CSSProperties["flexDirection"]) => ({ flexDirection: value }),
});
export const justifyContent = stylex.create({
normal: { justifyContent: "normal" },
start: { justifyContent: "flex-start" },
end: { justifyContent: "flex-end" },
center: { justifyContent: "center" },
spaceBetween: { justifyContent: "space-between" },
spaceAround: { justifyContent: "space-around" },
spaceEvenly: { justifyContent: "space-evenly" },
stretch: { justifyContent: "stretch" },
arbitrary: (value: CSSProperties["justifyContent"]) => ({ justifyContent: value }),
});
export const alignItems = stylex.create({
start: { alignItems: "flex-start" },
end: { alignItems: "flex-end" },
center: { alignItems: "center" },
baseline: { alignItems: "baseline" },
stretch: { alignItems: "stretch" },
arbitrary: (value: CSSProperties["alignItems"]) => ({ alignItems: value }),
});
export const gap = stylex.create({
0: { gap: 0 },
4: { gap: 4 },
8: { gap: 8 },
12: { gap: 12 },
16: { gap: 16 },
20: { gap: 20 },
24: { gap: 24 },
32: { gap: 32 },
40: { gap: 40 },
48: { gap: 48 },
56: { gap: 56 },
64: { gap: 64 },
arbitrary: (value: CSSProperties["gap"]) => ({ gap: value }),
});
And then you export an object that wraps all of these utilities:
export const util = {
display,
flexDirection,
justifyContent,
alignItems,
gap,
...
}
Then you can very easily express what would otherwise be small stylesheet objects as a composition of a few utilities.
Here is some code I wrote last night:
export function CheckboxItem() {
const [checked, setChecked] = useState<Checked>("UNCHECKED");
return (
<button
{...stylex.props(styles.touchableContainer, util.alignItems.center, util.display.flex, util.gap[8])}
onClick={() => setChecked(toggleCheckedStart)}
>
<div
{...stylex.props(
util.backgroundColor.arbitrary(varOf(touchableBackgroundColor)),
util.borderRadius[1e3],
util.display.flex,
util.flex[1],
util.minInlineSize[0],
util.paddingInlineEnd[16],
)}
>
<div {...stylex.props(util.padding[8])}>
<div
{...stylex.props(
util.backgroundColor.arbitrary("rgba(0 0 0 / 0.5)"),
util.blockSize[16],
util.borderRadius[1e3],
util.inlineSize[16],
)}
/>
</div>
<div {...stylex.props(util.alignItems.center, util.display.flex, util.flex[1], util.minInlineSize[0])}>
<div {...stylex.props(util.overflow.hidden, util.textOverflow.ellipsis, util.whiteSpace.nowrap)}>
Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
</div>
</div>
</div>
<Checkbox checked={checked} setChecked={setChecked} />
</button>
);
}
This is kind of mind-blowing to me. You can rename util
to whatever you want but for all intents and purposes this is typed utility styles that is still able to piggy back on top of the StyleX compiler. It's a kind of mix-and-match approach where you can use the best tool for the job.
This is really interesting because even values are typed and I can still opt into arbitrary
as a fallback. What's powerful about this is that assuming last still wins, this is like CSS from the future where you can actually predict how things will turn out because the order means something thanks to the StyleX compiler.
It's also interesting how long series of utils are automatically formatted as vertical lists when using Prettier, dprint, etc., which is easier to grok but also a hint to just use the style object if you find what you're doing is actually complex as opposed to just a few styles or a one-off override.
I really enjoy this because it means that I can incrementally adopt the stylesheet API only when I truly need to compose CSS, meaning there's some story I want to tell so I name my style objects and animations and variants so as to reinforce that story. For example, naming sidebar
, sidebarAnimatingIn
, sidebarAnimatingOut
. But I find that maybe as often as half the time, there is no 'story', or I don't know what that story is yet; I'm still in the process of scaffolding or reworking code or the code isn't complicated enough in the first place so as to warrant going through the trouble of creating style objects.
So my encouragement is the following, a stylex.inline
or stylex.atom
API would make the following possible:
- Allow users to incrementally adopt the stylesheet API when needed
- Allow users to decompose simple style objects as a composition of utilities
- Offer feature parity with CSS-in-JS libraries that expose
className={css(...)}
as a primitive - Offer the benefits of utility styles but with the safety and sanity of TypeScript and no extensions necessary
- Offer the ability to inline media queries and breakpoints (which my naive implementation can't do)
As per the original argument, which was that StyleX should not adopt inline styles because it would mean there are multiple ways to do the same thing, the nuance not being said is that there are still multiple ways to name the same thing. I find the constraint of needing to name everything more annoying than having access to stylex.inline
or stylex.atom
for specific use-cases like experimentation, scaffolding, and one-off overrides.
Right now, my experience with StyleX is that it makes 'hard things easy and easy things hard'. Conversely, Tailwind makes 'easy things easy and hard things hard'. In Tailwind, I can express most UI in fewer than 5 classes, but whenever I approach anything that is intrinsically complex it spirals out of control and I give up sanity and safety along the way. This is what led me to the observation that having something like utilities in StyleX, such as stylex.inline
or stylex.atom
or my naive util
implementation, provides me safety and sanity from the easiest to most complex UI. I can incrementally adopt the stylesheet API as needed.
In any case I'm personally happy that I think I have a fallback solution independent of this RFC. That being said, I see how much I personally struggle with this and I think that it would be really beneficial for the community to have a simpler way to buy in to StyleX without having to bet the farm on the stylesheet API.
Defining styles directly on an element only looks readable in the most simple of cases.
It's true that named styles can be more readable for larger components. However, we have the option to split them into separate, smaller components and name them appropriately to make them more readable as well.
Named styles can improve readability for large components:
const styles = stylex.create({
container: { display: 'flex', flexDirection: 'column', padding: '1rem' },
title: { fontSize: '2rem', marginBottom: '1rem' },
text: { fontSize: '1rem', lineHeight: '1.5' },
button: { backgroundColor: 'blue', color: 'white', padding: '0.5rem 1rem' },
})
function LargeComponent() {
return (
<html.div style={styles.container}>
<html.h1 style={styles.title}>Title</html.h1>
<html.p style={styles.text}>Some text content...</html.p>
<html.button style={styles.button}>Click me</html.button>
</html.div>
)
}
Splitting the component into smaller ones can also improve readability:
function Title() {
return <html.h1 style={stylex.inline({fontSize: '2rem', marginBottom: '1rem'})}>Title</html.h1>
}
function Text() {
return <p style={stylex.inline({fontSize: '1rem', lineHeight: '1.5'})}>Some text content...</html.p>
}
function Button() {
return <html.button style={stylex.inline({backgroundColor: 'blue', color: 'white', padding: '0.5rem 1rem'})}>Click me</html.button>;
}
function LargeComponent() {
return (
<html.div style={stylex.inline({display: 'flex', flexDirection: 'column', padding: '1rem'})}>
<Title />
<Text />
<Button />
</html.div>
);
}
In practice, I use inline styles extensively in my codebase and find 3-4 levels of nesting and about 100 lines of code for each component (including inline styles) still quite manageable and readable. When things get too large or complex,splitting components often make more sense anyway because it makes it clear what parts depend on which props/state, makes it easier to reduce re-renders by memoization, etc.
In conclusion, although I understand the concern about potential increase in complexity, I find inline styles very useful. Not all styles need naming if they are short and I find style colocation more readable in many cases.
@zaydek This may be of interest to you: https://gist.github.com/nmn/b98c21fbf3ee02c35319940b14030f62
assuming last still wins
It does. The main concern with this pattern is about detecting unused styles. JS tooling usually can't catch unused variables across module boundaries. I have some ideas to tackle and optimise this pattern, but it's on the back-burner for now.
In fact, I tend using inline
to define simple styles in my component like:
import React from 'react'
import { useScale, withScale } from '../../composables'
interface Props {
inline?: boolean
}
export type SpacerProps = Omit<React.HTMLAttributes<any>, keyof Props> & Props
function SpacerComponent({ inline = false, ...props }: SpacerProps) {
const { SCALES } = useScale()
return (
<div
stylex={{
width: SCALES.width(1),
height: SCALES.height(1),
padding: `${SCALES.pt(0)} ${SCALES.pr(0)} ${SCALES.pb(0)} ${SCALES.pl(0)}`,
margin: `${SCALES.mt(0)} ${SCALES.mr(0)} ${SCALES.mb(0)} ${SCALES.ml(0)}`,
display: 'block',
...(inline && { display: 'inline-block' })
}}
{...props}
/>
)
}
SpacerComponent.displayName = 'Spacer'
export const Spacer = withScale(SpacerComponent)
JSXAtrribute
is same as inline function, In my option only simple and short style sheet need it. If us style sheet is big, and we need compose some short style sheet i prefer using
import * as stylex from '@stylexjs/stylex'
const styles = stylex.create({
// ... a long style sheet
})
function Component() {
return <div {...stylex.props(styles.icon,inline({position:'static'}))}></div>
}
Let me explain what i did. The JSXAttribute
is just translating JSXAttribute
into props
or attrs
and combing it with create
In the follow code block
// input
const Component = () => {
return <div stylex={{ color: "red" }} />;
};
// output
import { create, props } from "@stylexjs/stylex";
const styles = create({
xxHash: {
color: "red",
},
});
const Component = () => {
return <div {...props(styles.xxHash)} />;
};
Back to topic. In my option is that inline
is equivalent to create
. So i extra them to the toplevel and translate them. Here is a simple example
// input
import { create, props } from "@stylexjs/stylex";
const styles = create({
test: {
// ... a long style sheet
},
});
const Component = () => {
return <div {...props(styles.test, inline({ position: "static" }))} />;
};
// output
import { create, props } from "@stylexjs/stylex";
const styles = create({
test: {
// ... a long style sheet
},
});
const _styles = create({
xxHash: {
position: "static",
},
});
const Component = () => {
return <div {...props(styles.test, _styles.xxHash)} />;
};
@nonzzz Is that a custom Vite plugin? What's doing the translation for you? That's really interesting.