ladifire-opensource / Stylex

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

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Stylex

Tailwind Styled Component
Create Tailwind CSS React components like styled components with class names on multiple lines and conditional class rendering
Stars: ✭ 57 (-36.67%)
Mutual labels:  css-in-js
Stylelint
A mighty, modern linter that helps you avoid errors and enforce conventions in your styles.
Stars: ✭ 9,350 (+10288.89%)
Mutual labels:  css-in-js
React Image Smooth Loading
[not maintained] Images which just flick to appear aren't cool. Images which appear smoothly with a fade like Instagram are cool
Stars: ✭ 84 (-6.67%)
Mutual labels:  css-in-js
Vue Styled Components
Visual primitives for the component age. A simple port for Vue of styled-components 💅
Stars: ✭ 1,114 (+1137.78%)
Mutual labels:  css-in-js
Css In Js Precompiler
WORK IN PROGRESS: Precompiles CSS-in-JS objects to CSS strings
Stars: ✭ 71 (-21.11%)
Mutual labels:  css-in-js
React Jss
JSS integration for React (Migrated to a Monorepo it JSS repository)
Stars: ✭ 1,212 (+1246.67%)
Mutual labels:  css-in-js
Snackui
SnackUI 🍑 - the final React style library. With an *optimizing compiler* that lets you write views naturally, with easier DX, working on native and web at once, all while being faster than hand-rolling your own CSS.
Stars: ✭ 55 (-38.89%)
Mutual labels:  css-in-js
Scale
The Scale library offers a set of customizable web components written with Stencil.js & TypeScript. The default theme of the library can be easily replaced so that a corresponding corporate identity of a dedicated brand can be represented.
Stars: ✭ 87 (-3.33%)
Mutual labels:  css-in-js
Bss
🎨 Better Style Sheets
Stars: ✭ 72 (-20%)
Mutual labels:  css-in-js
Clxx
Some lightweight H5 components and features
Stars: ✭ 79 (-12.22%)
Mutual labels:  css-in-js
Rosebox
CSS in Typescript
Stars: ✭ 62 (-31.11%)
Mutual labels:  css-in-js
Immutable Styles
A library for styling web interfaces with a focus on predictability and robustness. It uses immutability to remove side effects often tied to CSS, allowing UI bugs to be caught ahead of time!
Stars: ✭ 69 (-23.33%)
Mutual labels:  css-in-js
Horror
😱 React HTML elements with CSS-in-JS
Stars: ✭ 78 (-13.33%)
Mutual labels:  css-in-js
Css In Js Utils
Useful utility functions for CSS in JS solutions
Stars: ✭ 61 (-32.22%)
Mutual labels:  css-in-js
Nano Style
React functional CSS-in-JS
Stars: ✭ 85 (-5.56%)
Mutual labels:  css-in-js
Cabana React
A design system built especially for both Sketch and React. 💎⚛️
Stars: ✭ 58 (-35.56%)
Mutual labels:  css-in-js
Styled Components Rhythm
Vertical Rhythm and Font Baselines with Styled Components
Stars: ✭ 76 (-15.56%)
Mutual labels:  css-in-js
React Usestyles
🖍 Style components using React hooks. Abstracts the styling library away.
Stars: ✭ 89 (-1.11%)
Mutual labels:  css-in-js
Compiled
A familiar and performant compile time CSS-in-JS library for React.
Stars: ✭ 1,235 (+1272.22%)
Mutual labels:  css-in-js
Moo Css
模块化面向对象的css写法规范策略。适用于大中小型C端项目样式开发,旨在提高开发和维护效率。
Stars: ✭ 79 (-12.22%)
Mutual labels:  css-in-js


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

About Stylex

NOTE: The idea of stylex originated from Facebook.

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

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

Installation

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 you need to install a webpack plugin

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

If you're using Nextjs:

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

Setup with Webpack

First, we need import stylex-webpack-plugin:

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

Then, in plugins section, add this:

 plugins: [
    //...other plugins

    new StylexPlugin(),

Last thing, add this in rules section:

rules: [
      {
        test: /\.(ts|tsx)$/,
        use: [
          // ...keeps your other loaders here

          // and stylex-loader goes here
          {
            loader: StylexPlugin.loader,
            options: {
              inject: false,
            },
          },
        ],
      },

Setup with Babel

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
      },
    ],
  ],
};

Setup with Nextjs

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

Just run:

yarn add -D next-transpile-modules

Then in next.config.js, add these lines:

const withTM = require("next-transpile-modules")(
  ["@ladifire-opensource/stylex"],
  { unstable_webpack5: true }
);
const withStylex = require("@ladifire-opensource/stylex-nextjs-plugin");

module.exports = withStylex({
  inject: true, // for nextjs, we must inject style to head
})(withTM());

Setup with Vue

Add these lines in vue.config.js:

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

module.exports = {
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.(tsx|ts|js|mjs|jsx)$/,
          use: StylexPlugin.loader,
        },
      ],
    },
    plugins: [new StylexPlugin()],
  },
};

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() {
      return stylex(styles.button);
    }
  }
}
</script>

Setup with Create React App

Follow craco.js installation guide.

Finally in cracro.config.js add:

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

Setup with Angular

Under construction!!!

Examples

How to use stylex?

There're some methods you can you with stylex:

Create new stylex object (stylex.create)

This method will create a new stylex object:

import stylex from "@ladifire-opensource/stylex";

const styles = stylex.create({
  root: {
    fontWeight: 700,
    color: "blue",
  },
  button: {
    borderRadius: 8,
  },
});

Then we can use as:

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

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

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

or as an array:

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

Dedupe stylex objects (stylex.dedupe)

This method will dedupe (override) duplicate style properties:

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

Create a keyframes animation name (stylex.keyframes)

let j = 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)

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

The above code will transformed to:

const s = {
  color: "a512sdfe5", // red
  backgroundColor: "wer115asse", // white
};

Quick uses

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

Plugin options

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 the inject 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 with mini-css-extract-plugin to seprate css into reference links, you can setup in your webpack config as bellow:

...
const ExtractTextPlugin = require('mini-css-extract-plugin');
const StylexPlugin = 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: [
   new StylexPlugin(),
   new ExtractTextPlugin({
      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

See stylex-nextjs-examples for setup stylex with nextjs.

Others

Pass stylex through props (Reactjs)

If you using Reactjs, consider to use xstyle props to pass some stylex class from parent to child. Let's see bellow example:

import * as React from "react";
import stylex from "@ladifire-opensource/stylex";
import ChildComponent from "./path/to/child";

type Style = "root";

const styles = stylex.create({
  root: {
    color: "red",
  },
});

const Parent = () => {
  return (
    <ChildComponent
      xstyle={styles.root}
      //...otherProps
    />
  );
};

The xstyle prop is a good method because it helps to combine style props under one namespace and doesn't populate the global orios environment and it looks similar to the goal of sx prop.

Then in your child component you can use xstyle props as:

import * as React from "react";

import stylex from "@ladifire-opensource/stylex";

const styles = stylex.create({
  root: {
    backgroundColor: "red",
  },
});

const ChildComponent = (props) => {
  const { xstyle } = props;

  return <div className={stylex(styles.root, xstyle)}>Child</div>;
};

Theming with stylex

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

const defaultThemeVariables = {
  "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 and customTheme. To set rootTheme:

import CometStyleXSheet from "@ladifire-opensource/stylex-theme";

...

CometStyleXSheet.rootStyleSheet.setRootTheme(defaultThemeVariables);

and customTheme:

CometStyleXSheet.rootStyleSheet.setCustomTheme(customThemeVariables);

To change theme:

CometStyleXSheet.rootStyleSheet.toggleCustomTheme(!isCustomThemeActive);

This is example for React users:

import CometStyleXSheet from "@ladifire-opensource/stylex-theme";

import { themeDataBase } from "./themeDataBase";
import { themeDataCustom } from "./themeDataCustom";

export const ThemingExamples = () => {
  React.useEffect(() => {
    CometStyleXSheet.rootStyleSheet.setRootTheme(themeDataBase);
    CometStyleXSheet.rootStyleSheet.setCustomTheme(themeDataCustom);
  }, []);

  const [isDark, setIsDark] = React.useState < boolean > (() => false);
  const toggleIsDark = React.useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      const target = 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 the stylex repository to your GitHub Account.

Then, run: yarn install

To see reactjs demo, cd to stylex-reactjs-examples and following steps in README.md to run Reactjs demo

Join Stylex Community (Facebook group)

Visit this link to join Stylex community.

License

Stylex is MIT licensed.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].