Минимальные компоненты CSS-In-JS Components для React.
Есть также некоторые вещи, которые не являются целями.
as свойство, метод .withComponent() ).attrs() )defaultProps . import { styled } from '@minstack/styled' ;Стиль любой тип элемента HTML, используя имя тега. Стилизованный компонент поддерживает все те же реквизиты (включающие ссылки, которые направляются), которые поддерживает элемент HTML.
const StyledComponent = styled ( 'div' ) `
color: black;
` ;Стиль имени тега также поддерживается.
const StyledComponent = styled . div `
color: black;
` ; Стиль любой компонент React, который принимает свойство className или расширяет стили уже стилизованного компонента.
const StyledComponent = styled ( Component ) `
color: black;
` ; Дополнительные свойства могут быть добавлены в стилизованный компонент, установив общий параметр строки шаблона. Как правило, свойства стиля должны быть предварительно профиксированы с помощью $ чтобы указать, что они используются только для стиля. Любое имя свойства, которое начинается с символа $ не будет передано в базовый HTML -элемент в качестве атрибута.
interface ComponentStyleProps {
$font ?: string ;
}
const StyledComponent = styled ( 'div' ) < ComponentStyleProps > `
font-family: ${ ( props ) => props . $font } ;
` ; Используйте утилиту styled.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 . Затем значение темы будет доступно в качестве второго аргумента, передаваемого любого стиля функционального значения String String.
// 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 на верхнем уровне шаблона Tagged (без окружающего блока).
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;
}
` ; Каждый компонент в стиле имеет уникальный статический класс, который генерируется при создании. Метод стилизованного компонента toString() возвращает строку селектора (например, "._rmsss7y13d_" ) для этого статического класса.
. _rmsds7y13d_ . _rmsss7y13d_ {
color : red;
} Статический класс генерируется из имени отображения компонента, статической части шаблона стиля, унаследованных статических классов (при расширении другого стиля компонента) и количество ранее созданных компонентов, которые имеют одинаковый «отпечаток большого пальца». В большинстве случаев это должно сделать статические классы стабильными в SSR и клиентских рендере. Если возникают статические проблемы SSR, это, вероятно, связано с компонентами с тем же отпечатками пальца, имеющим нестабильный порядок создания. Попробуйте изменить имя displayName , используя метод .withConfig() , чтобы сделать проблемный отпечаток пальца проблемного компонента уникальным.
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;
} Ссылки для родителей ( & ) работают так же, как и в SCSS/SASS. Единственная дополнительная деталь заключается в том, что когда родительский селектор используется в корне стиля (не вложенного внутри родительского блока), он относится к уникальному классу стиля текущего стиля, который является неявным/виртуальным селектором родительского блока для стиля.
const StyledComponent = styled ( 'div' ) `
&& {
color: red;
}
&:hover {
color: blue;
}
.parent & {
color: green;
}
` ; Все CSS AT-rules поддерживаются (кроме @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;
}
}
}
}
` ;AT-Rules будут подниматься по мере необходимости, и родители-селекторы будут обрабатываться так же, как они будут без промежуточного договора.
@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 Tagged возвращает простую строку стиля со всеми интерполированными значениями. Разрешены только статические значения (нет функций). Пустые значения свойства ( 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>
` ; Метод getStyleTags() SSR Manager () возвращает одну строку HTML, содержащую только теги <style> . Существуют также методы getStyleElement() (массив элементов реагирования) и getCss() (массив строк CSS).
Используйте createStyledManager (или createSsrStyledManager ) и StyledProvider , чтобы установить nonce на всех введенных стилях.
const manager = createStyledManager ( nonce ) ;
render (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ; | Особенность | Минстак стиль | Губер | Стилизованные компоненты | Эмоция | |
|---|---|---|---|---|---|
| Библиотека | |||||
| Размер пакета (около кб) [1] | 2.8 | 1.2 | 13.3 | 9.1 | |
| Нулевые зависимости | ? | ? | ? | ? | |
| TypeScript Native | ? | ? | ? | ? | |
| API | |||||
| Tagged шаблоны стили | ? | ? | ? | ? | |
| Динамические стили | ? | ? | ? | ? | |
| Объектные стили | ? | ? | ? | ? | |
| Глобальные стили | ? | ? | ? | ? | |
Полиморфизм ( as ) | ? | ? | ? | ? | |
Картирование свойств ( attrs ) | ? | ? | ? | ? | |
| Темация [2] | ? | ? | ? | ? | |
| SSR | ? | ? | ? | ? | |
| Тестирование снимка | ? | ? | ? | ? | |
| Стиль | |||||
| Основной синтаксис CSS [3] | ? | ? | ? | ? | |
CSS @media | ? | ? | ? | ? | |
CSS @keyframes | ? | ? | ? | ? | |
Css @font-face | ? | ⭕ | ⭕ | ? | |
CSS @import | ? | ⭕ | ? | ? | |
Другие правила CSS @ | ? | ⭕ | ⭕ | ⭕ | |
| Префикс поставщика [4] | ? | ? | ? | ? | |
| Правило гнездование | ? | ? | ? | ? | |
Родительские селекторы ( & ) | ? | ? | ? | ? | |
| Стилизованные селекторы компонентов [5] | ? | ? | ? | ? |
styled экспорта (после удивления деревьев, минификации и GZIP), рассчитанного с использованием анализатора пакета WebPack. Губер очень похож на это решение. Он такой же быстрый, меньший и имеет поддержку для нескольких дополнительных функций (стилей объектов и свойства as ). Так что же такое недостатки Губера, и зачем мне использовать это вместо этого?
StyledTest warpper, который не только обеспечивает тестирование снимков, но и делает его таким образом, что является агностикой тестирования.setup() , которая настраивает единственный глобальный экземпляр API , и это не изменяет тип темы. Расширение типа темы может быть достигнуто с помощью слияния декларации, но это снова глобально и не очень безопасно. Эта библиотека предоставляет фабрику createStyled() , которая возвращает новый экземпляр API , который имеет сильно напечатанную тему.styled.div вместо styled('div') ). Эта библиотека поддерживает styled.<tag> без поддержки времени компиляции.setup() при использовании React. Эта библиотека реагирует и требует preact/compat при использовании Preact.Эта библиотека самоуверенна и оставляет некоторые функции, которые поддерживает Губер. Это заключается в том, чтобы уменьшить количество альтернативных способов, которыми могут быть разработаны компоненты стиля, что увеличивает согласованность кода и обеспечивает общий опыт разработчика (DX). Удаление поддержки двух разных способов выполнения одного и того же самого также означает, что размер библиотеки и накладные расходы времени выполнения уменьшаются и/или выделяются для улучшения основных функций, и что библиотека в целом более поддерживается.
as для изменения базового типа компонента стилизованного компонента. Эта библиотека не связана с тем, что она по своей природе печатает небезопасно, а использование помощников стиля (например, утилита styled.string ) обеспечивает лучший способ повторного использования стилей.См. Сценарий Benchmark.js для эталонной реализации.
| Библиотека | Op/s |
|---|---|
| Минстак стиль | 144,970 |
| Губер | 142 028 |
| Эмоция | 124 681 |
| Стилизованные компоненты | 118 072 |
getId принимает дополнительный аргумент пространства имен (вновь добавлен).withConfig() для стиля шаблоновgetId и динамического классаstyled.div Альтернатива styled('div') )useInsertionEffect , когда доступноstyled.stringStyledProvidercreateSsrStyledManager )StyledTest )getId больше не принимает аргументstyled.mixinrenderStylesToString