Три концепции библиотеки styled-components


Введение

В последнее время я играю со styled-components. Это библиотека CSS-in-JS, которая использует тегированные литералы шаблонов. Я хочу рассказать о трех концепциях, которые меня озадачили: Interpolation, GlobalStyle и ThemeProvider.

Что такое интерполяция?

Интерполяция — это адаптация компонента на основе переданных ему реквизитов; это означает, что вы можете вводить значения через реквизиты. Например:

const MockElement = styled.div`
  --size: ${(props) => (props.big ? '100px' : '50px')};
  width: var(--size);
  height: var(--size);
  background-color: yellowgreen;
`;

render(
  <div>
    // This renders a 50x50 square, because there was no "big" prop
    <MockElement />
    // This renders a 100x100 square, because "big" was passed
    <MockElement big />
  <div>
)
Войти в полноэкранный режим Выйти из полноэкранного режима

Таким образом, вы можете использовать реквизиты как истинные значения. А как насчет пользовательских значений? Это тоже работает!

const MockElement = styled.div`
  background-color: ${props => props.color ? props.color : 'yellowgreen'};

  --size: ${(props) => (props.big ? '100px' : '50px')};
  width: var(--size);
  height: var(--size);
`;

render(
  <div>
    // This renders a blue square
    <MockElement color='blue'/>
    // This renders... no color??
    <MockElement color />
  <div>
)
Войти в полноэкранный режим Выход из полноэкранного режима

Стилизованные реквизиты по умолчанию являются истинными, но поскольку значение не было передано, ничего не будет отображено. Чтобы использовать значение по умолчанию с помощью этой техники, вы либо полностью пропускаете реквизит, либо передаете null.

Но будьте осторожны! Вы должны передать функцию при интерполяции значения, иначе код сломается. Что-то вроде следующего не будет работать:

const MockElement = styled.div`
  background-color: ${props.color}; /* It must be a function */
`;
Войти в полноэкранный режим Выйти из полноэкранного режима

Должна ли функция быть встроенной? Нет! Вы можете просто передать любую функцию в качестве обратного вызова:

function declaredFunction (props) {
  let scale = `${props.factor * 50}px`
  return scale
}

const MockElement = styled.div`
  --size: ${declaredFunction};
  width: var(--size);
  height: var(--size);
  background-color: ${props => props.color ? props.color : 'yellowgreen'};
`;

render(
  <div>
    // This renders a 150x150, yellowgreen square
    <MockElement big color={null} factor={3}/>
  <div>
)
Войти в полноэкранный режим Выход из полноэкранного режима

На этом изучение интерполяции заканчивается. Переходим к следующему!

Что такое GlobalStyle?

Компонент GlobalStyle, как понятно из названия, используется для определения общих правил стилизации приложения. Близким сравнением будет использование файла index.css, который импортируется и собирается перед всеми другими таблицами стилей, таким образом, перезаписываясь последующими модулями css.

Использование глобального стиля довольно просто! Сначала необходимо создать файл GlobalStyle.js, как показано ниже:

import { createGlobalStyle } from 'style-components';

const GlobalStyle = createGlobalStyle`
  /* Insert global styling here */
`;

export default GlobalStyle;
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем поместите компонент… куда угодно, на самом деле. По крайней мере, в тех нескольких тестах, которые я проводил, я размещал компонент в любом месте проекта, и он прекрасно работал. Однако для организации я разместил свою систему маршрутизации (с помощью react-router) следующим образом:

# App.js

import GlobalStyle from './utils/GlobalStyle';

function App() {
  return (
    <BrowserRouter>
      <GlobalStyle />
      <Routes>
        {/*The routes and elements go here*/}
      </Routes>
    </BrowserRouter>
  );
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Круто! Переходим к последней теме: ThemeProvider.

Что такое ThemeProvider?

ThemeProvider — это источник универсальных реквизитов для всех своих дочерних компонентов. Вы должны поместить компонент в корень вашего проекта, если хотите, чтобы все компоненты имели к нему доступ.

Так, если вы используете App.js в качестве корня, вы можете сделать что-то вроде:

#App.js
import { ThemeProvider } from 'styled-components';

const themeObject = {
  button : {
    primary : {
      background: 'lightblue',
      color: 'white',
    },
    secondary: {
      /* other keywords*/
    }
  }
}

function App() {
  return (
    <ThemeProvider theme={themeObject}>
      <CoolButton />
    </ThemeProvider>
  );
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Этот themeObject становится доступным для всех объектов, которые являются дочерними для ThemeProvider. Вы используете реквизит theme через interpolation, вот так:

#CoolButton.styled.js
import styled from 'styled-components';

const CoolButton = styled.button`
  background-color: ${props => props.theme.button.primary.background};
  /* As seen above and below, you just need to access the string from the theme object */
  color: ${props => props.theme.button.primary.color};
`
Войти в полноэкранный режим Выход из полноэкранного режима

Вы также можете объединить все три компонента, сделав GlobalComponent дочерним ThemeProvider и интерполируя значения по мере необходимости. Один из полезных примеров — установка семейства шрифта.

# theme.js

const theme = {
  heading: "Cool Heading",
  subHeading: "Cute Heading"
};

export default theme;
Вход в полноэкранный режим Выход из полноэкранного режима
# GlobalStyle.js

import { createGlobalStyle } from 'styled-components';
import coolFontPath from './font-file1.woff';
import cuteFontPath from './font-file2.woff';

const GlobalStyle = createGlobalStyle`
  @font-face {
    font-family: 'Cool Heading';
    src: url(${coolFontPath};
  }

  @font-face {
    font-family: 'Cute Heading';
    src: url(${cuteFontPath};
  }

  h1 {
    font-family: ${props => props.theme.heading};
  }

  span.subheading {
    font-family: ${props => props.theme.subHeading}
  }
`
export default GlobalStyle;
Вход в полноэкранный режим Выход из полноэкранного режима
# App.js

import GlobalStyle from './GlobalStyle.js';
import theme from './theme.js';
import { ThemeProvider } from 'styled-components';

const App = () => {
  return (
  <ThemeProvider theme={theme}>
    <h1>I belong to the Cool Heading family</h1>
    <span className='subheading'>
      I belong to the Cute Heading family
    </span>
  </ThemeProvider>
  );
}
Войти в полноэкранный режим Выход из полноэкранного режима

Резюме

Ну вот и все! Это было изучение трех важных концепций библиотеки стилей: Interpolation, GlobalStyling и ThemeProvider. Надеюсь, это было полезно!

Оцените статью
devanswers.ru
Добавить комментарий