React Aria предоставляет инструменты для создания доступных компонентов пользовательского интерфейса, при этом управление динамическими размерами элементов является одной из ключевых задач при разработке адаптивных интерфейсов. Динамические размеры позволяют компонентам подстраиваться под содержимое, состояние или размер контейнера, сохраняя при этом совместимость с ARIA-стандартами для пользователей с особыми потребностями.
useResizeObserver для отслеживания изменений размеровОдним из основных подходов в React Aria для работы с динамическими
размерами является использование хука useResizeObserver. Он
позволяет реагировать на изменения размеров DOM-элементов в реальном
времени.
Пример использования:
import {useResizeObserver} from '@react-aria/utils';
import {useRef, useState} from 'react';
function ResizableComponent() {
const ref = useRef();
const [size, setSize] = useState({width: 0, height: 0});
useResizeObserver({
ref,
onResize: (entry) => {
setSize({width: entry.contentRect.width, height: entry.contentRect.height});
}
});
return (
Ширина: {size.width}px, Высота: {size.height}px
);
}
Ключевые моменты:
ref привязывается к отслеживаемому элементу.onResize срабатывает каждый раз, когда размеры элемента
изменяются.entry.contentRect предоставляет актуальные значения
ширины и высоты.Использование useResizeObserver обеспечивает корректное
обновление интерфейса и предотвращает некорректное отображение элементов
при изменении размеров окна или контента.
React Aria предоставляет хуки для интерактивных компонентов
(например, useButton, useSlider,
usePopover), которые можно комбинировать с динамическим
управлением размерами.
import {usePopover, useOverlayPosition} from '@react-aria/overlays';
import {useRef, useState} from 'react';
function AdaptivePopover({isOpen, onClose, children}) {
const triggerRef = useRef();
const popoverRef = useRef();
const [popoverWidth, setPopoverWidth] = useState(0);
useResizeObserver({
ref: triggerRef,
onResize: ({contentRect}) => {
setPopoverWidth(contentRect.width);
}
});
const {popoverProps} = usePopover({isOpen, onClose}, popoverRef);
const {overlayProps} = useOverlayPosition({
targetRef: triggerRef,
overlayRef: popoverRef,
placement: 'bottom'
});
return (
<>
{isOpen && (
{children}
)}
>
);
}
Особенности:
useOverlayPosition обеспечивает корректное
позиционирование при изменении размеров окна.useResizeObserver и
usePopover гарантирует доступность и адаптивность.В некоторых случаях необходимо, чтобы элементы автоматически подстраивались под размер контента. Для этого используется динамическое вычисление размеров с последующим обновлением состояния компонента.
Пример: адаптивный textarea
import {useRef, useState, useLayoutEffect} from 'react';
function AutoSizeTextarea() {
const ref = useRef();
const [height, setHeight] = useState('auto');
useLayoutEffect(() => {
if (ref.current) {
setHeight(ref.current.scrollHeight + 'px');
}
}, [ref.current?.value]);
return (
Особенности:
scrollHeight позволяет измерять реальную высоту
содержимого.useLayoutEffect гарантирует обновление перед рендером,
предотвращая мерцание.requestAnimationFrame –
для плавного обновления размеров при анимации.Динамические размеры напрямую влияют на доступность. Необходимо учитывать:
aria-expanded, aria-hidden,
aria-valuenow).aria-live или соответствующих ролей.Для адаптивного дизайна часто используются CSS-сетки. React Aria
позволяет динамически подстраивать размеры компонентов внутри
flex или grid:
{items.map(item => (
{item.content}
))}
Комбинация CSS Grid и хуков React Aria для динамических размеров обеспечивает: