Управление состоянием раскрытия

Chakra UI предоставляет удобные инструменты для управления видимостью компонентов и их состоянием раскрытия. Основной подход заключается в использовании хука useDisclosure, который упрощает управление открытием и закрытием элементов, таких как модальные окна, аккордеоны, выпадающие меню и боковые панели.


Хук useDisclosure

Хук useDisclosure возвращает объект с несколькими ключевыми свойствами:

const { isOpen, onOpen, onClose, onToggle } = useDisclosure();
  • isOpen — логическое значение, показывающее, открыт компонент или закрыт.
  • onOpen — функция, устанавливающая isOpen в true.
  • onClose — функция, устанавливающая isOpen в false.
  • onToggle — функция, переключающая состояние isOpen.

Пример использования с модальным окном:

import { Button, Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@chakra-ui/react";
import { useDisclosure } from "@chakra-ui/react";

function ExampleModal() {
  const { isOpen, onOpen, onClose } = useDisclosure();

  return (
    <>
      <Button onCl ick={onOpen}>Открыть модальное окно</Button>

      <Modal isOpen={isOpen} onCl ose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Заголовок модального окна</ModalHeader>
          <ModalBody>
            Содержимое модального окна
          </ModalBody>
          <ModalFooter>
            <Button onCl ick={onClose}>Закрыть</Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </>
  );
}

Управление аккордеонами

Для компонентов типа Accordion также важно управление раскрытием. Chakra UI предоставляет компонент AccordionItem с собственным контролем состояния, но для более сложных сценариев можно использовать useDisclosure:

import { Accordion, AccordionItem, AccordionButton, AccordionPanel, Box, useDisclosure } from "@chakra-ui/react";

function ControlledAccordion() {
  const { isOpen, onToggle } = useDisclosure();

  return (
    <Accordion allowToggle>
      <AccordionItem>
        <h2>
          <AccordionButton onCl ick={onToggle}>
            <Box flex="1" textAlign="left">
              Заголовок аккордеона
            </Box>
          </AccordionButton>
        </h2>
        {isOpen && <AccordionPanel pb={4}>Содержимое аккордеона</AccordionPanel>}
      </AccordionItem>
    </Accordion>
  );
}
  • allowToggle позволяет открывать и закрывать отдельный элемент аккордеона без влияния на остальные.
  • Управление через useDisclosure обеспечивает синхронизацию состояния с другими компонентами или внешней логикой.

Раскрытие боковой панели (Drawer)

Компонент Drawer также тесно интегрирован с useDisclosure. Принцип тот же: управление видимостью через isOpen, onOpen и onClose.

import { Drawer, DrawerBody, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerContent, DrawerCloseButton, Button } from "@chakra-ui/react";

function ExampleDrawer() {
  const { isOpen, onOpen, onClose } = useDisclosure();

  return (
    <>
      <Button onCl ick={onOpen}>Открыть боковую панель</Button>
      <Drawer isOpen={isOpen} placement="right" onCl ose={onClose}>
        <DrawerOverlay />
        <DrawerContent>
          <DrawerCloseButton />
          <DrawerHeader>Боковая панель</DrawerHeader>
          <DrawerBody>
            Содержимое панели
          </DrawerBody>
          <DrawerFooter>
            <Button onCl ick={onClose}>Закрыть</Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
    </>
  );
}
  • placement определяет позицию боковой панели (left, right, top, bottom).
  • Использование DrawerCloseButton обеспечивает дополнительный способ закрытия через UI.

Синхронизация нескольких компонентов

Иногда требуется синхронизировать несколько раскрывающихся компонентов, например, модальное окно и аккордеон. Для этого можно использовать один экземпляр useDisclosure:

const { isOpen, onOpen, onClose } = useDisclosure();

<Button onCl ick={onOpen}>Открыть оба компонента</Button>
<Modal isOpen={isOpen} onCl ose={onClose}>...</Modal>
<AccordionItem isOpen={isOpen}>...</AccordionItem>

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


Управление анимациями и задержками

Chakra UI позволяет комбинировать useDisclosure с компонентами Collapse или Fade для плавного раскрытия:

import { Collapse, Button, Box, useDisclosure } from "@chakra-ui/react";

function ExampleCollapse() {
  const { isOpen, onToggle } = useDisclosure();

  return (
    <>
      <Button onCl ick={onToggle}>Переключить</Button>
      <Collapse in={isOpen} animateOpacity>
        <Box p="40px" color="white" mt="4" bg="teal.500" rounded="md" shadow="md">
          Плавное раскрытие содержимого
        </Box>
      </Collapse>
    </>
  );
}
  • animateOpacity добавляет эффект постепенного появления.
  • Collapse автоматически управляет высотой содержимого при открытии и закрытии.

Рекомендации по использованию

  • Использовать useDisclosure везде, где требуется бинарное состояние открытия/закрытия.
  • Для сложных сценариев с несколькими компонентами централизовать состояние, чтобы избежать несинхронизированных открытий.
  • Комбинировать с компонентами Collapse, Fade или ScaleFade для улучшения пользовательского опыта.
  • Использовать onToggle для компонентов с переключением состояния по одному элементу, и onOpen/onClose для строгого управления открытием и закрытием.

Chakra UI с useDisclosure обеспечивает гибкое и интуитивное управление раскрытием элементов, позволяя создавать интерактивные интерфейсы без громоздкой логики состояния.