В Radix UI взаимодействие с компонентами, такими как DropdownMenu, Popover, Tooltip и HoverCard, часто требует тонкой настройки поведения при наведении или клике. Одним из ключевых аспектов UX является задержка открытия и закрытия компонентов, чтобы избежать резких или случайных действий пользователя.
Radix UI предоставляет встроенные пропсы для управления задержками:
delayDuration — задает время задержки
перед открытием компонента.closeDelay — устанавливает время
задержки перед закрытием компонента (доступно не для всех компонентов,
часто используется через onOpenChange с таймером).disableOutsidePointerEvents — иногда
используется совместно с задержками, чтобы блокировать клики вне
компонента до его закрытия.Пример на Popover:
import * as Popover from '@radix-ui/react-popover';
<Popover.Root>
<Popover.Trigger>Открыть попап</Popover.Trigger>
<Popover.Content
sideOffset={5}
align="start"
onOpenAutoFo cus={(event) => event.preventDefault()}
delayDuration={300} // Задержка перед открытием 300мс
>
Контент попапа с задержкой открытия
</Popover.Content>
</Popover.Root>
Здесь delayDuration задает
время ожидания перед появлением контента, что позволяет
избежать мгновенных открытий при случайном наведении или клике.
Radix UI не всегда предоставляет отдельный проп
closeDelay, поэтому закрытие с задержкой реализуется через
управление состоянием компонента:
import { useState, useEffect } from 'react';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
function DelayedDropdown() {
const [open, setOpen] = useState(false);
const [delayedClose, setDelayedClose] = useState(null);
const handleOpenChange = (isOpen) => {
if (!isOpen) {
const timer = setTimeout(() => setOpen(false), 500); // Задержка закрытия 500мс
setDelayedClose(timer);
} else {
clearTimeout(delayedClose);
setOpen(true);
}
};
return (
<DropdownMenu.Root open={open} onOpenCha nge={handleOpenChange}>
<DropdownMenu.Trigger>Меню</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item>Элемент 1</DropdownMenu.Item>
<DropdownMenu.Item>Элемент 2</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
);
}
Пояснение:
Для компонентов, реагирующих на наведение курсора, задержки особенно важны:
import * as HoverCard from '@radix-ui/react-hover-card';
<HoverCard.Root openDelay={400} closeDelay={200}>
<HoverCard.Trigger>Наведи курсор</HoverCard.Trigger>
<HoverCard.Content>
Информация с задержкой открытия 400мс и закрытия 200мс
</HoverCard.Content>
</HoverCard.Root>
Ключевые моменты:
openDelay — задержка перед открытием
при наведении.closeDelay — задержка перед закрытием
после ухода курсора.Часто задержки сочетаются с анимациями появления и исчезновения:
import { keyframes, styled } from '@stitches/react';
const fadeIn = keyframes({
from: { opacity: 0 },
to: { opacity: 1 }
});
const fadeOut = keyframes({
from: { opacity: 1 },
to: { opacity: 0 }
});
const AnimatedContent = styled(HoverCard.Content, {
animation: `${fadeIn} 0.3s`,
'&[data-state="closed"]': {
animation: `${fadeOut} 0.3s`
}
});
Особенности интеграции:
data-state для
управления состояниями.HoverCard и Tooltip.useState и таймеры.Задержки открытия и закрытия в Radix UI обеспечивают плавность, предсказуемость и улучшенный пользовательский опыт, особенно для компонентов с наведением или вложенной навигацией. Их гибкая настройка через пропсы и управление состоянием позволяет реализовать как простые, так и сложные сценарии поведения интерфейса.