Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Write CSS-in-JS with atomic support. Like Facebook's Stylex!

License

NotificationsYou must be signed in to change notification settings

reacttips-dev/stylex

Repository files navigation


Write CSS in JS with Atomic first, like Facebook do!

NOTE: The idea of stylex originated from Facebook.

The underlying idea was to not discard idiomatic CSS but to make iteasier to maintain and keep the good parts of CSS that developers areused to enjoying. The number one priority was readability andmaintainability, which are issues compounded at scale.

See Facebook React conf video for more about Stylex:Click here

Yarn users:

yarn add @ladifire-opensource/stylex

Npm users:

npm install @ladifire-opensource/stylex

The second step is depending on what bundler you use, for webpack youneed to install a webpack plugin

yarn add @ladifire-opensource/stylex-webpack-plugin

If you're usingNextjs:

yarn add @ladifire-opensource/stylex-nextjs-plugin

First, we need importstylex-webpack-plugin:

constStylexPlugin=require("@ladifire-opensource/stylex-webpack-plugin");

Then, inplugins section, add this:

plugins:[//...other pluginsnewStylexPlugin(),

Last thing, add this inrules section:

rules:[{test:/\.(ts|tsx)$/,use:[// ...keeps your other loaders here// and stylex-loader goes here{loader:StylexPlugin.loader,options:{inject:false,},},],},

This is example of Babel config with stylex:

/** * Copyright (c) Ladifire, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. *//*eslint-env node*/module.exports={presets:["@babel/react","@babel/env","@babel/preset-typescript"],plugins:["@babel/plugin-syntax-dynamic-import","@babel/plugin-proposal-object-rest-spread","@babel/plugin-transform-runtime",["@babel/plugin-transform-modules-commonjs"],["@babel/plugin-transform-spread",{loose:true,},],["@babel/plugin-proposal-decorators",{legacy:true}],["@babel/plugin-proposal-class-properties",{loose:true}],["@ladifire-opensource/babel-plugin-transform-stylex",{inject:true,// will inject compiled css to stylesheet in head},],],};

First thing, you need addnext-transpile-modules to your project.

Just run:

yarn add -D next-transpile-modules

Then innext.config.js, add these lines:

constwithTM=require("next-transpile-modules")(["@ladifire-opensource/stylex"],{unstable_webpack5:true});constwithStylex=require("@ladifire-opensource/stylex-nextjs-plugin");module.exports=withStylex({inject:true,// for nextjs, we must inject style to head})(withTM());

Add these lines invue.config.js:

constStylexPlugin=require("@ladifire-opensource/stylex-webpack-plugin");module.exports={configureWebpack:{module:{rules:[{test:/\.(tsx|ts|js|mjs|jsx)$/,use:StylexPlugin.loader,},],},plugins:[newStylexPlugin()],},};

Then you can write like this in your.vue:

<script>import stylex from '@ladifire-opensource/stylex'const styles = stylex.create({button:{borderRadius:8,padding:16,backgroundColor:"#1DA1F2",color:"#fff"},});export default{name:'HelloWorld',props:{msg:String},computed:{buttonClasses(){returnstylex(styles.button);}}}</script>

Followcraco.js installation guide.

Finally incraco.config.js add:

module.exports={// ...babel:{/// ...plugins:[/// ...["@ladifire-opensource/babel-plugin-transform-stylex",{inject:true,},],],},};

Under construction!!!

There're some methods you can you with stylex:

Create new stylex object(stylex.create)

This method will create a new stylex object:

importstylexfrom"@ladifire-opensource/stylex";conststyles=stylex.create({root:{fontWeight:700,color:"blue",},button:{borderRadius:8,},});

Then we can use as:

<divclassName={stylex(styles.root)}>Component</div>

The arguments ofstylex(...args) can be separated by comma:

<divclassName={stylex(styles.root,styles.button)}>Component</div>

or as an array:

<divclassName={stylex([styles.root,styles.button])}>Component</div>

Dedupe stylex objects(stylex.dedupe)

This method will dedupe (override) duplicate style properties:

<divclassName={stylex.dedupe({color:"var(--primary-text)",},isError      ?{color:"var(--negative)",}      :null)}>  Dedupe</div>

Create a keyframes animation name(stylex.keyframes)

letj=stylex.create({dark:{backgroundColor:"var(--placeholder-icon)",},paused:{animationPlayState:"paused",},root:{animationDirection:"alternate",animationDuration:"1s",animationIterationCount:"infinite",animationName:stylex.keyframes({"0%":{opacity:0.25,},"100%":{opacity:1,},}),animationTimingFunction:"steps(10,end)",backgroundColor:"var(--wash)",opacity:0.25,},});

Compose (merge) stylex objects(stylex.compose)

consts=stylex.compose({color:"red",backgroundColor:"blue",},{backgroundColor:"white",});

The above code will transformed to:

consts={color:"a512sdfe5",// redbackgroundColor:"wer115asse",// white};

Quick uses

Describe some common static methods for quick uses, eg: stylex.absolute, ...

Inject css to compiled js

By default, stylex will inject css to stylesheet object in<head> of html document.

There is no extra reference links of stylesheets to inject.

The webpack setup should be:

...rules:[{test:/\.(ts|tsx)$/,exclude:STANDARD_EXCLUDE,use:[babelLoaderConfig,{loader:StylexPlugin.loader,options:{inject:true,},},],},...

In the compiled js, there're something like this will be injected:

inject('.avcdd15645{color: "red"}');

Then the stylex runtime code will excute theinject function and add'.avcdd15645{color: "red"}'to the stylesheet in the<head> section.

Separate css into .css files

In case you want to use stylex withmini-css-extract-plugin to seprate cssinto reference links, you can setup in your webpack config as bellow:

...constExtractTextPlugin=require('mini-css-extract-plugin');constStylexPlugin=require("@ladifire-opensource/stylex-webpack-plugin");...rules:[{test:/\.(ts|tsx)$/,exclude:STANDARD_EXCLUDE,use:[babelLoaderConfig,{loader:StylexPlugin.loader,options:{inject:false,// set false to ignore inject css to js},},],},...plugins:[newStylexPlugin(),newExtractTextPlugin({filename:'[name].[contentHash:11].css',chunkFilename:'[name].[contentHash:11].css',}),...

Babel

This is example of stylex's babel config:

module.exports={presets:["@babel/react","@babel/env","@babel/preset-typescript"],plugins:["@babel/plugin-syntax-dynamic-import","@babel/plugin-proposal-object-rest-spread","@babel/plugin-transform-runtime",["@babel/plugin-transform-modules-commonjs"],["@babel/plugin-transform-spread",{loose:true,},],["@babel/plugin-proposal-decorators",{legacy:true}],["@babel/plugin-proposal-class-properties",{loose:true}],["@ladifire-opensource/babel-plugin-transform-stylex",{inject:true,// will inject compiled css to stylesheet in head},],],};

SSR support

Seestylex-nextjs-examples for setup stylex with nextjs.

Others

Pass stylex through props (Reactjs)

If you using Reactjs, consider to usexstyle props to pass some stylex class fromparent to child. Let's see bellow example:

import*asReactfrom"react";importstylexfrom"@ladifire-opensource/stylex";importChildComponentfrom"./path/to/child";typeStyle="root";conststyles=stylex.create({root:{color:"red",},});constParent=()=>{return(<ChildComponentxstyle={styles.root}//...otherProps/>);};

Thexstyle prop is a good method because it helps to combine style props under one namespaceand doesn't populate the global orios environment and it looks similar to the goal ofsx prop.

Then in your child component you can usexstyle props as:

import*asReactfrom"react";importstylexfrom"@ladifire-opensource/stylex";conststyles=stylex.create({root:{backgroundColor:"red",},});constChildComponent=(props)=>{const{ xstyle}=props;return<divclassName={stylex(styles.root,xstyle)}>Child</div>;};

Theming with stylex

Stylex support multiple theming. A "theme" is declared by given it an object ofvariables, like this:

constdefaultThemeVariables={"primary-icon":"rgb(15, 20, 25)","primary-text":"rgb(15, 20, 25)","primary-text-on-media":"#FFFFFF",};

There're two theme objects in stylex:rootTheme andcustomTheme.To setrootTheme:

importCometStyleXSheetfrom"@ladifire-opensource/stylex-theme";...CometStyleXSheet.rootStyleSheet.setRootTheme(defaultThemeVariables);

andcustomTheme:

CometStyleXSheet.rootStyleSheet.setCustomTheme(customThemeVariables);

To change theme:

CometStyleXSheet.rootStyleSheet.toggleCustomTheme(!isCustomThemeActive);

This is example for React users:

importCometStyleXSheetfrom"@ladifire-opensource/stylex-theme";import{themeDataBase}from"./themeDataBase";import{themeDataCustom}from"./themeDataCustom";exportconstThemingExamples=()=>{React.useEffect(()=>{CometStyleXSheet.rootStyleSheet.setRootTheme(themeDataBase);CometStyleXSheet.rootStyleSheet.setCustomTheme(themeDataCustom);},[]);const[isDark,setIsDark]=React.useState<boolean>(()=>false);consttoggleIsDark=React.useCallback((event:React.ChangeEvent<HTMLInputElement>)=>{consttarget=event.target;setIsDark(target.checked);CometStyleXSheet.rootStyleSheet.toggleCustomTheme(!isDark);},[isDark,setIsDark]);// ...};

Thanks to

  • We'd like to send a big thanks to: johanholmerin for style9 (an other stylex cover)
  • We'd like to thanks Facebook very much (most of javascript code in stylex is re-write from built code of Facebook)

Contributing

Contributions are always welcome, no matter how large or small!

Setup

Fork thestylex repository to your GitHub Account.

Then, run:yarn install

To see reactjs demo, cd tostylex-reactjs-examples and following steps inREADME.md to run Reactjs demo

Join Stylex Community (Facebook group)

Visitthis link to join Stylex community.

License

Stylex isMIT licensed.


[8]ページ先頭

©2009-2025 Movatter.jp