Styled Components

Styled Components — это библиотека для стилизации компонентов в экосистеме JavaScript, обеспечивающая удобный способ писать CSS непосредственно внутри компонентов. Она широко используется с React, но полностью совместима с Preact через адаптеры и совместимые версии. Основная идея заключается в объединении логики компонента и его стилей, что упрощает поддержку и масштабирование приложения.

Установка и интеграция

Для работы со Styled Components в Preact необходимо использовать совместимую версию:

npm install styled-components
npm install --save-dev @types/styled-components

В Preact можно использовать библиотеку через пакет preact/compat, который обеспечивает совместимость API с React:

import { h } from 'preact';
import styled from 'styled-components';

Это позволяет использовать все возможности Styled Components практически без изменений в привычной React-среде.

Создание стилизованных компонентов

Основная концепция Styled Components заключается в создании компонентов с заранее определёнными стилями. Синтаксис использует шаблонные литералы:

const Button = styled.button`
  background-color: #3498db;
  color: white;
  font-size: 16px;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s ease;

  &:hover {
    background-color: #2980b9;
  }
`;

В этом примере создаётся кнопка с базовыми стилями и эффектом при наведении. Компонент Button может быть использован как обычный Preact-компонент:

const App = () => (
  <Button>Нажми меня</Button>
);

Передача пропсов для динамических стилей

Styled Components позволяет создавать динамические стили, изменяя их в зависимости от пропсов компонента. Это обеспечивает гибкость и повторное использование компонентов:

const Button = styled.button`
  background-color: ${props => props.primary ? '#3498db' : '#bdc3c7'};
  color: ${props => props.primary ? 'white' : 'black'};
  padding: ${props => props.large ? '15px 30px' : '10px 20px'};
  border-radius: 5px;
  border: none;
  cursor: pointer;
`;

const App = () => (
  <>
    <Button primary large>Главная кнопка</Button>
    <Button>Второстепенная кнопка</Button>
  </>
);

Такой подход избавляет от необходимости создавать отдельные классы CSS для каждого варианта компонента.

Наследование стилей

Styled Components поддерживает наследование, что упрощает создание модифицированных версий компонентов:

const PrimaryButton = styled(Button)`
  background-color: #e74c3c;
  &:hover {
    background-color: #c0392b;
  }
`;

const App = () => <PrimaryButton>Удалить</PrimaryButton>;

В этом примере PrimaryButton наследует все стили базовой кнопки Button и добавляет уникальные свойства.

Использование глобальных стилей

Для задания глобальных CSS-правил используется createGlobalStyle:

import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    font-family: 'Arial', sans-serif;
    background-color: #f5f5f5;
  }
`;

const App = () => (
  <>
    <GlobalStyle />
    <Button>Пример кнопки</Button>
  </>
);

Это позволяет централизованно управлять стилями приложения, не создавая конфликтов с компонентными стилями.

Тема и контекст

Styled Components предоставляет поддержку тем через объект ThemeProvider. Это полезно для реализации светлой и тёмной темы, или для настройки цветовой схемы всего приложения:

import { ThemeProvider } from 'styled-components';

const theme = {
  colors: {
    primary: '#3498db',
    secondary: '#2ecc71'
  },
  fontSize: '16px'
};

const ThemedButton = styled.button`
  background-color: ${props => props.theme.colors.primary};
  color: white;
  font-size: ${props => props.theme.fontSize};
  padding: 10px 20px;
`;

const App = () => (
  <ThemeProvider theme={theme}>
    <ThemedButton>Кнопка с темой</ThemedButton>
  </ThemeProvider>
);

Это решение упрощает масштабирование приложения и обеспечивает единообразие визуального стиля.

Оптимизация производительности

Styled Components автоматически генерирует уникальные классы для компонентов, что минимизирует конфликты CSS. Однако при работе с Preact важно учитывать, что избыточное использование динамических пропсов и условий может приводить к дополнительной генерации классов. Для оптимизации рекомендуется:

  • Использовать статические стили там, где это возможно.
  • Минимизировать количество вычислений внутри шаблонных литералов.
  • Применять attrs для передачи неизменяемых атрибутов:
const Input = styled.input.attrs({
  type: 'text'
})`
  padding: 10px;
  border-radius: 5px;
  border: 1px solid #ccc;
`;

Это уменьшает количество пересоздаваемых стилей при ререндере.

Совместимость с Preact

Для обеспечения полной совместимости необходимо:

  • Подключать preact/compat.
  • Использовать версии Styled Components, совместимые с Preact.
  • Проверять работу темы и глобальных стилей, так как некоторые специфичные плагины могут быть рассчитаны только на React.

Это позволяет использовать Styled Components в Preact-проектах без потери функциональности и преимуществ CSS-in-JS.