From 222f5bc6040d0f63fb2df6cd4e7746412f1dcfa0 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Tue, 25 Jun 2024 23:16:13 +0800 Subject: [PATCH] feat: add stylex.md --- README.md | 3 +- assets/stylex.svg | 1 + docs/quickreference.md | 2 +- docs/stylex.md | 1046 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1050 insertions(+), 2 deletions(-) create mode 100644 assets/stylex.svg create mode 100644 docs/stylex.md diff --git a/README.md b/README.md index 3df48b5..140e070 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,8 @@ Quick Reference [Stylus](./docs/stylus.md) [Sass](./docs/sass.md) [Less.js](./docs/lessjs.md) -[Tailwind CSS](./docs/tailwindcss.md) +[Tailwind CSS](./docs/tailwindcss.md) +[StyleX](./docs/stylex.md) ## Nodejs diff --git a/assets/stylex.svg b/assets/stylex.svg new file mode 100644 index 0000000..54cc442 --- /dev/null +++ b/assets/stylex.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/quickreference.md b/docs/quickreference.md index 7fb2ce8..c04ba83 100644 --- a/docs/quickreference.md +++ b/docs/quickreference.md @@ -1009,7 +1009,7 @@ H2 部分 - 5列效果展示 ... ``` -[#示例](https://github.com/jaywcjlove/reference/blob/ee03850619440e3700ed68ccc2ed21d3591a1490/docs/quickreference.md?plain=1#L1063-L1077) +[#示例](https://github.com/jaywcjlove/reference/blob/ee03850619440e3700ed68ccc2ed21d3591a1490/docs/quickreference.md?plain=1#L986-L991) ### Two diff --git a/docs/stylex.md b/docs/stylex.md new file mode 100644 index 0000000..31132c5 --- /dev/null +++ b/docs/stylex.md @@ -0,0 +1,1046 @@ +StyleX 备忘清单 +==== + +这是 [StyleX](https://github.com/facebook/stylex) 用户界面的样式系统的快速参考指南备忘单 + +入门 StyleX +--- + +### 介绍 + + +StyleX 是一个 CSS In JS 的用户界面的样式系统 + +- [StyleX Intellisense](https://marketplace.visualstudio.com/items?itemName=yash-singh.stylex) _VSCode 插件_ + +#### Vite + + +- [vite-plugin-stylex](https://www.npmjs.com/package/vite-plugin-stylex) +- [vite-plugin-stylex-dev](https://www.npmjs.com/package/vite-plugin-stylex-dev) + +#### Babel 插件 + + +- [tailwind-to-stylex](https://www.npmjs.com/package/tailwind-to-stylex) 支持在 Tailwind CSS 中使用 +- [@stylex-extend/babel-plugin](https://github.com/nonzzz/stylex-extend/tree/main/packages/babel-plugin) 使用 JSX 属性定义 StyleX + +#### Prettier + + +- [prettier-plugin-stylex-key-sort](https://github.com/nedjulius/prettier-plugin-stylex-key-sort) + +#### Bun + + +- [bun-plugin-stylex](https://www.npmjs.com/package/bun-plugin-stylex) + +#### 入门模板 + + +- [next.js](https://github.com/nmn/nextjs-app-dir-stylex) _支持 StyleX 的 next.js 项目_ +- [qwik](https://github.com/nmn/qwik-stylex) _使用 StyleX 和 tailwind-to-stylex 的 Qwik 项目_ +- [docusaurus 3](https://github.com/nmn/docusaurus-stylex) _支持 StyleX 的 docusaurus 3 项目_ +- [SvelteKit](https://github.com/nmn/sveltekit-stylex) _支持 StyleX 的 SvelteKit 项目_ + +### 配置编译器 + +```js +import plg from '@stylexjs/rollup-plugin'; + +const config = () => ({ + plugins: [ + plg({ ...options }) + ] +}) + +export default config; +``` + +### 使用样式 + + +```js +import * as React from 'react'; +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ ... }); +const colorStyles = stylex.create({ ... }); +``` + +在 [React](./react.md) 中使用 + +```jsx +function ReactDemo( + { color,isActive,style } +) { + return ( +
+ ); +} +``` + +### 定义样式 + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + root: { + width: '100%', + maxWidth: 800, + minHeight: 40, + }, +}); +``` + +样式是使用对象语法和 `create()` API 定义的 + +安装 +---- + + +### StyleX 运行时包 + + +```bash +npm install --save @stylexjs/stylex +``` + +### 编译器(生产) Rollup + + +```bash +npm install --save-dev @stylexjs/rollup-plugin +``` + +修改 Rollup 配置 _rollup.config.js_ + +```js +import stylexPlugin from '@stylexjs/rollup-plugin'; + +const config = { + input: './index.js', + output: { + file: './.build/bundle.js', + format: 'es', + }, + // 确保在 Babel 之前使用 stylex 插件 + plugins: [stylexPlugin({ + // 必需项。生成的 CSS 文件的文件路径。 + fileName: './.build/stylex.css', + // 默认值:false + dev: false, + // 所有生成的类名的前缀 + classNamePrefix: 'x', + // CSS 变量支持所必需 + unstable_moduleResolution: { + // 类型:'commonJS' | 'haste' + // 默认值:'commonJS' + type: 'commonJS', + // 项目根目录的绝对路径 + rootDir: __dirname, + }, + })], +}; + +export default config; +``` + +### 编译器(开发) + + +```bash +npm install --save-dev @stylexjs/babel-plugin +``` + +修改 Babel 配置 _(babel.config.js)_ + +```js +import styleX from '@stylexjs/babel-plugin'; + +const config = { + plugins: [ + [styleX, { + dev: true, + // 设置为 true 以进行快照测试 + // 默认值:false + test: false, + // CSS 变量支持所必需 + unstable_moduleResolution: { + // 类型:'commonJS' | 'haste' + // 默认值:'commonJS' + type: 'commonJS', + // 项目根目录的绝对路径 + rootDir: __dirname, + } + }], + ], +}; + +export default config; +``` + +### 编译器(生产) Webpack + + +```bash +npm install --save-dev @stylexjs/webpack-plugin +``` + +修改 Webpack 配置 _webpack.config.js_ + +```js +const StylexPlugin = require('@stylexjs/webpack-plugin'); +const path = require('path'); + +const config = (env, argv) => ({ + entry: { + main: './src/index.js', + }, + output: { + path: path.resolve(__dirname, '.build'), + filename: '[name].js', + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: 'babel-loader', + }, + ], + }, + plugins: [ + // 确保在 Babel 之前使用 stylex 插件 + new StylexPlugin({ + filename: 'styles.[contenthash].css', + // 获取 webpack 的模式并为开发设置值 + dev: argv.mode === 'development', + // 使用静态生成的 CSS 文件,而不是运行时注入的 CSS。 + // 即使在开发环境中也是如此。 + runtimeInjection: false, + // 可选的。默认值:'x' + classNamePrefix: 'x', + // CSS 变量支持所必需 + unstable_moduleResolution: { + // 类型:'commonJS' | 'haste' + // 默认值:'commonJS' + type: 'commonJS', + // 项目根目录的绝对路径 + rootDir: __dirname, + }, + }), + ], + cache: true, +}); + +module.exports = config; +``` + +### 编译器(生产) Next.js + + +```bash +npm install --save-dev @stylexjs/nextjs-plugin \ + @stylexjs/babel-plugin rimraf +``` + +在 `package.json` 添加配置 + +```js +{ + "scripts": { + ..., + "predev": "rimraf .next", + "prebuild": "rimraf .next" + } +} +``` + +修改 Babel 配置 _.babelrc.js_ + +```js +module.exports = { + presets: ["next/babel"], + plugins: [ + [ + "@stylexjs/babel-plugin", { + dev: process.env.NODE_ENV === "development", + test: process.env.NODE_ENV === "test", + runtimeInjection: false, + genConditionalClasses: true, + treeshakeCompensation: true, + unstable_moduleResolution: { + type: "commonJS", + rootDir: __dirname, + }, + }, + ], + ], +}; +``` + +修改 Next.js 配置 _next.config.mjs_ + +```js +/** @type {import('next').NextConfig} */ +import stylexPlugin from "@stylexjs/nextjs-plugin"; + +const nextConfig = {}; + +const __dirname = new URL(".", import.meta.url).pathname; +export default stylexPlugin({ + rootDir: __dirname, +})(nextConfig); +``` + +### 仅限本地开发 + + +要开始使用 `StyleX` 而无需配置编译器和构建过程,您可以安装本地开发运行时 + +```bash +npm install --save-dev @stylexjs/dev-runtime +``` + +开发运行时必须导入到应用程序的 `JavaScript` 入口点并进行配置 + +```js +import inject from '@stylexjs/dev-runtime'; + +inject({ + classNamePrefix: 'x', + dev: true, + test: false, +}); +``` + +### 用 ESLint 捕捉错误 + + +```bash +npm install --save-dev @stylexjs/eslint-plugin +``` + +StyleX 编译器不会验证您的样式,并且会编译许多无效样式。当您创作样式时,您应该使用 ESLint 插件来捕获这些错误。修改 ESLint 配置 `.eslintrc.js` + +```js +module.exports = { + plugins: ["@stylexjs"], + rules: { + "@stylexjs/valid-styles": "error", + }, +}; +``` + +定义样式 +---- + +### 创建样式 + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + base: { + fontSize: 16, + lineHeight: 1.5, + color: 'rgb(60,60,60)', + }, + highlighted: { + color: 'rebeccapurple', + }, +}); +``` + +### 伪类 + + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + button: { + backgroundColor: 'lightblue', + }, +}); +``` + +样式名为 `button` 的背景样式上添加 `:hover` 和 `:active` 伪类 + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + button: { + backgroundColor: { + default: 'lightblue', + ':hover': 'blue', + ':active': 'darkblue', + }, + }, +}); +``` + +### 伪元素 + + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + input: { + // 伪元素 + '::placeholder': { + color: '#999', + }, + color: { + default: '#333', + // 伪类 + ':invalid': 'red', + }, + }, +}); +``` + +### 媒体查询(和其他@规则) + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + base: { + width: { + default: 800, + '@media (max-width: 800px)': '100%', + '@media (min-width: 1540px)': 1366, + }, + }, +}); +``` + +同样,媒体查询也可以作为样式值中的 "条件" + +### 组合条件 + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + button: { + color: { + default: 'var(--blue-link)', + ':hover': { + default: null, + '@media (hover: hover)': 'scale(1.1)', + }, + ':active': 'scale(0.9)', + }, + }, +}); +``` + +当您需要组合媒体查询和伪选择器时,嵌套超过`一层` + +### 后备样式 + + +```css +.header { + position: fixed; + position: -webkit-sticky; + position: sticky; +} +``` + +使用 `firstThatWorks` 函数来实现相同的目的 + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + header: { + position: stylex.firstThatWorks('sticky', '-webkit-sticky', 'fixed'), + }, +}); +``` + +### 关键帧动画 + +```js +import * as stylex from '@stylexjs/stylex'; + +const fadeIn = stylex.keyframes({ + from: {opacity: 0}, + to: {opacity: 1}, +}); + +const styles = stylex.create({ + base: { + animationName: fadeIn, + animationDuration: '1s', + }, +}); +``` + +使用 `stylex.keyframes()` 函数来定义关键帧动画 + +### 动态样式 + + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + // 函数参数必须是简单标识符 + // -- 不允许解构或默认值 + bar: (height) => ({ + height, + // 函数体必须是对象字面量 + // -- 不允许使用 { return {} } + }), +}); + +function MyComponent() { + // `height` 的值在编译时不能确定。 + const [height, setHeight] = useState(10); + return
; +} +``` + +注意:动态样式是一项高级功能,应谨慎使用。对于大多数用例,条件样式应该足够了。 + +使用样式 +---- + +### 合并样式 + + +```jsx +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + base: { + fontSize: 16, + lineHeight: 1.5, + color: 'grey', + }, + highlighted: { + color: 'rebeccapurple', + }, +}); + +
; +``` + +如果样式的顺序颠倒,文本将为灰色 + +```jsx +
+``` + +### 条件样式 + +```jsx +
+``` + +通过使用常见的 JavaScript 模式(例如三元表达式和 `&&` 运算符),可以在运行时有条件地应用样式。 `stylex.props` 忽略虚假值,例如 `null`、`undefined` 或 `false` + +### 样式变体 + + +```js +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + violet: { + backgroundColor: { + default: 'blueviolet', + ':hover': 'darkviolet', + }, + color: 'white', + }, + gray: { + backgroundColor: { + default: 'gainsboro', + ':hover': 'lightgray', + }, + }, + // ... more variants here ... +}); +``` + +然后,通过使用 `variant` 属性作为样式对象上的键来应用适当的样式 + +```jsx +function Button({variant, ...props}) { + return ( +