From 5bf3be5ae2f87a93926929ec7e7a9003d621dd08 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 23 Feb 2024 18:41:13 +0700 Subject: [PATCH 1/6] add more content --- packages/zero-runtime/README.md | 162 +++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/packages/zero-runtime/README.md b/packages/zero-runtime/README.md index 514eb20d7c4fae..720daa0bbe87c8 100644 --- a/packages/zero-runtime/README.md +++ b/packages/zero-runtime/README.md @@ -2,6 +2,7 @@ A zero-runtime CSS-in-JS library that extracts the colocated styles to their own CSS files at build-time. +- [Starter template](#starter-template) - [Getting started](#getting-started) - [Next.js](#nextjs) - [Vite](#vite) @@ -18,6 +19,26 @@ A zero-runtime CSS-in-JS library that extracts the colocated styles to their own - [Color schemes](#color-schemes) - [Switching color schemes](#switching-color-schemes) - [TypeScript](#typescript) +- [How-to guides](#how-to-guides) + - [Coming from Emotion or styled-components](#coming-from-emotion-or-styled-components) + +## Starter template + +Use the following commands to create a new project with the latest version of the framework and zero-runtime (for existing projects, see [Getting started](#getting-started)): + +**Next.js template**: + +```bash +curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/zero-nextjs +cd zero-nextjs +``` + +**Vite template**: + +```bash +curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/zero-vite +cd zero-vite +``` ## Getting started @@ -132,7 +153,7 @@ Use the `variants` key to define styles for a combination of the component's pro Each variant is an object with `props` and `style` keys. The styles are applied when the component's props match the `props` object. -**Example 1**: A button component with `small` and `large` sizes: +**Example 1** — A button component with `small` and `large` sizes: ```jsx const Button = styled('button')({ @@ -156,7 +177,7 @@ const Button = styled('button')({ ; // padding: 0.5rem ``` -**Example 2**: A button component with variants and colors: +**Example 2** — A button component with variants and colors: ```jsx const Button = styled('button')({ @@ -177,7 +198,7 @@ const Button = styled('button')({ ; ``` -**Example 3**: Apply styles based on a condition: +**Example 3** — Apply styles based on a condition: The value of the `props` can be a function that returns a boolean. If the function returns `true`, the styles are applied. @@ -195,6 +216,37 @@ const Button = styled('button')({ }); ``` +Note that the `props` function will not work if it is inside another closure, for example, inside an array.map: + +```jsx +const Button = styled('button')({ + border: 'none', + padding: '0.75rem', + // ...other base styles + variants: ['red', 'blue', 'green'].map((item) => ({ + props: (props) => { + // ❌ Cannot access `item` in this closure + return props.color === item && !props.disabled; + }, + style: { backgroundColor: 'tomato' }, + })), +}); +``` + +Instead, use plain objects to define the variants: + +```jsx +const Button = styled('button')({ + border: 'none', + padding: '0.75rem', + // ...other base styles + variants: ['red', 'blue', 'green'].map((item) => ({ + props: { color: item, disabled: false }, + style: { backgroundColor: 'tomato' }, + })), +}); +``` + #### Styling based on runtime values > 💡 This approach is recommended when the value of a prop is **unknown** ahead of time or possibly unlimited values, e.g. styling based on the user's input. @@ -451,3 +503,107 @@ declare module '@mui/zero-runtime/theme' { } } ``` + +## How-to guides + +### Coming from Emotion or styled-components + +Emotion and styled-components are runtime CSS-in-JS libraries. What you write in your styles is what you get in the final bundle which means that the styles can be as dynamic as you want with the trade-offs of bundle size and performance overhead. + +Zero-runtime, on the other hand, extracts CSS at build time and replaces the JS code with hashed classnames and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using javascript callbacks or variables in zero-runtime APIs. + +Here are some common patterns and how to achieve them with zero-runtime: + +1. A fixed set of styles + +In Emotion or styled-components, you can use props to create styles conditionally: + +```js +const Flex = styled('div')((props) => ({ + display: 'flex', + ...(props.vertical // ❌ Zero Runtime will throw an error + ? { + flexDirection: 'column', + paddingBlock: '1rem', + } + : { + paddingInline: '1rem', + }), +})); +``` + +But in zero-runtime, you need to define all of the styles ahead of time using the `variants` key: + +```js +const Flex = styled('div')((props) => ({ + display: 'flex', + variants: [ + { + props: { vertical: true }, + style: { + flexDirection: 'column', + paddingBlock: '1rem', + }, + }, + { + props: { vertical: false }, + style: { + paddingInline: '1rem', + }, + }, + ], +})); +``` + +> 💡 Keep in mind that `variants` is for fixed values of props, for example component's colors, sizes, states. + +2. Programatically generated styles + +For emotion and styled-components, the styles will be different on each render and instances because the styles are generated at runtime: + +```js +function randomBetween(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1) + min); +} +function generateBubbleVars() { + return ` + --x: ${randomBetween(10, 90)}%; + --y: ${randomBetween(15, 85)}%; + `; +} + +function App() { + return ( +
+ {[...Array(10)].map((_, index) => ( +
+ ))} +
+ ) +} +``` + +However, in zero-runtime, all of the instances will have the same styles and won't change between renders because the styles are extracted at build time. + +To achieve the same result, you need to move the dynamic logic to props and pass the value to CSS variables instead: + +```js +function randomBetween(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1) + min); +} + +const Bubble = styled('div')({ + '--x': props => props.x, + '--y': props => props.y, +}); + +function App() { + return ( +
+ {[...Array(10)].map((_, index) => ( + + ))} +
+ ) +} +``` From 21d0d5fa471131cd2595cb8dff13fd9b45a22fb4 Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Mon, 26 Feb 2024 20:23:53 +0700 Subject: [PATCH 2/6] Apply suggestions from code review Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Signed-off-by: Siriwat K --- packages/zero-runtime/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/zero-runtime/README.md b/packages/zero-runtime/README.md index 720daa0bbe87c8..414ae03a3ebe83 100644 --- a/packages/zero-runtime/README.md +++ b/packages/zero-runtime/README.md @@ -24,7 +24,7 @@ A zero-runtime CSS-in-JS library that extracts the colocated styles to their own ## Starter template -Use the following commands to create a new project with the latest version of the framework and zero-runtime (for existing projects, see [Getting started](#getting-started)): +Use the following commands to create a new project with the latest framework version and zero-runtime (for existing projects, see [Getting started](#getting-started)): **Next.js template**: @@ -216,7 +216,7 @@ const Button = styled('button')({ }); ``` -Note that the `props` function will not work if it is inside another closure, for example, inside an array.map: +Note that the `props` function will not work if it is inside another closure, for example, inside an `array.map`: ```jsx const Button = styled('button')({ @@ -510,11 +510,11 @@ declare module '@mui/zero-runtime/theme' { Emotion and styled-components are runtime CSS-in-JS libraries. What you write in your styles is what you get in the final bundle which means that the styles can be as dynamic as you want with the trade-offs of bundle size and performance overhead. -Zero-runtime, on the other hand, extracts CSS at build time and replaces the JS code with hashed classnames and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using javascript callbacks or variables in zero-runtime APIs. +On the other hand, zero-runtime extracts CSS at build time and replaces the JS code with hashed class names and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using JavaScript callbacks or variables in zero-runtime APIs. Here are some common patterns and how to achieve them with zero-runtime: -1. A fixed set of styles +1. **Fixed set of styles** In Emotion or styled-components, you can use props to create styles conditionally: @@ -555,11 +555,11 @@ const Flex = styled('div')((props) => ({ })); ``` -> 💡 Keep in mind that `variants` is for fixed values of props, for example component's colors, sizes, states. +> 💡 Keep in mind that the `variants` key is for fixed values of props, for example, a component's colors, sizes, and states. -2. Programatically generated styles +2. **Programatically generated styles** -For emotion and styled-components, the styles will be different on each render and instances because the styles are generated at runtime: +For Emotion and styled-components, the styles will be different on each render and instance because the styles are generated at runtime: ```js function randomBetween(min: number, max: number) { @@ -583,7 +583,7 @@ function App() { } ``` -However, in zero-runtime, all of the instances will have the same styles and won't change between renders because the styles are extracted at build time. +However, in zero-runtime, all instances will have the same styles and won't change between renders because the styles are extracted at build time. To achieve the same result, you need to move the dynamic logic to props and pass the value to CSS variables instead: From 9049ea0416e0d734f8edd702c77cd1080ef97c89 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 28 Feb 2024 14:03:48 +0700 Subject: [PATCH 3/6] update readme --- packages/zero-runtime/README.md | 35 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/zero-runtime/README.md b/packages/zero-runtime/README.md index 414ae03a3ebe83..d40acc3349beb7 100644 --- a/packages/zero-runtime/README.md +++ b/packages/zero-runtime/README.md @@ -2,7 +2,6 @@ A zero-runtime CSS-in-JS library that extracts the colocated styles to their own CSS files at build-time. -- [Starter template](#starter-template) - [Getting started](#getting-started) - [Next.js](#nextjs) - [Vite](#vite) @@ -22,29 +21,22 @@ A zero-runtime CSS-in-JS library that extracts the colocated styles to their own - [How-to guides](#how-to-guides) - [Coming from Emotion or styled-components](#coming-from-emotion-or-styled-components) -## Starter template +## Getting started -Use the following commands to create a new project with the latest framework version and zero-runtime (for existing projects, see [Getting started](#getting-started)): +Zero-runtime supports Next.js and Vite with future support for more bundlers. You must install the corresponding plugin, as shown below. -**Next.js template**: +### Next.js -```bash -curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/zero-nextjs -cd zero-nextjs -``` +#### Starter template -**Vite template**: +Use the following commands to create a new Next.js project with Zero Runtime setup: ```bash -curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/zero-vite -cd zero-vite +curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/zero-nextjs +cd zero-nextjs ``` -## Getting started - -Zero-runtime supports Next.js and Vite with future support for more bundlers. You must install the corresponding plugin, as shown below. - -### Next.js +#### Manual installation ```bash npm install @mui/zero-runtime @@ -63,6 +55,17 @@ module.exports = withZeroPlugin({ ### Vite +#### Starter template + +Use the following commands to create a new Vite project with Zero Runtime setup: + +```bash +curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/zero-vite +cd zero-vite +``` + +#### Manual installation + ```bash npm install @mui/zero-runtime npm install --save-dev @mui/zero-vite-plugin From 2ae791a6b59e968f5c2147a8887cc7fc8ffb8724 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Mon, 4 Mar 2024 15:07:23 +0700 Subject: [PATCH 4/6] update zero to pigment --- packages/pigment-react/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/pigment-react/README.md b/packages/pigment-react/README.md index 91da4105c2e786..5a2d9f9756917c 100644 --- a/packages/pigment-react/README.md +++ b/packages/pigment-react/README.md @@ -1,6 +1,6 @@ # Pigment CSS -A zero-runtime CSS-in-JS library that extracts the colocated styles to their own CSS files at build-time. +A Pigment CSS CSS-in-JS library that extracts the colocated styles to their own CSS files at build-time. - [Getting started](#getting-started) - [Next.js](#nextjs) @@ -32,8 +32,8 @@ Pigment CSS supports Next.js and Vite with support for more bundlers in future. Use the following commands to create a new Next.js project with Zero Runtime setup: ```bash -curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/zero-nextjs -cd zero-nextjs +curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/pigmentcss-nextjs +cd pigmentcss-nextjs ``` #### Manual installation @@ -60,8 +60,8 @@ module.exports = withPigment({ Use the following commands to create a new Vite project with Zero Runtime setup: ```bash -curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/zero-vite -cd zero-vite +curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/pigmentcss-vite +cd pigmentcss-vite ``` #### Manual installation @@ -513,9 +513,9 @@ declare module '@pigmentcss/react/theme' { Emotion and styled-components are runtime CSS-in-JS libraries. What you write in your styles is what you get in the final bundle which means that the styles can be as dynamic as you want with the trade-offs of bundle size and performance overhead. -On the other hand, zero-runtime extracts CSS at build time and replaces the JS code with hashed class names and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using JavaScript callbacks or variables in zero-runtime APIs. +On the other hand, Pigment CSS extracts CSS at build time and replaces the JS code with hashed class names and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using JavaScript callbacks or variables in Pigment CSS APIs. -Here are some common patterns and how to achieve them with zero-runtime: +Here are some common patterns and how to achieve them with Pigment CSS: 1. **Fixed set of styles** @@ -535,7 +535,7 @@ const Flex = styled('div')((props) => ({ })); ``` -But in zero-runtime, you need to define all of the styles ahead of time using the `variants` key: +But in Pigment CSS, you need to define all of the styles ahead of time using the `variants` key: ```js const Flex = styled('div')((props) => ({ @@ -586,7 +586,7 @@ function App() { } ``` -However, in zero-runtime, all instances will have the same styles and won't change between renders because the styles are extracted at build time. +However, in Pigment CSS, all instances will have the same styles and won't change between renders because the styles are extracted at build time. To achieve the same result, you need to move the dynamic logic to props and pass the value to CSS variables instead: From dca9a14ee87c749f3585c8029dcf2818ab87769f Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Tue, 5 Mar 2024 14:31:31 +0700 Subject: [PATCH 5/6] update readme --- packages/pigment-react/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/pigment-react/README.md b/packages/pigment-react/README.md index fbb0397a4721e8..761c80e51f7fb5 100644 --- a/packages/pigment-react/README.md +++ b/packages/pigment-react/README.md @@ -1,6 +1,6 @@ # Pigment CSS -A Pigment CSS CSS-in-JS library that extracts the colocated styles to their own CSS files at build-time. +Pigment CSS is a zero-runtime CSS-in-JS library that extracts the colocated styles to their own CSS files at build time. - [Getting started](#getting-started) - [Why this project exists?](#why-choose-pigment-css) @@ -39,7 +39,7 @@ Pigment CSS is built on top of [WyW-in-JS](https://wyw-in-js.dev/), enabling us #### Starter template -Use the following commands to create a new Next.js project with Zero Runtime setup: +Use the following commands to create a new Next.js project with Pigment CSS set up: ```bash curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/pigmentcss-nextjs @@ -67,7 +67,7 @@ module.exports = withPigment({ #### Starter template -Use the following commands to create a new Vite project with Zero Runtime setup: +Use the following commands to create a new Vite project with Pigment CSS set up: ```bash curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/pigmentcss-vite @@ -272,7 +272,7 @@ const Heading = styled('h1')({ }); ``` -Zero-runtime will replace the callback with a CSS variable and inject the value through inline style. This makes it possible to create a static CSS file while still allowing dynamic styles. +Pigment CSS will replace the callback with a CSS variable and inject the value through inline style. This makes it possible to create a static CSS file while still allowing dynamic styles. ```css .Heading_class_akjsdfb { @@ -377,7 +377,7 @@ const Heading = styled('h1')(({ theme }) => ({ #### CSS variables support -Zero-runtime can generate CSS variables from the theme values when you wrap your theme with `extendTheme` utility. For example, in a `next.config.js` file: +Pigment CSS can generate CSS variables from the theme values when you wrap your theme with `extendTheme` utility. For example, in a `next.config.js` file: ```js const { withPigment, extendTheme } = require('@pigment-css/nextjs-plugin'); @@ -521,9 +521,9 @@ declare module '@pigment-css/react/theme' { ### Coming from Emotion or styled-components -Emotion and styled-components are runtime CSS-in-JS libraries. What you write in your styles is what you get in the final bundle which means that the styles can be as dynamic as you want with the trade-offs of bundle size and performance overhead. +Emotion and styled-components are runtime CSS-in-JS libraries. What you write in your styles is what you get in the final bundle, which means the styles can be as dynamic as you want with bundle size and performance overhead trade-offs. -On the other hand, Pigment CSS extracts CSS at build time and replaces the JS code with hashed class names and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using JavaScript callbacks or variables in Pigment CSS APIs. +On the other hand, Pigment CSS, as a zero-runtime library, extracts CSS at build time and replaces the JS code with hashed class names and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using JavaScript callbacks or variables in Pigment CSS's APIs. Here are some common patterns and how to achieve them with Pigment CSS: @@ -534,7 +534,7 @@ In Emotion or styled-components, you can use props to create styles conditionall ```js const Flex = styled('div')((props) => ({ display: 'flex', - ...(props.vertical // ❌ Zero Runtime will throw an error + ...(props.vertical // ❌ Pigment CSS will throw an error ? { flexDirection: 'column', paddingBlock: '1rem', @@ -596,7 +596,7 @@ function App() { } ``` -However, in Pigment CSS, all instances will have the same styles and won't change between renders because the styles are extracted at build time. +However, in Pigment CSS with the same code as above, all instances will have the same styles and won't change between renders because the styles are extracted at build time. To achieve the same result, you need to move the dynamic logic to props and pass the value to CSS variables instead: From ff6f85265a4e6e3e72053f4ebeac99e9ca9b760f Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Fri, 8 Mar 2024 10:27:37 +0700 Subject: [PATCH 6/6] udpate readme --- packages/pigment-react/README.md | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/packages/pigment-react/README.md b/packages/pigment-react/README.md index 761c80e51f7fb5..afca1fa7e9e461 100644 --- a/packages/pigment-react/README.md +++ b/packages/pigment-react/README.md @@ -37,17 +37,6 @@ Pigment CSS is built on top of [WyW-in-JS](https://wyw-in-js.dev/), enabling us ### Next.js -#### Starter template - -Use the following commands to create a new Next.js project with Pigment CSS set up: - -```bash -curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/pigmentcss-nextjs -cd pigmentcss-nextjs -``` - -#### Manual installation - ```bash npm install @pigment-css/react npm install --save-dev @pigment-css/nextjs-plugin @@ -65,17 +54,6 @@ module.exports = withPigment({ ### Vite -#### Starter template - -Use the following commands to create a new Vite project with Pigment CSS set up: - -```bash -curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/pigmentcss-vite -cd pigmentcss-vite -``` - -#### Manual installation - ```bash npm install @pigment-css/react npm install --save-dev @pigment-css/vite-plugin @@ -523,7 +501,7 @@ declare module '@pigment-css/react/theme' { Emotion and styled-components are runtime CSS-in-JS libraries. What you write in your styles is what you get in the final bundle, which means the styles can be as dynamic as you want with bundle size and performance overhead trade-offs. -On the other hand, Pigment CSS, as a zero-runtime library, extracts CSS at build time and replaces the JS code with hashed class names and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using JavaScript callbacks or variables in Pigment CSS's APIs. +On the other hand, Pigment CSS extracts CSS at build time and replaces the JS code with hashed class names and some CSS variables. This means that it has to know all of the styles to be extracted ahead of time, so there are rules and limitations that you need to be aware of when using JavaScript callbacks or variables in Pigment CSS's APIs. Here are some common patterns and how to achieve them with Pigment CSS: