glamorous
Зачем нужен glamorous?
Вы любите CSS в JS, но вам не нравится необходимость создавать функции компонента лишь для стилизации. Вы не хотите
придумывать имя для чего-то, относящегося только к стилям. Всё это очень раздражает: создание отдельных стилей, присваивание className
и связанные с props'ами "танцы с бубном".
Пример, как сделать с помощью glamor
(или aphrodite
или чего-то подобного):
const styles = glamor.css({
fontSize: 20,
textAlign: 'center',
})
function MyStyledDiv({className = '', ...rest}) {
return (
<div
className={`${styles} ${className}`}
{...rest}
/>
)
}
С glamorous
то, что выше, будет выглядеть просто как:
const MyStyledDiv = glamorous.div({
fontSize: 20,
textAlign: 'center',
})
Фактически, можно сделать это ещё лучше, благодаря множеству возможностей составления компонетов друг с другом!
Да, а что если вы не позаботились об имени для MyStyledDiv
? Если вы просто хотите div, который стилизуется с помощью glamor?
Вы можете сделать так тоже:
const { Div } = glamorous
function App() {
return (
<Div
fontSize={20}
textAlign="center"
>
Hello world!
</Div>
)
}
Попробовать в браузере здесь!
Итак, это основы решения glamorous
... Продолжим знакомиться с деталями!
Этот модуль распространяется через npm, предоставляемый node и должен быть установлен, как одна из зависимостей проекта:
npm install --save glamorous
Также, вам необходимо добавить react
и glamor
в ваш проект(если их там ещё нет):
npm install --save react glamor
Внимание: Если вы используете React v15.5 или выше, вам также необходимо установить
prop-types
:npm install --save prop-types
Затем вы сможете использовать один из форматов модуля:
main
: dist/glamorous.cjs.js
- экспортируется как CommonJS модульglobal
: dist/glamorous.umd.js
и dist/glamorous.umd.min.js
- экспортируются как umd модуль, который употребим в
нескольких контекстах, наиболее значимый из которых - глобальный.jsnext:main
и модуль: dist/glamorous.es.js
- экспортируются с использованием ES modules спецификации, вам будет нужно настроить webpack, чтобы использовать этот файл, с помощью resolve.mainFields свойства.Наиболее распространённый способ использования этого модуля через CommonJS:
const glamorous = require('glamorous')
const {ThemeProvider} = glamorous
// итд.
Если вы используете transpiling(и/или используете jsnext:main):
import glamorous, {ThemeProvider} from 'glamorous'
// вы можете импортировать нужный Glamorous Компонент (подробнее в разделе "Встроенные компоненты")
import {Div, H2} from 'glamorous'
// тэги с тем же именем, что и встроенные объекты JavaScript, импортируются с Tag суффиксом.
// Имя тэга, содержащее тире, нужно писать в CamelCase
import {MapTag, ColorProfile} from 'glamorous'
Если вы хотите использовать глобально:
<!-- Загрузка зависимостей -->
<script src="https://unpkg.com/react/dist/react.js"></script>
<script src="https://unpkg.com/prop-types/prop-types.js"></script>
<script src="https://unpkg.com/glamor/umd/index.js"></script>
<!-- загрузка библиотеки -->
<script src="https://unpkg.com/glamorous/dist/glamorous.umd.js"></script>
<script>
// Используй window.glamorous здесь...
const glamorous = window.glamorous
const {ThemeProvider} = glamorous
</script>
Для этого раздела нет перевода. Вы можете помочь перевести его?
start using glamorous
Функция glamorous
это дефолтный экспорт. Она позволяет создавать glamorous-компоненты,
которые рендерят стили в компонент, которому вы их дали. Это сделано путём отправки
className
prop в компонент, который вы указали ему отрендерить.
Но прежде чем мы приступим к способам оборачивания компонентов, давайте рассмотрим
встроенные DOM-элементы.
Для каждого DOM элемента, существует ассоциированная glamorous
фабрика компонента,
прикреплённая к glamorous
функции. Так же, как выше, у вас есть доступ к этим
фабрикам, таким как: glamorous.div
, glamorous.a
, glamorous.article
, и т.д.
const MyStyledSection = glamorous.section({ margin: 1 })
<MyStyledSection>содержимое</MyStyledSection>
// rendered output: <section class="<glamor-generated-class>">содержимое</section>
// styles applied: {margin: 1}
GlamorousComponent
это то, что возвращает glamorousComponentFactory.
Их работа - собрать все стили вместе, получить className
(из glamor
)
и перенаправить это в ваш компонент.
Часто бывает, что вы хотите стилизовать что-то без присваивания этому имени
(потому что именование это трудно). Так glamorous предоставляет предсозданные
GlamorousComponent
для каждого типа узлов DOM. Покажем на примере ниже:
const { Div, Span, A, Img } = glamorous
function MyUserInterface({name, tagline, imageUrl, homepage, size}) {
const nameSize = size
const taglineSize = size * 0.5
return (
<Div display="flex" flexDirection="column" justifyContent="center">
<A href={homepage} textDecoration="underline" color="#336479">
<Img borderRadius="50%" height={180} src={imageUrl} />
<Div fontSize={nameSize} fontWeight="bold">{name}</Div>
</A>
<Span fontSize={taglineSize} color="#767676">
{tagline}
</Span>
</Div>
)
}
Поробовать в браузере здесь!
Именовать всё и вся - может быть трудной задачей, а имея все эти компоненты по
умолчанию - очень удобно. Другая удобная вещь - то, что props сами являются стилями
для этих компонентов. Заметим, что glamorous умеет отличать props для стилизации, от
props, которые имеют семантическое значение (например как с Img
и A
компонентами,
которые используют src
и href
props).
Сss
prop может быть использовано, чтобы передать стили в качестве объекта.
import glamorous, {withTheme} from 'glamorous'
const { Div, Span } = glamorous
const predefinedStyle = {
color: '#767676',
fontSize: 18,
}
const MyUserInterface = withTheme(function ({tagline, theme}) {
return (
<Div
css={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
[theme.mq.tablet]: {
flexDirection: 'row'
}
}}
>
<Span css={predefinedStyle}>
{tagline}
</Span>
</Div>
)
})
Ещё один совет... Это отлично работает:
<glamorous.Div color="blue">
JSX это весело!
</glamorous.Div>
Распространённый сценарий использования props - это переопределение стиля
существующего компонента(созданного glamorous
'ом или нет). Это может быть
достигнуто использованием props className
, css
и theme
или просто
композицией компонента с glamorous()
функцией.
Если вы хотите больше узнать об использовании theme
prop, смотрите раздел
Тематизация, для более детальных объяснений. В этом разделе
мы расскажем как использовать className
, css
и композицию для переопределения
стилей компонента.
Давайте посмотрим, что может быть сделано в примере ниже.
Попробовать в браузере здесь!
Мы будем использовать это, как наш GlamorousComponent
:
const MyStyledDiv = glamorous.div({margin: 1, fontSize: 1, padding: 1})
className
Для каждого className
, которое вы передаёте, GlamorousComponent
проверяет наличие
glamor
генерируемого className
(взятого из glamor или glamorous
, не важно).
Если оно есть, компонент использует исходные стили, которые были использованы при создании
этого className
и объединит их со стилями для элемента, который рендерится, так что в
случае конфликта выиграет стиль, который вы передаёте как className
.
Любой classNames
, не генерируемый glamor
'ом, просто будет объединён с тем что уже существует.
const myCustomGlamorStyles = glamor.css({fontSize: 2})
<MyStyledDiv className={`${myCustomGlamorStyles} custom-class`} />
// применённые стили:
// {margin: 1, fontSize: 2, padding: 1}
// так же как любые применённые кастомно-классовые стили
css
Это может быть css
того же типа, что и любой из переданных стилей
(как в glamorous.div(...styles)
). Если он указан, то будет объединён со стилем
этого компонента и получит высший приоритет среди всех предопределённых стилей
компонента.
const myCustomGlamorStyles = glamor.css({fontSize: 2, padding: 2})
<MyStyledDiv
className={`${myCustomGlamorStyles} custom-class`}
css={{padding: 3}}
/>
// применённые стили:
// {margin: 1, fontSize: 2, padding: 3}
// так же как любые применённые кастомно-классовые стили
glamorous()
композицииЕсли мы просто хотим расширить стили существующего компонента, это может быть сделано
с использованием glamorous()
функции.
const MyComposedStyledDiv = glamorous(MyStyledDiv)({fontSize: 4, padding: 4})
<MyComposedStyledDiv />
// применённые стили:
// {margin: 1, fontSize: 4, padding: 4}
Фактически, встроенные фабрики DOM компонентов, всего лишь абстракции этой функции,
так что glamorous.div
может быть записан как glamorous('div')
.
Одно из достоинств glamorous - это то, что он позволяет вам проводить чёткое разделение между динамическими и статическими стилями, принуждая вас выбирать между объектом и функцией. Ниже приведён пример, имеющий оба - статический и динамический стили:
const MyLink = glamorous.a( { color: 'blue', textDecoration: 'none', }, ({size = 'small'}) => ({ fontSize: size === 'big' ? 24 : 16, }) // можно продолжить передавать любое количество // аргументов и `glamor` будет объединять их. // В случае конфликта стилей, последний получит // приоритет. ) render( <div> <MyLink href="#">Default is small</MyLink> <br /> <MyLink href="#" size="big">size="big"</MyLink> </div> )
Попробовать в браузере здесь!
Для того, чтобы создавать анимацию с glamorous, вы можете использовать
обычный CSS transitions - для простых вещей, а для продвинутых -
keyframes
из glamor
'овского css.keyframes
API.
// import * as glamor from 'glamor' // Задайте стили анимации const animationStyles = props => { const bounce = glamor.css.keyframes({ '0%': { transform: `scale(1.01)` }, '100%': { transform: `scale(0.99)` } }) return {animation: `${bounce} 0.2s infinite ease-in-out alternate`} } // Создайте элемент const AnimatedDiv = glamorous.div(animationStyles) render( <AnimatedDiv> Bounce. </AnimatedDiv> )
React Native
glamorous
предоставляет версию для проектов на React Native, называемую glamorous-native
.
npm install glamorous-native --save
Вы можете узнать больше на проект glamorous-native.