最小CSS In-JS样式的组件解决方案用于React。
也有一些非目标。
as属性, .withComponent()方法).attrs()方法)defaultProps 。 import { styled } from '@minstack/styled' ;使用标签名称样式任何HTML元素类型。样式的组件支持HTML元素支持的所有相同的道具(包括转发的参考)。
const StyledComponent = styled ( 'div' ) `
color: black;
` ;标签名称方法样式也得到了支持。
const StyledComponent = styled . div `
color: black;
` ;样式任何接受className属性的React组件,或扩展已经样式的组件的样式。
const StyledComponent = styled ( Component ) `
color: black;
` ; 通过设置模板字符串的通用参数,可以将额外的属性添加到样式组件中。通常,样式属性应以$为前缀,以表明它们仅用于样式。以$字符开头的任何属性名称都不会作为属性传递到基础HTML元素。
interface ComponentStyleProps {
$font ?: string ;
}
const StyledComponent = styled ( 'div' ) < ComponentStyleProps > `
font-family: ${ ( props ) => props . $font } ;
` ; 使用styled.global global实用程序来创建全局样式组件。
const GlobalStyle = styled . global `
body,
html {
margin: 0;
padding: 0;
}
` ;样式属性也可以添加到全球样式中。
interface GlobalStyleProps {
$font ?: string ;
}
const GlobalStyle = styled . global < GlobalStyleProps > `
body,
html {
font-family: ${ ( props ) => props . $font } ;
}
` ;定义密钥帧或字体尺寸与定义任何其他样式相同。由于它们没有范围为任何特定组件,因此它们可能仅在全球样式中使用。为防止名称碰撞,请使用随附的getId实用程序生成CSS安全的唯一名称。
const openSansFont = getId ( 'font/open-sans' ) ;
const slideInAnimation = getId ( 'keyframes/slide-in' ) ;
const GlobalStyle = styled . global `
@font-face {
font-family: ${ openSansFont } ;
src: url('/fonts/OpenSans-Regular-webfont.woff') format('woff');
}
@keyframes ${ slideInAnimation } {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
` ;
const StyledComponent = styled ( 'div' ) `
font-family: ${ openSansFont } ;
animation-name: ${ slideInAnimation } ;
` ; 传递主题挂钩(或任何功能),该挂钩将主题返回到createStyled实用程序中。然后,当第二个参数传递给任何样式的模板字符串功能值时,主题值将可用。
// File: styled-with-theme.ts
import { createStyled } from '@minstack/styled' ;
export const styled = createStyled ( useTheme ) ;这会创建一个强烈键入styled实例。使用此实例而不是内置实例。
import { styled } from './styled-with-theme' ;
const ThemedComponent = styled ( 'div' ) `
color: ${ ( props , theme ) => theme . fgColor } ;
background-color: ${ ( props , theme ) => theme . bgColor } ;
` ; 支持所有CSS和嵌套。
要将样式直接应用于已设计的HTML元素或组件,请在标记模板的顶部使用CSS属性(无周围块)。
const StyledComponent = styled ( 'div' ) `
color: red;
` ;顶级CSS属性将包裹在动态样式的类选择器中
. _rmsds7y13d_ {
color : red;
}使用CSS规则块为样式组件的儿童设计样式。
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
}
` ;样式的动态类将自动添加到所有选择器上,以使其“范围”。
. _rmsds7y13d_ . child {
color : blue;
}每个样式的组件(除全局样式除外)都可以用作选择器。
const StyledComponentA = styled ( 'div' ) `
color: blue;
` ;
const StyledComponentB = styled ( 'div' ) `
${ StyledComponentA } {
background-color: yellow;
}
` ;每个样式的组件都有一个独特的静态类,该类别是在创建中生成的。样式"._rmsss7y13d_"组件的toString()方法返回该静态类的选择器字符串(例如。
. _rmsds7y13d_ . _rmsss7y13d_ {
color : red;
}静态类是从组件的显示名称,样式模板的静态部分,继承的静态类(扩展另一个样式组件)以及共享相同“ thumbprint”的先前创建的组件的数量。在大多数情况下,这应该使SSR和客户端渲染的静态类稳定。如果发生静态类SSR问题,则可能是由于具有相同指纹的组件具有不稳定的创建顺序。尝试使用.withConfig()方法更改displayName ,以使有问题的组件的指纹独特。
const StyledComponent = styled . div . withConfig ( { displayName : 'StyledComponent' } ) `
color: red;
` ;巢规则块可创建更复杂的选择器。
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
.grandchild {
color: green;
}
}
` ;就像样式的动态类被预选到顶级选择器一样,父母选择器也被培养给子女选择器。
. _rmsds7y13d_ . child {
color : blue;
}
. _rmsds7y13d_ . child . grandchild {
color : green;
}家长选择器参考( & )的工作方式与SCS/SASS中的方式相同。一个额外的细节是,当在样式根上使用父级选择器(不嵌套在父块内)时,它是指当前样式的唯一样式类,即该样式的隐式/虚拟父块选择器。
const StyledComponent = styled ( 'div' ) `
&& {
color: red;
}
&:hover {
color: blue;
}
.parent & {
color: green;
}
` ;支持所有CSS ATULES( @charset除外, <style>元素中不允许使用)。
const StyledComponent = styled ( 'div' ) `
@media screen and (min-width: 900px) {
color: red;
}
.child {
@media screen and (min-width: 600px) {
.grandchild {
color: blue;
.adopted & {
color: green;
}
}
}
}
` ;在必要的情况下,将悬挂在符号的情况下,而在没有介入设备的情况下,将以相同的方式处理家长的选择者。
@media screen and ( min-width : 900 px ) {
. _rmsds7y13d_ {
color : red;
}
}
@media screen and ( min-width : 600 px ) {
. _rmsds7y13d_ . child . grandchild {
color : blue;
}
. adopted . _rmsds7y13d_ . child . grandchild {
color : green;
}
}如果CSS属性值为“空”(空字符串, false , null , undefined或"" ),则将从样式中省略整个属性。
const StyledComponent = styled ( 'div' ) `
color: ${ null } ;
background-color: red;
` ;不包括颜色属性,因为它没有价值。
. _rmsds7y13d_ {
background-color : red;
}样式可以包含块( /* */ )和行注释( // )。评论永远不会包含在渲染样式表中。
const StyledComponent = styled ( 'div' ) `
// This is a comment.
/* And so...
...is this. */
` ; styled.string标记的模板函数返回一个简单的样式字符串,其中所有值插值。仅允许静态值(无函数)。空属性值( null , undefined , false和"" )以相同的方式在样式组件中使用,并导致属性被省略。
const fontHelper = styled . string `
font-family: Arial, sans-serif;
font-weight: 400;
font-size: ${ size } ;
` ;
// Then use in a styled component or another helper.
const StyledComponent = styled ( 'div' ) `
${ fontHelper }
color: red;
` ; styled.string手没有副作用,而且工作很少,因此在功能中也可以安全使用。
const shadow = ( depth : number ) => {
return styled . string `
-moz-box-shadow: 0 ${ depth } px ${ depth } px black;
-webkit-box-shadow: 0 ${ depth } px ${ depth } px black;
box-shadow: 0 ${ depth } px ${ depth } px black;
` ;
} ;
// Then use in a styled component or another helper.
const StyledComponent = styled ( 'div' ) < { $shadowDepth : number } > `
${ ( props ) => shadow ( props . $shadowDepth ) }
color: red;
` ; 使用StyledTest包装器生产具有稳定的类名称和样式信息的快照。
const container = render ( < MyStyledComponent /> , { wrapper : StyledTest } ) ;
expect ( container ) . toMatchSnapshot ( ) ; // Snapshot
<div>
<div
class="_test-dynamic-0_ _test-static-0_"
>
Hello, world!
</div>
<style>
._test-dynamic-0_ {
padding: 1rem;
}
</style>
</div>
StyledProvider可以覆盖默认的cache , manager和renderer 。默认操作不需要提供商。
const cache = createStyledCache ( ) ;
const manager = createStyledManager ( ) ;
const renderer = createStyledRenderer ( ) ;
render (
< StyledProvider cache = { cache } manager = { manager } renderer = { renderer } >
< App />
</ StyledProvider > ,
) ; StyledTest组件是一种预先配置的StyledProvider ,它注入了所有三个资源的测试版本以替换班级名称并捕获样式。
注意:提供的缓存,管理器和渲染器不得在样式组件的寿命中更改。如果发生突变,将抛出(或在生产中记录)。
在呈现服务器上的应用程序时,请使用createSsrStyledManager和StyledProvider捕获样式。
const manager = createSsrStyledManager ( ) ;
const html = renderToString (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ;
const html = `
<!doctype HTML>
<html>
<head>
${ manager . getStyleTags ( ) }
</head>
<body>
<div id="root">
${ html }
</div>
</body>
</html>
` ; SSR Manager的getStyleTags()方法返回一个仅包含<style>标签的单个HTML字符串。还有getStyleElement() (react元素数组)和getCss() (CSS字符串数组)方法。
使用createStyledManager (或createSsrStyledManager )和StyledProvider对所有注射样式设置nonce 。
const manager = createStyledManager ( nonce ) ;
render (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ; | 特征 | Minstack风格 | 戈贝 | 样式的组件 | 情感 | |
|---|---|---|---|---|---|
| 图书馆 | |||||
| 束大小(大约KB)[1] | 2.8 | 1.2 | 13.3 | 9.1 | |
| 零依赖性 | ? | ? | ? | ? | |
| 打字稿本地 | ? | ? | ? | ? | |
| API | |||||
| 标记的模板样式 | ? | ? | ? | ? | |
| 动态风格 | ? | ? | ? | ? | |
| 对象样式 | ? | ? | ? | ? | |
| 全球风格 | ? | ? | ? | ? | |
多态性( as ) | ? | ? | ? | ? | |
属性映射( attrs ) | ? | ? | ? | ? | |
| 主题[2] | ? | ? | ? | ? | |
| SSR | ? | ? | ? | ? | |
| 快照测试 | ? | ? | ? | ? | |
| 风格 | |||||
| 基本CSS语法[3] | ? | ? | ? | ? | |
CSS @media | ? | ? | ? | ? | |
CSS @keyframes | ? | ? | ? | ? | |
CSS @font-face | ? | ⭕ | ⭕ | ? | |
CSS @import | ? | ⭕ | ? | ? | |
其他CSS @规则 | ? | ⭕ | ⭕ | ⭕ | |
| 供应商前缀[4] | ? | ? | ? | ? | |
| 规则嵌套 | ? | ? | ? | ? | |
家长选择器( & ) | ? | ? | ? | ? | |
| 样式的组件选择器[5] | ? | ? | ? | ? |
styled导出(摇晃,缩小和GZIP之后)。 Goober与此解决方案非常相似。它快速,较小,并且支持一些额外的功能(对象样式和as属性)。那么,Goober的缺点是什么,为什么要使用它?
StyledTest测试包装组件,不仅可以进行快照测试,而且以测试框架不可知的方式进行。setup()函数,这不会更改主题类型。通过声明合并可以扩展主题类型,但这再次是全局,不是很安全。该库提供了返回一个新的API实例的createStyled()工厂,该实例具有强烈的主题。styled.div而不是styled('div') )。该库支持styled.<tag>没有编译时间支持。setup()进行调用。该库的目标是反应,并且在使用preact时需要preact/compat 。该图书馆被认为是景点支持的一些功能。这是为了减少可以设计样式组件的替代方法,从而提高了代码一致性,并提供了更好的开发人员体验(DX)。删除对完成同一操作的两种不同方法的支持也意味着库的大小和运行时开销将减少和/或分配到改进的核心功能,并且库的总体上更可维护。
as属性,用于更改样式组件的基础组件类型。该库并不是因为它固有地键入不安全,并且使用样式助手(例如, styled.string实用程序)提供了一种更好的重复使用样式的方法。有关基准实现,请参见Benchmark.js脚本。
| 图书馆 | OP/s |
|---|---|
| Minstack风格 | 144,970 |
| 戈贝 | 142,028 |
| 情感 | 124,681 |
| 样式的组件 | 118,072 |
getId接受可选的名称空间参数(重新添加).withConfig()静态方法为样式模板getId和动态类哈希中使用主要版本styled.div styled('div') )useInsertionEffectstyled.stringStyledProvidercreateSsrStyledManager )StyledTest )getId不再接受论点styled.mixin混合renderStylesToString