К содержимому
uiify

Modal

Модальный диалог на основе нативного элемента dialog.

Браузеры
Chrome 123+Firefox 121+Safari 17.5+
Уровень
0
Сжатый размер
944 B
Лимит принудительной компоновки
0 ms
Лимит axe
0
Совместим с SSR
Да
На основе
elements/dialog
Публичный контракт
Тестовый стенд

Песочница

Modal

Закрыт

Управляемый

После гидратации этим модальным окном управляет состояние родителя.

Изменения: 0, состояние: закрыт

Примеры

Sizes

size writes data-size: sm 24rem, md (default) 28rem, lg 40rem, full fills the viewport. On a phone every size except full is a bottom sheet.

Small

24rem wide.

Large

40rem wide.

import { Modal } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Modal id="size-sm" size="sm" title="Small" trigger="Small">
        <p>24rem wide.</p>
      </Modal>
      <Modal id="size-lg" size="lg" title="Large" trigger="Large">
        <p>40rem wide.</p>
      </Modal>
    </>
  );
}

Long content

The title, content and footer share one scroll area. Compose the parts inside ModalBody for a document-style dialog.

Terms of service

The whole document scrolls together.

Clause 1: text that makes the document taller than the screen.

Clause 2: text that makes the document taller than the screen.

Clause 3: text that makes the document taller than the screen.

Clause 4: text that makes the document taller than the screen.

Clause 5: text that makes the document taller than the screen.

Clause 6: text that makes the document taller than the screen.

Clause 7: text that makes the document taller than the screen.

Clause 8: text that makes the document taller than the screen.

Clause 9: text that makes the document taller than the screen.

Clause 10: text that makes the document taller than the screen.

Clause 11: text that makes the document taller than the screen.

Clause 12: text that makes the document taller than the screen.

Clause 13: text that makes the document taller than the screen.

Clause 14: text that makes the document taller than the screen.

Clause 15: text that makes the document taller than the screen.

Clause 16: text that makes the document taller than the screen.

Clause 17: text that makes the document taller than the screen.

Clause 18: text that makes the document taller than the screen.

Clause 19: text that makes the document taller than the screen.

Clause 20: text that makes the document taller than the screen.

Clause 21: text that makes the document taller than the screen.

Clause 22: text that makes the document taller than the screen.

Clause 23: text that makes the document taller than the screen.

Clause 24: text that makes the document taller than the screen.

Clause 25: text that makes the document taller than the screen.

Clause 26: text that makes the document taller than the screen.

Clause 27: text that makes the document taller than the screen.

Clause 28: text that makes the document taller than the screen.

Clause 29: text that makes the document taller than the screen.

Clause 30: text that makes the document taller than the screen.

import { ModalTrigger, ModalContent, ModalBody, ModalHeader, ModalTitle, ModalClose, ModalFooter } from "@gunkin/uiify";
export default function Example() {
  return <>
    <ModalTrigger target="terms">Read terms</ModalTrigger>
    <ModalContent id="terms" aria-labelledby="terms-title">
      <ModalBody>
        <ModalHeader><ModalTitle id="terms-title">Terms of service</ModalTitle><ModalClose aria-label="Close" target="terms">×</ModalClose></ModalHeader>
        {Array.from({ length: 30 }, (_, index) => <p key={index}>Clause {index + 1}: text that makes the document taller than the screen.</p>)}
        <ModalFooter><ModalClose target="terms">Done</ModalClose></ModalFooter>
      </ModalBody>
    </ModalContent>
  </>;
}

Opening a modal from a modal

Render the child Modal inside the parent. It opens on top, Escape closes only the child, focus returns to the button that opened it, and the page is dimmed once.

Edit profile

Unsaved changes are lost when you close.

Discard changes?

This cannot be undone.

import { Modal, ModalClose } from "@gunkin/uiify";

export default function Example() {
  return (
    <Modal
      id="editor"
      trigger="Edit profile"
      title="Edit profile"
      description="Unsaved changes are lost when you close."
    >
      <Modal
        id="discard"
        trigger="Discard changes"
        title="Discard changes?"
        description="This cannot be undone."
        footer={<ModalClose target="discard">Keep editing</ModalClose>}
      />
    </Modal>
  );
}

API

Modal

ModalTrigger

СвойствоТипПо умолчаниюОписание
target*string—Идентификатор ModalContent, открываемого этой кнопкой; браузер разрешает его при щелчке, поэтому JavaScript библиотеки не выполняется.
childrenReactNode—Содержимое кнопки триггера.
asTAs & NativeButtonAs<TAs>"button"Компонент, передающий свойства и ref нативной кнопке; другие теги отклоняются, поскольку командам invoker нужна настоящая кнопка.

ModalContent

СвойствоТипПо умолчаниюОписание
id*string—Уникальный идентификатор, заданный потребителем; на него ссылаются триггер и цель закрытия.
size"sm" | "md" | "lg" | "full""md"Ступень ширины (24, 28, 40rem). full заполняет область просмотра. Записывается в data-size; для собственной ширины переопределите --uiify-modal-inline-size.
align"center" | "start""center"Вертикальное положение на планшете и компьютере. На телефонах используется нижняя панель, если size не равен full.
dismiss"any" | "closerequest" | "none""any"closedby: any добавляет закрытие касанием фона, closerequest разрешает только Escape, none — только ваши элементы управления. Safari не поддерживает closedby, поэтому Escape всегда закрывает; UIEnhance обрабатывает касания фона (any) и свайп панели (кроме none).
backdrop"opaque" | "blur" | "none""opaque"Оформление фона. Записывается в data-backdrop.
childrenReactNode—Содержимое диалога.

ModalClose

СвойствоТипПо умолчаниюОписание
target*string—Идентификатор ModalContent, закрываемого этой кнопкой.
childrenReactNode—Содержимое кнопки закрытия.
asTAs & NativeButtonAs<TAs>"button"Компонент, передающий свойства и ref нативной кнопке; другие теги отклоняются, поскольку командам invoker нужна настоящая кнопка.

ModalHeader

СвойствоТипПо умолчаниюОписание
childrenReactNode—Закреплённая верхняя строка с заголовком, описанием и элементом закрытия.

ModalTitle

СвойствоТипПо умолчаниюОписание
childrenReactNode—Доступное название диалога; ссылайтесь на его id из aria-labelledby.

ModalDescription

СвойствоТипПо умолчаниюОписание
childrenReactNode—Поясняющий текст; ссылайтесь на его id из aria-describedby.

ModalBody

СвойствоТипПо умолчаниюОписание
childrenReactNode—Прокручиваемая область между шапкой и подвалом.

ModalFooter

СвойствоТипПо умолчаниюОписание
childrenReactNode—Строка действий, закреплённая под содержимым.

ModalGrabber

СвойствоТипПо умолчаниюОписание
childrenReactNode—Декоративная ручка перетаскивания мобильной панели; свайп начинается здесь.

ModalClientContent (@gunkin/uiify/components/modal/client)

СвойствоТипПо умолчаниюОписание
id*string—Уникальный идентификатор, заданный потребителем; на него ссылаются триггер и закрытие.
openboolean—Управляемое состояние открытия, определяющее поведение после гидратации.
defaultOpenboolean—Неуправляемое начальное состояние, применяемое через showModal() после гидратации; серверная разметка остаётся закрытой.
onOpenChange(open: boolean) => void—Срабатывает один раз на каждое нативное или программное изменение с новым состоянием, в том числе при монтировании, если браузер открыл диалог до гидратации.
onOpenChangeComplete(open: boolean) => void—Срабатывает один раз на каждый переход открытия или закрытия после завершения переходов CSS либо сразу, если их нет, включая переход defaultOpen после гидратации; никогда не срабатывает для неизменившегося диалога.
size"sm" | "md" | "lg" | "full""md"Ступень ширины (24, 28, 40rem). full заполняет область просмотра. Записывается в data-size; для собственной ширины переопределите --uiify-modal-inline-size.
align"center" | "start""center"Вертикальное положение на планшете и компьютере. На телефонах используется нижняя панель, если size не равен full.
dismiss"any" | "closerequest" | "none""any"closedby: any добавляет закрытие касанием фона, closerequest разрешает только Escape, none — только ваши элементы управления. Safari не поддерживает closedby, поэтому Escape всегда закрывает; UIEnhance обрабатывает касания фона (any) и свайп панели (кроме none).
backdrop"opaque" | "blur" | "none""opaque"Оформление фона. Записывается в data-backdrop.
childrenReactNode—Содержимое диалога.

Клавиатура

КлавишаДействие
EscapeЗакрыть (при вложенности — только верхнее модальное окно)
TabЦиклически перемещать фокус внутри модального окна
Shift+TabОбойти элементы в обратном порядке табуляции

Доступность

Нативный <dialog> открывается триггером command="show-modal" до выполнения JavaScript. Браузер обеспечивает модальность, удержание фокуса, Escape и возврат фокуса; закрытие использует request-close, поэтому onCancel может его отменить. Иконка закрытия в шапке присутствует всегда. На телефонах модальное окно становится нижней панелью; свайп вниз и касание фона — дополнительные способы закрытия, но никогда не единственные.

Привязка стилей

data-uiify-modaldata-part="trigger|content|header|title|description|body|footer|grabber|close"data-size="sm|lg|full"data-align="start"data-backdrop="blur|none"--uiify-trigger-open (inside [data-uiify-modal][data-part="root"])--uiify-modal-inline-size (dialog width)
Эта страница переведена автоматически и ещё не проверена.