跳到主要内容

编程艺术:Object Styles To 模板字符串 — Numio

将 css({...}) 和 styled.x({...}) 对象样式改写为 styled-components、Emotion 或 Linaria 使用的标签模板字面量。camelCase 键变为 kebab-case,数字会加上 px(无单位属性除外),JS 表达式变为 ${} 插值。

把 Emotion 或 Glamor 的对象样式迁移到要求模板字面量 CSS 的 styled-components 或 Linaria。

Object Styles

Template Literal

适用场景

  • 把 Emotion 或 Glamor 的对象样式迁移到要求模板字面量 CSS 的 styled-components 或 Linaria。
  • 把 styled(Component)({...}) 定义转换为模板语法,以便像普通 CSS 一样阅读和编辑。

使用方法

  1. 将调用 css({...})、styled.tag({...}) 或 styled(Component)({...}) 的 JavaScript 或 TypeScript(可含 JSX/TSX)粘贴到 Object Styles 编辑器。
  2. 在“设置”中保持 "Transpile css tags" 和 "Transpile styled tags" 开启,或关闭其中一个以保留对应调用不变;关闭时会显示警告横幅。
  3. 复制 Template Literal 面板。被转换调用之外的代码会保留,但会经 Prettier 重新格式化。

对象样式(JavaScript 或 TypeScript)

const Button = styled.button({
  padding: 8,
  fontSize: '14px',
  backgroundColor: theme.primary,
  '&:hover': {
    opacity: 0.8,
  },
})

const card = css({
  display: 'flex',
  marginTop: 16,
})

标签模板字面量

const Button = styled.button`
  padding: 8px;
  font-size: 14px;
  background-color: ${theme.primary};

  &:hover {
    opacity: 0.8;
  }
`
const card = css`
  display: flex;
  margin-top: 16px;
`

功能与限制

转换在浏览器中运行:Web Worker 用 Babel standalone 应用 babel-plugin-object-styles-to-template(普通 JavaScript 解析失败时改用 TypeScript 语法解析),结果由 Prettier 格式化且不带分号。

只转换参数为单个普通对象的调用。带函数或多个参数的 styled("div")(obj, props => ...) 以及 css([...]) 数组会保持原样。

zIndex、lineHeight、opacity 等无单位属性保留裸数字,其他数字加上 px。数组值不会展开,而是变为 ${[0, 4]} 这样的插值。

Prettier 也会规范化未改动的代码,例如单引号会变成双引号。

FAQ

能识别哪些调用名?

插件会转换 css(...) 和 styled 调用:styled.button(...)、styled("div")(...) 和 styled(Link)(...)。其他带对象参数的函数,例如 someFn({ color: 'red' }),不会被修改。

变量和主题值如何处理?

任何非字面量值,例如 theme.primary 或 colors.white,都会作为 JavaScript 表达式保留在模板的 ${...} 中,因此仍在运行时求值。

支持 &:hover 这样的嵌套选择器吗?

支持。'&:hover' 等键下的嵌套对象会变成模板中的嵌套块,并用空行与父级声明隔开。

支持 TypeScript 吗?

支持。如果代码无法按 JavaScript 解析,会改用 Babel 的 TypeScript 语法重新解析。类型会被保留:interface 不变,styled.button<Props>({...}) 会变为 styled.button<Props>`...`。

规范与参考资料