npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@elcrm/modal

v0.0.42

Published

React-модальные окна для elCRM: очередь, размеры (в т.ч. page), вкладки, формы, списки и темы через CSS-переменные.

Readme

@elcrm/modal

React-библиотека модальных окон для elCRM: очередь окон, размеры, вкладки, формы, списки и кастомизация через CSS-переменные.

npm version license

Установка

npm install @elcrm/modal
# или
bun add @elcrm/modal

Peer-зависимости: 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: нет id
Modal.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 .wmmw). Размеры и направление формы — через 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