@elcrm/modal
v0.0.42
Published
React-модальные окна для elCRM: очередь, размеры (в т.ч. page), вкладки, формы, списки и темы через CSS-переменные.
Maintainers
Readme
@elcrm/modal
React-библиотека модальных окон для elCRM: очередь окон, размеры, вкладки, формы, списки и кастомизация через CSS-переменные.
Установка
npm install @elcrm/modal
# или
bun add @elcrm/modalPeer-зависимости: react ≥ 18, react-dom ≥ 18, @elcrm/setting.
Быстрый старт
import { Modal } from "@elcrm/modal";
import "@elcrm/modal/style.css";
function App() {
const open = () => {
Modal.Add(
<Modal.Main title="Заголовок" size="m">
<Modal.Center>
<p>Содержимое</p>
</Modal.Center>
</Modal.Main>,
);
};
return (
<>
<button onClick={open}>Открыть</button>
<Modal.Init />
</>
);
}Modal.Main по умолчанию (scroll) оборачивает children в прокрутку с отступами — Modal.Scroll писать не обязательно.
Ритм отступов — один токен --modal-padding (30px): шапка, тело, футер. На окне: padding="24px" или в теме.
Обязательно смонтируйте <Modal.Init /> в корне приложения.
API
Компоненты
| API | Описание |
| -------------- | ------------------------------------------------------------------------------------------ |
| Modal.Init | Корневой рендер очереди модалок. Опционально: import_modules для динамической загрузки |
| Modal.Main | Окно с оверлеем: title, size, button, tabs, menu, shake, escape, scroll, padding, className |
| Modal.Panel | Панель без оверлея (те же props, что у Main) |
| Modal.Scroll | Вручную при scroll={false} или тонкой настройке |
| Modal.Center | Центрирование контента |
| Modal.Form | Форма: direction?: "row" \| "column" (по умолчанию "column") |
| Modal.Column | Горизонтальный layout колонок |
| Modal.List | Список с hover и разделителями |
Размеры size: "a" (auto) · "s" 400px · "m" 500px · "l" 800px · "x" 1000px · "f" full (max 1200px) · "p" page (весь экран поверх страницы).
Раскрытие из элемента: Create даёт Trigger и Open(params, { origin }) — FLIP-анимация из позиции клика (и обратно при закрытии).
Поведение закрытия (Main / Panel):
| Prop | По умолчанию | Описание |
| -------- | ------------ | ------------------------------------------------- |
| escape | true | Закрытие по клавише Escape (верхнее окно в стеке) |
| shake | true | Клик по оверлею трясёт окно; false — закрывает |
| scroll | true | Авто-Modal.Scroll с отступами (List/Form alone — без) |
| padding| true | true / false / "24px" → --modal-padding |
| крестик | — | Всегда закрывает и удаляет окно из очереди |
Modal.Add прокидывает в корень name и onClose — закрытие снимает модалку с очереди Init.
Функции
Modal.Add(element, name?) // добавить в очередь; name — для точечного закрытия
Modal.Close(name?) // закрыть одно окно или все
Modal.Open(type, name, params) // загрузить модуль `{type}/modal/{name}.tsx`
Modal.Icon({ type, name, params }) // иконка-триггер Open
Modal.Create(Screen, nameOrIcons?) // фабрика { Open, Icon }
Modal.Shake(event) // анимация тряскиModal.Create
Фабрика { Open, Icon }. Тип params у Open выводится из пропсов Screen
(поля name / onClose / data фабрика прокидывает сама).
type Props = { id: number; onClose?: () => void };
function EditModal({ id, onClose }: Props) {
return (
<Modal.Main title="Редактирование" onClose={onClose}>
<Modal.Scroll>
<p>ID: {id}</p>
<button type="button" onClick={onClose}>
Закрыть
</button>
</Modal.Scroll>
</Modal.Main>
);
}
const { Open, Icon } = Modal.Create(EditModal, "edit-modal");
Open({ id: 123 }); // ок
// Open({}) — ошибка TypeScript: нет idModal.Create(Screen, nameOrIcons?) // фабрика { Open, Icon }Динамическая загрузка
// Children/modal/Info.tsx
export default {
Open: (params: { id: number }) => {
Modal.Add(
<Modal.Main title="Инфо">
<Modal.Scroll>ID: {params.id}</Modal.Scroll>
</Modal.Main>,
);
},
};
Modal.Open("Children", "Info", { id: 123 });Либо передайте свой загрузчик в <Modal.Init import_modules={...} />.
Вкладки
type TabItem = {
name: string;
active?: boolean;
onClick?: () => void;
};CSS-переменные
CSS Modules с короткими уникальными классами (prefix m, как n/f/b в notice/form/button): всегда 3 символа — m + буква модуля + 1 локальная (Modal .w → mmw). Размеры и направление формы — через data-size / data-direction.
Импортируйте стили и задайте токены темы:
import "@elcrm/modal/style.css";| Переменная | Назначение |
| ---------------------------------- | -------------------- |
| --modal-padding | Горизонтальный ритм (шапка / тело / футер), default 30px |
| --modal-background-color | Фон окна |
| --modal-background-image | Фоновое изображение |
| --modal-background-overflow | Затемнение оверлея |
| --modal-box-shadow | Тень окна |
| --modal-color | Цвет текста |
| --modal-exit | Цвет кнопки закрытия |
| --modal-text | Текст в формах |
| --modal-border | Разделитель в списке |
| --modal-tinge | Подсветка hover |
| --modal-disabled | Отключённые элементы |
| --modal-radius | Скругление |
| --modal-shadow / --modal-shade | Цвета теней |
| --modal-inset / --modal-outset | Готовые тени |
Пример:
body[data-theme="light"] {
--modal-padding: 30px;
--modal-background-color: #ffffff;
--modal-color: #000000;
--modal-exit: #000000;
--modal-background-overflow: #000000b8;
--modal-text: #333333;
--modal-border: #ddd;
--modal-tinge: #0000000a;
--modal-shadow: #cccccc;
--modal-shade: #ffffff;
--modal-inset:
inset 2px 2px 2px var(--modal-shadow),
inset -1px -1px 1px var(--modal-shade);
--modal-outset:
2px 2px 2px var(--modal-shadow), -1px -1px 1px var(--modal-shade);
}На одном окне без темы:
<Modal.Main title="Плотно" padding="20px">…</Modal.Main>Поведение
- Окна можно открывать поверх друг друга; Escape закрывает только верхнее (
escape={true}). - Клик вне окна: тряска при
shake={true}(по умолчанию) или закрытие приshake={false}. - Крестик и Escape снимают окно из очереди (больше не остаётся «зомби» в
Init). button— любой JSX (например@elcrm/button).Mainрендерится через portal вdocument.body.
Лицензия
MIT © MaSkal
