Styled components подход

Styled Components в контексте Naive UI представляют собой метод организации и стилизации компонентов с использованием возможностей CSS-in-JS. Основная идея заключается в том, чтобы создавать стилизованные версии стандартных компонентов Naive UI, инкапсулируя их стили и логику в одном месте. Такой подход повышает повторное использование компонентов и упрощает управление стилями при масштабировании проекта.


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

Для начала нужно импортировать компонент из Naive UI, который будет базовым:

import { NButton } from 'naive-ui'
import { styled } from '@stitches/react'

Использование styled позволяет определить отдельный компонент с кастомными стилями:

const PrimaryButton = styled(NButton, {
  backgroundColor: '#409EFF',
  color: '#ffffff',
  borderRadius: '6px',
  padding: '8px 16px',
  fontWeight: '600',
  '&:hover': {
    backgroundColor: '#66b1ff'
  },
  '&:disabled': {
    backgroundColor: '#c0c4cc',
    color: '#ffffff'
  }
})

Ключевые моменты:

  • Первый аргумент styled — базовый компонент Naive UI.
  • Второй аргумент — объект CSS, где можно описывать базовые стили и псевдоклассы (&:hover, &:focus, &:disabled).
  • Стили изолированы и применяются только к конкретной версии компонента.

Использование пропсов для динамической стилизации

Styled Components поддерживают динамическую настройку через пропсы:

const AlertButton = styled(NButton, {
  variants: {
    type: {
      success: { backgroundColor: '#67C23A', color: '#ffffff' },
      warning: { backgroundColor: '#E6A23C', color: '#ffffff' },
      danger: { backgroundColor: '#F56C6C', color: '#ffffff' }
    },
    size: {
      small: { padding: '4px 12px', fontSize: '12px' },
      medium: { padding: '8px 16px', fontSize: '14px' },
      large: { padding: '12px 20px', fontSize: '16px' }
    }
  },
  defaultVariants: {
    type: 'success',
    size: 'medium'
  }
})

Пояснения:

  • variants позволяют создавать набор предустановленных стилей для компонента.
  • defaultVariants задаёт значения по умолчанию, если пропсы не переданы.
  • Такой подход значительно упрощает создание многофункциональных компонентов с минимальным дублированием кода.

Комбинирование нескольких компонентов

Иногда нужно объединить несколько базовых компонентов в один стилизованный:

const CardHeader = styled('div', {
  display: 'flex',
  justifyContent: 'space-between',
  alignItems: 'center',
  padding: '12px 16px',
  borderBottom: '1px solid #ebeef5',
  backgroundColor: '#f5f7fa'
})

const CardTitle = styled('h3', {
  margin: 0,
  fontSize: '16px',
  fontWeight: '600'
})

const CardActionButton = styled(NButton, {
  fontSize: '14px',
  color: '#409EFF',
  background: 'none',
  padding: '0 8px',
  '&:hover': {
    color: '#66b1ff'
  }
})

В результате можно создать комплексный компонент Card с заголовком и кнопкой действия, сохранив полное разделение стилей и компонентов.


Интеграция с темизацией

Naive UI и Styled Components поддерживают динамическую тему. Например, можно использовать CSS-переменные или тему Stitches:

const ThemedButton = styled(NButton, {
  backgroundColor: '$primary',
  color: '$onPrimary',
  '&:hover': {
    backgroundColor: '$primaryHover'
  }
})
  • $primary, $onPrimary, $primaryHover — переменные темы, которые можно менять глобально.
  • Такой подход обеспечивает гибкость при смене темы, например, при переходе между светлой и тёмной.

Работа с анимациями и состояниями

Styled Components позволяют определять анимации прямо в компоненте:

const AnimatedButton = styled(NButton, {
  transition: 'transform 0.2s ease-in-out, background-color 0.2s',
  '&:hover': {
    transform: 'scale(1.05)',
    backgroundColor: '#66b1ff'
  },
  '&:active': {
    transform: 'scale(0.95)'
  }
})
  • transition обеспечивает плавное изменение стилей.
  • Псевдоклассы &:hover, &:active дают визуальный отклик пользователю без использования дополнительных библиотек.

Сильные стороны подхода

  • Изоляция стилей: каждый компонент имеет свои собственные CSS-правила.
  • Повторное использование: легко создавать библиотеки кастомных компонентов.
  • Поддержка динамических пропсов: варианты и темы позволяют менять внешний вид без дублирования кода.
  • Интеграция с Naive UI: можно использовать все функциональные возможности компонентов Naive UI и при этом добавлять кастомные стили.