Анимация открытия и закрытия

Radix UI предоставляет мощные и гибкие компоненты для создания интерактивного интерфейса. Одной из ключевых возможностей является управление анимациями открытия и закрытия элементов, таких как модальные окна, аккордеоны, всплывающие подсказки и менюшки. Эти анимации позволяют создавать плавный пользовательский опыт и контролировать визуальные переходы компонентов.

Использование свойства asChild и анимационных классов

Большинство компонентов Radix UI используют композиционный подход. Чтобы применить анимацию, нужно понимать концепцию asChild, которая позволяет передавать собственный элемент для рендеринга компонента, сохраняя при этом все внутренние механизмы работы:

import * as Dialog from '@radix-ui/react-dialog';


  Открыть
  
    
    
      
Контент модального окна

С помощью asChild можно использовать сторонние библиотеки для анимаций, например, Framer Motion или CSS-анимации.

Анимация через CSS

Для простых анимаций Radix UI отлично интегрируется с CSS. Ключевым моментом является использование классов для состояний open и closed:

.dialog-content {
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

[data-state="open"] .dialog-content {
  opacity: 1;
  transform: translateY(0);
}

[data-state="closed"] .dialog-content {
  opacity: 0;
  transform: translateY(-10px);
}

В данном примере data-state автоматически управляется компонентом Radix UI, что делает процесс синхронизации анимаций с состоянием полностью прозрачным для разработчика.

Интеграция с Framer Motion

Для более сложных анимаций можно использовать Framer Motion. Преимущество подхода заключается в возможности использовать динамические анимации, контролируемые через пропсы:

import { motion } from 'framer-motion';
import * as Dialog from '@radix-ui/react-dialog';


  Открыть
  
    
    
      
        Контент модального окна
      
    
  

Использование motion.div позволяет управлять анимацией открытия (animate), закрытия (exit) и начального состояния (initial) без вмешательства в логику компонента.

Анимации для аккордеонов и выпадающих элементов

Radix UI предоставляет компонент Accordion, который управляет скрытием и показом панелей с помощью состояния open. Анимацию можно подключить через CSS или JS:

.accordion-content {
  height: 0;
  overflow: hidden;
  transition: height 0.3s ease;
}

[data-state="open"] .accordion-content {
  height: auto;
}

Для плавного эффекта открытия рекомендуется использовать псевдо-анимацию с переходом по высоте или использовать Framer Motion для динамического изменения высоты.

Контроль через хуки состояния

Radix UI также предоставляет доступ к состояниям через хуки, что позволяет интегрировать анимацию с другими эффектами, например:

import { useState } from 'react';
import * as Accordion from '@radix-ui/react-accordion';
import { motion } from 'framer-motion';

function AnimatedAccordion() {
  const [open, setOpen] = useState(false);

  return (
     setOpen(!open)}>
      
        
          Заголовок
        
        
          
            Контент аккордеона
          
        
      
    
  );
}

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

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

При использовании анимаций важно учитывать производительность:

  • Предпочтительно использовать transform и opacity вместо height и width для плавных переходов.
  • Для сложных анимаций лучше применять Framer Motion с AnimatePresence, чтобы избежать лишних перерендеров.
  • CSS-переходы должны быть GPU-ускоряемыми, чтобы не нагружать основной поток браузера.

Работа с порталами

Компоненты, такие как Dialog.Portal и Tooltip.Portal, рендерят элементы вне DOM-дерева родителя. Для анимаций это важно, так как классы состояния должны правильно применяться к портальному элементу. Radix UI обеспечивает автоматическое управление data-state, что упрощает синхронизацию анимаций с открытием и закрытием элементов.