前端UI组件设计系统【免费下载链接】styled-system⬢ Style props for rapid UI development项目地址https://gitcode.com/gh_mirrors/st/styled-system点击查看免费下载本指南以 docs/custom-props.md 为主体结合styled-system/core的源码与测试用例展开。当 styled-system 内置的space、color、layout等函数无法覆盖你需要的 CSS 属性时system与compose这两个低层工具就是扩展的入口。读完本文你将掌握如何为任意 CSS 属性创建带主题取值、响应式能力与别名支持的 style prop 函数并理解其底层实现原理。为什么需要自定义 Style Propsstyled-system 通过样式属性style props将设计系统中的 token间距、颜色、字号等映射到组件上。它内置了一系列常用的 style prop 函数例如space、color、layout、typography、flexbox、border等这些函数均从styled-system的入口统一导出见 packages/styled-system/src/index.js。但设计系统的边界永远不会只停在库内置的属性上——你可能需要textDecoration、transition、cursor、objectFit等未收录的 CSS 属性。此时官方提供的扩展方式是使用system工具创建自己的 style prop 函数并用compose将多个函数组合进同一个组件。这两个工具是整个库的基石文档中明确说明All Styled System functions rely on these low-level utilities.system创建一个 style prop 函数compose将多个 style prop 函数合并为一个。换句话说理解system和compose等于理解了 styled-system 如何从零构建出全部内置函数。system 的基本用法system接受一个配置对象作为唯一参数返回一个可用于 styled-components、Emotion 或其他 CSS-in-JS 库的 style prop 函数。下面是一个为链接组件添加textDecoration支持的完整示例取自 docs/custom-props.mdimport styled from styled-components import { system } from styled-system const textDecoration system({ prop: textDecoration, cssProperty: textDecoration, }) const Link styled.a ${system({ textDecoration: true, fontWeight: { property: fontWeight, scale: fontWeights, }, })} 上面的示例展示了两种配置形态第一种用prop/cssProperty形式声明textDecoration函数单独创建后备用第二种直接在组件样式中内联传入一个配置对象同时声明textDecoration与带主题 scale 的fontWeight。system的配置对象中每个 key 都代表组件的一个 style prop每个 key 对应的 value 可以定义以下字段字段类型说明propertystring返回样式对象中使用的 CSS 属性名propertiesstring[]多个 CSS 属性的数组例如[marginLeft, marginRight]scalestring引用theme对象中某个键的字符串transformfunction基于 scale 转换原始值的函数defaultScaleobject/array当theme对象中没有定义对应 scale 时的兜底 scale这些字段对应着核心实现createStyleFunction见 packages/core/src/index.jsexport const createStyleFunction ({ properties, property, scale, transform getValue, defaultScale, }) { properties properties || [property] const sx (value, scale, _props) { const result {} const n transform(value, scale, _props) if (n null) return properties.forEach(prop { result[prop] n }) return result } sx.scale scale sx.defaults defaultScale return sx }从源码可以确认几点properties未提供时默认退化为单个property转换结果若是null则跳过输出对应测试 ignores null values见 packages/core/test/system.jstransform默认为getValue即get(scale, n, n)优先从 scale 中按 key 取值取不到时返回原始值。一个映射多个属性properties当单个 prop 需要同时映射到多个 CSS 属性时使用properties。例如marginX同时输出marginLeft与marginRightconst mx system({ mx: { properties: [marginLeft, marginRight], scale: space, }, })在styled-system/space包的源码中marginX、marginY、paddingX、paddingY正是这样通过properties实现的见 packages/space/src/index.js。测试 packages/core/test/system.js 验证了这种多属性映射并同时验证了数组形式的值会按断点展开为响应式媒体查询样式。transform自定义值转换逻辑默认情况下styled-system 会根据 scale 中的 key 从主题取值或直接返回原始值。当你需要改变这个逻辑时提供自定义的transform函数即可。transform接收两个参数(value, scale)。其中value是原始 prop 值scale是主题 scale 对象或数组。const margin system({ margin: { property: margin, transform: (n, scale, props) { const m props.multiply || 1 return m * n }, }, })实际调用时transform还会收到第三个参数props整个组件 props见 packages/core/src/index.js 中createStyleFunction内部transform(value, scale, _props)的调用。测试 transforms values 演示了transform结合props的完整用法const a parser({ margin: 8 }) // → { margin: 8 } const b parser({ margin: 12, multiply: 2 }) // → { margin: 24 }需要说明的是官方文档对transform的描述是(value, scale)两个参数但从 packages/core/src/index.js 的实现看第三个参数props同样会被传入这在某些场景如依据其他 prop 决定输出下非常实用。在真实项目中styled-system/space包的getMargin就是一个经典的自定义 transform它支持负的 margin 值通过绝对值取 scale 值再取负见 packages/space/src/index.js。快捷定义prop: true如果你的 style prop 不需要从主题取值且 prop 名与目标 CSS 属性名一致可以直接使用快捷定义shortcut definitionsystem({ transition: true, })这会将transitionprop 直接翻译为transition样式输出无需再写{ property: transition }。从 packages/core/src/index.js 的system实现可以看到快捷定义的底层逻辑是if (conf true) { // shortcut definition config[key] createStyleFunction({ property: key, scale: key, }) return }即true值会被展开为property和scale都等于该 key 名的完整配置——scale指向同名主题键主题中通常不存在该键于是退化为返回原始值。内置函数中大量使用这种形态例如color: true、width: true见 packages/core/test/system.js。system 返回的 style prop 函数system返回的函数就是一个标准的 style prop 函数接收props作为参数返回一个样式对象。它可以像其他内置函数一样直接用于 styled-components、Emotion 等 CSS-in-JS 库。该函数还附带两个静态属性见 packages/core/src/index.js 中createParser的返回值parse.config该函数的配置对象parse.propNames该函数接受的所有 prop 名数组由Object.keys(config)生成可用于检测组件接收了哪些 props。在 styled-components 中.propNames常配合shouldForwardProp使用避免非法的 DOM 属性被透传到原生元素上styled-system/should-forward-prop包封装了这套逻辑。另外当配置包含多个 prop 时返回的 parser 还会为每个 prop 生成独立的单属性函数。测试 includes single property functions 验证了这一点见 packages/core/test/system.jsconst parser system({ color: true, backgroundColor: true, width: true, }) parser.color({ color: tomato, backgroundColor: nope }) // → { color: tomato } parser.width({ width: 100%, color: tomato }) // → { width: 100% }为 prop 创建别名使用system创建别名很简单为配置对象添加一个指向原配置的 key 即可。import { system } from styled-system const config { color: { property: color, scale: colors, }, backgroundColor: { property: backgroundColor, scale: colors, }, } // alias config.bg config.backgroundColor export const color system(config)创建后bg与backgroundColor行为完全一致。这也是 styled-system 内置函数的常用做法在 packages/space/src/index.js 中configs.margin.m configs.margin.margin、configs.padding.px configs.padding.paddingX等一行行别名赋值构成了m/mt/mx/p/px等全部间距别名。此外styled-system入口还为 v4 用户保留了style兼容函数其参数中同样包含alias字段底层会执行if (alias) config[alias] config[prop]逻辑一致见 packages/styled-system/src/index.js。组合多个函数compose当需要在一个组件中同时使用多个 style prop 函数时用compose把它们合并为一个import styled from styled-components import { space, layout, color, compose } from styled-system const Box styled(div)( compose( space, layout, color ) )compose的实现相当简洁见 packages/core/src/index.js它将各 parser 的config合并成一个大配置再交给createParser生成新的 parserexport const compose (...parsers) { let config {} parsers.forEach(parser { if (!parser || !parser.config) return assign(config, parser.config) }) const parser createParser(config) return parser }这也解释了为什么每个 style prop 函数都必须带有config静态属性——它是组合的接口。测试 packages/core/test/compose.js 验证了compose(color, fontSize)能一次性处理多个 props。另外由于配置对象可以直接合并你甚至可以手动组合配置const composed system({ ...color.config, ...layout.config })详见测试 parser configs can be composed manuallypackages/core/test/system.js。底层原理createParser 如何工作理解createParser能让你更好地掌控自定义 prop 的行为。从 packages/core/src/index.js 的源码可以看到parser 的核心流程是遍历组件props仅处理配置中存在的 keyif (!config[key]) continue通过get(props.theme, sx.scale, sx.defaults)从主题中取出 scale支持点路径如colors.primary若 prop 值是数组或对象则按断点展开为响应式媒体查询样式否则直接调用sx(raw, scale, props)生成样式对对象形式的响应式样式按断点数值排序确保media块顺序稳定。默认断点来自defaultsconst defaults { breakpoints: [40, 52, 64].map(n n em), }对应媒体查询media screen and (min-width: 40em/52em/64em)。若主题定义了breakpoints数组或{ sm: 32em, md: 40em }这类对象均可见测试 supports non-array breakpoints object则优先使用主题配置。测试 packages/core/test/system.js 同时覆盖了数组值与对象值两种响应式写法以及多 prop 响应式样式合并的场景。因此自定义 style prop 天然继承了三项能力主题取值scale、响应式数组/对象值、与内置函数一致的组合方式。实战编写你自己的 textDecoration 组件综合上述知识点一个完整的自定义组件通常是这样组织的import styled from styled-components import { system, compose, space, color } from styled-system // 1. 自定义单个属性 const textDecoration system({ textDecoration: { property: textDecoration, }, }) // 2. 自定义带主题 scale 的属性 const fontWeight system({ fontWeight: { property: fontWeight, scale: fontWeights, defaultScale: [100, 200, 300, 400, 500, 600, 700], }, }) // 3. 组合内置与自定义函数 const Link styled.a ${compose(space, color, textDecoration, fontWeight)} export default Link使用defaultScale的好处是即使消费方没有在主题中定义fontWeights组件依然有一个合理的兜底取值对应 docs/api.md 中defaultScale的用法说明。更多参考完整的systemAPI 说明与示例见 docs/api.md核心实现system、compose、createStyleFunction、createParser、get见 packages/core/src/index.js行为验证测试见 packages/core/test/system.js 与 packages/core/test/compose.js真实的别名与 transform 案例见 packages/space/src/index.js所有内置函数如何统一导出见 packages/styled-system/src/index.js。赞分享前端UI组件设计系统【免费下载链接】styled-system⬢ Style props for rapid UI development项目地址https://gitcode.com/gh_mirrors/st/styled-system点击查看免费下载相关推荐Styled System API 完全指南从 Space 到 System 的 Style Props 全解析Styled System API 完全指南从 Space 到 System 的 Style Props 全解析 本文以 styled system 仓库 d前端UI组件设计系统Styled System 的 should-forward-prop 指南用 Emotion 精确过滤 Styled System 样式 propsStyled System 的 should forward prop 指南用 Emotion 精确过滤 Styled System 样式 props 本指南前端UI组件设计系统使用 styled-system/props 从组件 props 中高效分离样式属性使用 styled system/props 从组件 props 中高效分离样式属性 导读 styled system/props 是 Styled Sys前端UI组件设计系统上一篇深度剖析ZLMediaKit跨平台RTP发送机制的核心差异与优化策略下一篇攻克ZLMediaKit项目WebRTC编译难题从报错到成功的全流程解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
