DevGang
Авторизоваться

5 лучших библиотек всплывающих окон для React

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

В экосистеме React эту потребность удовлетворяют многие библиотеки, предлагая различные уровни настройки, стратегии позиционирования и оперативности. В этом подробном руководстве мы рассмотрим пять выдающихся библиотек всплывающих окон и позиционирования для React:

  1. Popper.js
  2. act-tiny-popover
  3. react-laag
  4. reactjs-popup
  5. react Joyride

Для каждой из этих библиотек мы углубимся в их настройку, возможности позиционирования, скорость реагирования и многое другое, используя один и тот же базовый демонстрационный проект, чтобы увидеть каждую библиотеку в действии. Вы можете просмотреть код и демо-версии на CodeSandbox или перейти к концу, чтобы увидеть сравнительную таблицу для всех пяти библиотек.

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

Почему библиотеки popover?

Создание надежного всплывающего виджета с нуля может оказаться сложной задачей по многим причинам. Например, очень важно тщательно обрабатывать многочисленные крайние случаи. Эти сложности могут создать серьезные проблемы для вашего процесса разработки.

Давайте подробнее рассмотрим простой, многократно используемый компонент всплывающего окна, созданный с нуля.

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

Достижение этого в React включает в себя создание состояния компонента для переключения содержимого всплывающего окна и применение position:absolute к всплывающему поповеру, чтобы совместить его с ссылочным элементом. Следующий код должен отображать настроенное всплывающее окно:

const TableRow = ({ ... }) => {
  const [isPopoverOpen, setIsPopoverOpen] = useState(false);

  return (
    // ...
    <Popover
      isOpen={isPopoverOpen}
      content={<div className="popover-content">{popup}</div>}
    >
      <div
        className="btn-container"
        onClick={() => setIsPopoverOpen(!isPopoverOpen)}
      >
        <Button label="Admin" />
        <RxCaretSort />
      </div>
    </Popover>

Фактический компонент Popover будет выглядеть так:

const Popover = ({ isOpen, content, children }) => {
  return (
    <div className="no-library">
      {children}
      {isOpen && content}
    </div>
  ); 
};

export default Popover;

GIF ниже демонстрирует результат:

Посмотрите на код в CodeSandbox.

Хотя на данный момент эта демонстрация работает нормально, могут возникнуть две серьезные проблемы — размещение и обрезка — каждая из которых требует решения множества потенциальных крайних случаев. Давайте рассмотрим это сейчас.

Проблема с размещением

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

Чтобы предотвратить это переполнение, вы можете внести некоторые корректировки вручную. Хотя ручная настройка вполне подходит при реализации всплывающего окна в одном месте, для многократно используемого компонента мы должны включить логику динамического позиционирования.

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

Проблемы с обрезкой

Невозможно предсказать, где может оказаться повторно используемый компонент всплывающего окна. Он может располагаться внутри контейнера со стилями, которые могут нарушить отображение всплывающего окна, например, overflow: hidden или другие стили.

В таком случае, если элемент находится рядом с нижним краем границы, всплывающее окно будет обрезано:

Мы можем включить всплывающее окно, чтобы оно появлялось снаружи, и игнорировать overflow: Hidden родительского элемента, используя React Portals:

import { createPortal } from "react-dom";

const Popover = ({ isOpen, content, children }) => {
  return (
    <div>
      {children}
      {isOpen && createPortal(content, document.body)}
    </div>
  );
};

export default Popover;

Функция createPortal позволяет нам отображать контент непосредственно в указанном узле DOM — в данном случае в <body>.

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

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

1. Popper.js: механизм позиционирования всплывающих окон и всплывающих подсказок.

Popper.js — это библиотека позиционирования, разработанная для «выскакивающих» элементов, включая всплывающие окна.

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

Благодаря своим возможностям различные библиотеки пользовательского интерфейса, такие как Material UI, Foundation и Bootstrap, включают Popper.js для обеспечения точного позиционирования элементов всплывающих окон. Точно так же разработчики React часто полагаются на него как на основной инструмент для создания пользовательских всплывающих окон.

Хотя Popper.js не является эксклюзивным для React, он предоставляет оболочку React-popper, упрощая включение мощных возможностей позиционирования Popper в приложения React.

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

Настройка Popper и его использование с порталами

Сначала давайте установим @popperjs/core и его оболочку React:

npm i react-popper @popperjs/core

В предыдущем примере мы наблюдали, как функция createPortal отображает содержимое всплывающего окна в другой части DOM. Теперь давайте воспользуемся библиотекой Поппера, чтобы точно определить позиционирование.

Оболочка реакции-поппера предоставляет хук usePopper, который требует трех аргументов: referenceElement, popperElement и объекта конфигурации. В этой конфигурации мы можем указать начальное размещение всплывающего окна:

import { useState } from "react";

import { usePopper } from "react-popper";
// ...
const TableRow = ({ name, email, popup }) => {
  // ...
  const [referenceElement, setReferenceElement] = useState(null);
  const [popperElement, setPopperElement] = useState(null);

  const { styles, attributes } = usePopper(referenceElement, popperElement, {
    placement: "bottom-start",
    modifiers: [{ name: "offset", options: { offset: [0, 5] } }]
  });

  return (
    // ...
    <Popover

Хук usePopper возвращает объект, содержащий стили и атрибуты, необходимые для позиционирования всплывающего окна вместе с ссылочным элементом. Чтобы обеспечить правильное позиционирование, мы присвоили установщики всплывающего окна и ссылки атрибутам ref как для содержимого всплывающего окна, так и для ссылочного элемента.

Благодаря этой реализации всплывающее окно теперь должно плавно прикрепляться к кнопке, избегая любого переполнения, скрытого в родительском контейнере, и обеспечивая правильное позиционирование. Результат должен выглядеть так:

Посмотрите на демо-версию проекта и его исходный код в CodeSandbox.

Использование&nbsp;react-popper без createPortal

Давайте рассмотрим, как библиотека Popper управляет позиционированием без использования функции createPortal. После удаления его из кода у нас теперь есть следующее:

// import { createPortal } from "react-dom";

const Popover = ({ isOpen, content, children }) => {
  return (
    <div>
      {children}
      {isOpen && content}
      {/* {isOpen && createPortal(content, document.body)} */}
    </div>
  );
};

export default Popover;

Библиотека достаточно умна, чтобы перевернуть содержимое всплывающего окна в другое место, которое лучше подходит, благодаря ее способности обрабатывать контексты offsetParent. Нет необходимости перемещать popper за пределы исходного контекста DOM:

Посмотрите исходный код на CodeSandbox и посмотрите живую демонстрацию, чтобы убедиться в этом сами.

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

2. React-tiny-popover: легкая, но блестящая библиотека.

Если вы ищете простоту и минимальную занимаемую площадь, react-tiny-popover на отличный выбор для создания всплывающих окон.

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

Настройка и использование response-tiny-popover

Вы можете установить response-tiny-popover как есть, без каких-либо других зависимостей:

npm install react-tiny-popover –save

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

// ...
import { Popover, ArrowContainer } from "react-tiny-popover";

const TableRow = ({ name, email, popup }) => {
  const [isPopoverOpen, setIsPopoverOpen] = useState(false);
  return (
    // ...
    <Popover
      isOpen={isPopoverOpen}
      positions={["top", "bottom", "left", "right"]}
      align="start"
      padding={8}
      onClickOutside={() => setIsPopoverOpen(false)}
      content={({ position, childRect, popoverRect }) => (
        <ArrowContainer
          position={position}
          childRect={childRect}
          popoverRect={popoverRect}
          arrowColor={"#2a2e2d"}
          arrowSize={8}
        >
          <div>
            <div className="popover-content">{popup}</div>
          </div>
        </ArrowContainer>
      )}
    >
      <div
        onClick={() => setIsPopoverOpen(!isPopoverOpen)}
        className="btn-container"
      >
        <Button label="Admin" />
        <RxCaretSort />
      </div>
    </Popover>
    // ...
  );
};

Компонент Popover из библиотеки требует три реквизита:

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

Ожидаемое поведение компонента Popover выглядит следующим образом:

Подобно возможности позиционирования, предлагаемой Popper.js, act-tiny-popover также может защищать границы контейнера и перемещать себя, чтобы предотвратить скрытое переполнение. Однако, в отличие от Popper, эта библиотека по умолчанию перемещает содержимое всплывающего окна за пределы контекста DOM, добавляя его в document.body:

Чтобы расположить всплывающее окно рядом с кнопкой, которая его активирует, включите свойство родительского элемента, а затем оберните всплывающее окно ссылочным элементом:

import { useState, useRef } from "react";
// ...
const TableRow = ({ name, email, popup }) => {
  // ...
  const boxContainerRef = useRef();
  return (
    // ...
      <div className="popover-container" ref={boxContainerRef}>
        <Popover
          // ...
          parentElement={boxContainerRef.current}
        >
          {...}
        </Popover>
    </div>
    //   ...
  );
};

Поповер теперь должен быть прикреплен к элементу контейнера, а не к элементу body:

Если вы предпочитаете всплывающее окно без стрелки, вы можете изменить свойство содержимого, чтобы исключить ArrowContainer, следующим образом:

content={<div className="popover-content">{popup}</div>}

Посмотрите исходный код и демонстрацию в CodeSandbox.

3. Реакция-задержка

React-laag предоставляет крючок для позиционирования всплывающих окон. Как и в случае с Popper.js, над созданием визуальных аспектов поповера все еще приходится прикладывать некоторые усилия. Библиотека выполняет сложные вычисления для достижения точного позиционирования.

В последнее время его популярность растет: с менее чем 50 тысяч загрузок npm в неделю до более 138 тысяч за последний год:

Настройка и использование React-laag

Как и в случае с React-Tiny-Popover, вы можете установить React-Laag без каких-либо зависимостей:

npm install react-laag

Вот краткий пример интеграции библиотеки в наш проект:

// ...
import { useLayer, Arrow } from "react-laag";

const TableRow = ({ name, email, popup }) => {
  const [isOpen, setIsOpen] = useState(false);

  const { renderLayer, triggerProps, layerProps, arrowProps } = useLayer({
    isOpen,
    onOutsideClick: () => setIsOpen(false),
    onDisappear: () => setIsOpen(false),
    overflowContainer: false,
    auto: true,
    placement: "right-start",
    triggerOffset: 12,
    arrowOffset: 16
  });
return (
    // ...
    <Popover
      isOpen={isOpen}
      content={renderLayer(
        <div className="popover-content" {...layerProps}>
          {popup}
          <Arrow {...arrowProps} backgroundColor="#2a2e2d" />
        </div>
      )}
    >
      <div
        {...triggerProps}
        onClick={() => setIsOpen(!isOpen)}
        className="btn-container"
      >
        <Button label="Admin" />
        <RxCaretSort />
      </div>
    </Popover>
    // ...
  );
};

Несмотря на то, что эта библиотека в первую очередь ориентирована на позиционирование, она предоставляет важные функции всплывающего окна, такие как функция onOutsideClick, для управления событием внешнего щелчка, которое закрывает всплывающее окно. См. ожидаемое поведение в демонстрации ниже:

Посмотрите на исходный код этой демонстрации реакции в CodeSandbox.

4. Reactjs-popup

Библиотека всплывающих окон responsejs-popup — отличный выбор для тех, кто ищет универсальность в простом пакете. Он предлагает полностью доступный всплывающий компонент, улучшающий взаимодействие с пользователем для людей, которые полагаются на навигацию с помощью клавиатуры.

Настройка и использование Reactjs-popup

Установить Reactjs-popup очень просто. Просто используйте эту команду:

npm i reactjs-popup

Код ниже демонстрирует, как создать всплывающее окно с помощью реакции js-popup:

import Popup from "reactjs-popup";

const TableRow = ({ name, email, popup }) => {
  return (
    // ...
    <Popup
      trigger={
        <div className="btn-container">
          <Button label="Admin" />
          <RxCaretSort />
        </div>
      }
      position={["top left", "top right", "bottom left", "bottom right"]}
      closeOnDocumentClick
      arrowStyle={{ color: "#2a2e2d" }}
    >
      <div className="popover-content">{popup}</div>
    </Popup>
    // ...
  );
};

Это самая простая реализация всплывающего окна для нашего гипотетического проекта, которую мы видели до сих пор. Reactjs-popup предоставляет нам простой в использовании компонент Popup и очень хорошо справляется со сложным позиционированием. Не стесняйтесь изучать исходный код и демо-версию на CodeSandbox.

5. React Joyride: экскурсии с поповерами

React Joyride использует уникальный подход к поповерам, специализируясь на поповерах, предназначенных для экскурсий по приложениям React. Это отличный выбор для динамичного и увлекательного привлечения новых пользователей.

Прежде чем реализовать эту библиотеку, давайте посмотрим краткую демонстрацию того, что она влечет за собой:

Как мы видим, React Joyride обеспечивает достаточный контроль над расположением всплывающего окна, чтобы обеспечить удобство взаимодействия с пользователем. Он может адаптироваться к экранам разных размеров, что делает его идеальным для ознакомления.

Настройка и использование React Joyride

Установка React Joyride проста: требуется только следующая команда без каких-либо других зависимостей:

npm i react-joyride

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

import { useState } from "react";
import Joyride from "react-joyride";
// ...

const TableRow = ({ name, email, popup }) => {

  const [{ run, steps }] = useState({
    run: true,
    steps: [
      {
        content: <h2>Tour this app with me!</h2>,
        locale: { skip: <strong>SKIP</strong> },
        placement: "center",
        target: "body"   
      }, 
      { 
        content: <h2>User's details</h2>,
        placement: "bottom",
        target: ".user"
      },
      {
        content: <h2>Assign a role</h2>,
        placement: "bottom",
        target: ".btn-container"
      },
      {
        content: <h2>Take me to next section</h2>,
        placement: "bottom",
        target: ".navigation"
      }
    ]
  });

  return (
    <>
      <Joyride
        steps={steps}
        continuous
        hideCloseButton
        run={run}
        scrollToFirstStep
        showProgress
        showSkipButton
      />
      {/* ... */}
    </>
  );
};

Вы можете увидеть полный код на CodeSandbox.

Таблица сравнения всплывающих библиотек React

Эта сравнительная таблица для всех пяти библиотек popover может оказаться полезным ресурсом, поскольку вы решите, какой вариант лучше всего подходит для вашего проекта:

Заключение

Поповеры предоставляют интерактивный и удобный способ улучшения ваших приложений React, но их может быть сложно реализовать с нуля. Библиотеки всплывающих окон могут облегчить работу с различными крайними случаями, поэтому ваши компоненты всплывающих окон будут отлично выглядеть и работать на любом устройстве и экране любого размера.

В огромном разнообразии всплывающих библиотек React выбор сводится к конкретным потребностям вашего проекта. Независимо от того, стремитесь ли вы к легкой простоте реагирования на reactjs-popup и react-tiny-popover или к надежным возможностям позиционирования Popper.js, вы можете выбирать из множества вариантов.

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

В конце концов, изучение этих библиотек не только улучшит ваши навыки работы с React, но и даст вам возможность создавать привлекательные и удобные всплывающие интерфейсы.

Посмотреть все демо-версии проекта можно здесь.

Источник:

#JavaScript #React
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу