Replies: 13 comments 23 replies
-
This is not a supported pattern. StyleX is a compiler so all values need to be defined locally. The only exception to this rule is Variables defined with In the case of variables, we don't actually read the file being imported at all. Instead we rely on the import name, and file path (relative to In your example, it is possible to use one variable to define another variable. So if You might want to share values across files. There are two patterns to achieve this: You can export compiled styles with
|
Beta Was this translation helpful? Give feedback.
-
This is actually really informative and really helpful! Perhaps this should be a topic that is covered in the docs? I am assuming many are trying to use existing tokens with StyleX. |
Beta Was this translation helpful? Give feedback.
-
What specifically would you like to see in the docs? We don't want to talk about Shared Media queries yet, because we don't know what it will look like. |
Beta Was this translation helpful? Give feedback.
-
Just did some further testing: import * as colors from '@me/my-personal-colors'
export const colorTokens = stylex.defineVars({
bgColor: colors.neutral.0
}); But the part about adding to the docs was more on the sharing values across files. But since it is a temporary limitation with a new process of adding additional capabilities when defining vars in on the horizon, perhaps we could wait for the implementation to come. But I think it would also be helpful to document a few purposeful limitations/patterns like the ones you shared above and many others in the issue board. |
Beta Was this translation helpful? Give feedback.
-
Because the compiler needs to read the contents of that file and StyleX only compiles a single file at a time.
It's not temporary... Let me try to clarify the rules of compilation:
Does that make sense? Some additional notes:
|
Beta Was this translation helpful? Give feedback.
-
Ah got it! I just somehow understood it completely the wrong way. This is some great info on the design choices! I just saw the |
Beta Was this translation helpful? Give feedback.
-
Yup. Look through |
Beta Was this translation helpful? Give feedback.
-
@nmn have you tried adding a new concept calling it “special global variables” that get replaced at build time before stylex plugin? Such global variables would get replaced using replace plugin, for example: rollup-plugin-replace.
Such global variables should work even without stylex adding them. It’d be great to know, if anyone tried it to avoid the extremely bad DX with only statically analyzable variables. Another pattern would be Facebook’s prepack, but it’d be much more complicated |
Beta Was this translation helpful? Give feedback.
-
I have been thinking along similar lines to create a standalone project to implement something like Bun's macro system in Babel. But this would be a project separate from StyleX itself. You're allowed to use any transformation steps you want before StyleX, but StyleX won't handle this for you. Also, the question in this issue seems to have been addressed, so I'm converting this to a discussion. |
Beta Was this translation helpful? Give feedback.
-
I was looking at the current state of the defineVars and stylex.types.atRule functions and they don't really solve what i was looking to do. Currently I use styled-components and was looking to slowly convert a small project over to stylex to feel how it works and if I preferred it for the future but there's a few major blocks i am currently running into. i understand that css values need to be static at compile time but i feel there are some really useful libraries available or simple functions you can write yourself that take out a lot of the repetitiveness of rewriting code on each and every css line. An example would be using the chroma-js library for modifying colours within styles. Technically this fails the only static values are allowed limitation, but this is something that in theory would not change and does not need to be executed within the runtime cycle, but can be done at compile time. // index.tsx
import chroma from 'chroma-js';
const s = stylex.create({
wrapper: {
width: '100%',
// backgroundColor: '#ff9264',
backgroundColor: `${chroma('red').brighten(2).hex()}`,
},
}); Another example would be to simplify repeating tedious calculations by allowing execution of simple functions that modify a variable defined from stylex, and even allow definevars to self reference values that are calculated from each other, for example a function that scales a size value: // globalTokens.stylex.ts
import stylex from '@stylexjs/stylex';
export const grid = stylex.defineVars({
columns: {
default: '10',
[`@media (max-width: 1024px)`]: '5',
},
atom: `calc(100vw / ${REFERENCE.columns})`, // instead of the current method of having to define this line inside another defineVars variable export that references grid
}); // index.tsx
import { grid } from './globalTokens.stylex';
const ga = (scale: number) => `calc(${grid.atom} * ${scale})`;
const s = stylex.create({
wrapper: {
// width: '20vw',
width: `${ga(2)}`, // instead of repeating `calc(${grid.atom} * 2)` everywhere with different values for the scale factor
height: `${ga(20)}`,
gap: `${ga(2)}`,
},
}); I feel like these might be a big deal for reducing repetitive code and to make the framework more ergonomic to use unless if there's another way that stylex can handle these patterns? |
Beta Was this translation helpful? Give feedback.
-
I've also been wondering if stylex.include actually works because I haven't been able to get it to work so far. i saw a discussion on one issue somewhere here but can't remember exactly where on whether it was even useful. I can see it being used to encapsulate small groups of css into reusable components essentially that can be used to build more layered style collections inside stylex rather then in components. An example would be as follows: const commonFrame = stylex.create({
base: {
height: `100%`,
width: `100%`,
paddingTop: `0`,
paddingBottom: `0`,
paddingLeft: `30px`,
paddingRight: `30px`,
position: 'relative',
margin: 'auto',
minHeight: `100px`,
display: 'block',
},
});
const frame = stylex.create({
content: {
...stylex.include(commonFrame.base),
paddingLeft: {
// eslint-disable-next-line @stylexjs/valid-styles
[greaterThanIncSmallDesktop]: `210px`,
},
paddingRight: {
// eslint-disable-next-line @stylexjs/valid-styles
[greaterThanIncSmallDesktop]: `210px`,
},
},
});
const flex = stylex.create({
container: {
display: 'flex',
minHeight: 0,
minWidth: 0,
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
alignItems: 'flex-start',
},
});
const s = stylex.create({
wrapper: {
...stylex.include(frame.content),
...stylex.include(flex.container),
height: 'auto',
width: '100%',
flexFlow: 'column',
flexWrap: 'wrap',
justifyContent: 'flex-start',
backgroundColor: '#060908',
gap: `50px`,
paddingTop: `100px`,
paddingBottom: `100px`,
},
});
export const El = () => (
<div {...stylex.props(s.wrapper)}>item</div>
) At the moment the above does not seem to work, it only works if applying the separate stylex classnames directly to the component itself: export const El = () => (
<div {...stylex.props(commonFrame.base, frame.content, flex.container, s.wrapper)}>item</div>
) |
Beta Was this translation helpful? Give feedback.
-
I think this question is related. We are building a project where the users (devs) is allowed to redefined the variable values in their own consuming projects. The consuming projects dont really need to use stylex. Our project outputs the css and js file. The problem is now that the variables that they should put into their tag on their site is those hashed names. How do we do a defineVar call and specify that we want "pretty" names such its easy for the consuming project to redefine/override those variables? |
Beta Was this translation helpful? Give feedback.
-
I need helpWhen working with styleX, I keep running into the same problem. As long as I import the files where the stylex variables are defined directly into the .ts file with the component, everything works fine.
export const colorBtn = defineVars({
btnPrimaryBgActive: "var(--colorBtnPrimaryBgActive)",
btnPrimaryBgBase: "var(--colorBtnPrimaryBgBase)",
btnPrimaryBgHover: "var(--colorBtnPrimaryBgHover)",
btnPrimaryTextBase: "var(--colorBtnPrimaryTextBase)",
btnPrimaryTextHover: "var(--colorBtnPrimaryTextHover)",
btnPrimaryTextActive: "var(--colorBtnPrimaryTextActive)",
btnSecondaryBgBase: "var(--colorBtnSecondaryBgBase)",
btnSecondaryBgHover: "var(--colorBtnSecondaryBgHover)",
btnSecondaryBgActive: "var(--colorBtnSecondaryBgActive)",
btnSecondaryTextBase: "var(--colorBtnSecondaryTextBase)",
btnSecondaryTextHover: "var(--colorBtnSecondaryTextHover)",
btnSecondaryTextActive: "var(--colorBtnSecondaryTextActive)",
btnSecondaryBorderBase: "var(--colorBtnSecondaryBorderBase)"
});
import {
colorColor,
colorBtn
} from "../../stylex/tokens/colors.stylex";
import {
measuresSpacing,
measuresBorderWidth,
measuresBorderRadius
} from "../../stylex/tokens/measures.stylex";
const BUTTON_STYLE = stylex.create({
default: {
cursor: "pointer",
borderWidth: measuresBorderWidth.borderWidthBtn,
borderStyle: "solid",
borderRadius: measuresBorderRadius.borderRadiusBtn,
},
disabled: {
color: colorColor.colorDisabledText,
backgroundColor: colorColor.colorDisabledBg,
borderColor: colorColor.colorDisabledBorder,
cursor: "not-allowed",
},
primary: {
color: {
default: colorBtn.btnPrimaryTextBase,
":hover": colorBtn.btnPrimaryTextHover,
},
backgroundColor: {
default: colorBtn.btnPrimaryBgBase,
":hover": colorBtn.btnPrimaryBgHover,
},
borderColor: {
default: colorBtn.btnPrimaryBgBase,
":hover": colorBtn.btnPrimaryBgHover,
},
},
secondary: {
color: {
default: colorBtn.btnSecondaryTextBase,
":hover": colorBtn.btnSecondaryTextHover,
},
backgroundColor: {
default: colorBtn.btnSecondaryBgBase,
":hover": colorBtn.btnSecondaryBgHover,
},
borderColor: {
default: colorBtn.btnSecondaryBorderBase,
":hover": colorBtn.btnSecondaryBgHover,
},
},
small: {
paddingInline: measuresSpacing.spacingBtnSmallPaddingInline,
paddingBlock: measuresSpacing.spacingBtnSmallPaddingBlock,
fontSize: "12px",
lineHeight: "1",
},
medium: {
paddingInline: measuresSpacing.spacingBtnMediumPaddingInline,
paddingBlock: measuresSpacing.spacingBtnMediumPaddingBlock,
fontSize: "16px",
lineHeight: "1.25",
},
large: {
paddingInline: {
default: measuresSpacing.spacingBtnLargePaddingInline,
"@media (width <= 1024px)": measuresSpacing.spacingBtnMediumPaddingInline,
},
paddingBlock: {
default: measuresSpacing.spacingBtnLargePaddingBlock,
"@media (width <= 1024px)": measuresSpacing.spacingBtnMediumPaddingBlock,
},
fontSize: "18px",
lineHeight: "1.5",
}
});
export default BUTTON_STYLE;
import * as stylex from "@stylexjs/stylex";
import { StylexTestComponentProps } from "./StylexTestComponent.types";
import BUTTON_STYLE from "./StylexTestComponent.styles";
export const StylexTestComponent: React.FC<StylexTestComponentProps> = ({
variant = "primary",
size = "medium",
disabled,
children,
style
}) => {
return (
<button {...stylex.props(
BUTTON_STYLE.default,
BUTTON_STYLE[variant],
BUTTON_STYLE[size],
disabled && BUTTON_STYLE.disabled,
style)}
disabled={disabled}
aria-disabled={disabled}>
{children}
</button>
);
}; But what if I want to wrap all the variables in an index file that I want to import, as we are used to, I always get the same message: Only static values are allowed inside of a stylex.create() call. export * from "./colors.stylex";
export * from "./fonts.stylex";
export * from "./gradients.stylex";
export * from "./measures.stylex";
export * from "./shadows.stylex"; If I name the index like index.stylex.ts, it works fine but the custom css properties that styleX generates does't contain any values. I need to distribute styleX variables that contain design tokens from Figma in the form of an NPM package, but the actual logic of how styleX works doesn't allow me to do that, or it's not documented. Is this possible? Alternatively, how do I achieve this? @nmn The idea of using it is: import { whatever } from @my/stylex/variables My custom styleX css definitions in the current application. |
Beta Was this translation helpful? Give feedback.
-
I was wondering if there was any way to get imported values working in StyleX like so:
I cannot tell If this is a supported pattern. I am currently getting the error
Only static values are allowed inside of a stylex.create() call.
Beta Was this translation helpful? Give feedback.
All reactions