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

@ezuikit/control-modal

v0.0.1

Published

draggable modal dialog control for ezviz

Readme

Modal 弹框控件

可拖动的模态弹框,支持多实例层级管理、点击置顶、拖动标题栏移动、Esc 关闭,且拖动时限制在视口内不超出页面。

特性

  • 支持右上角 X 关闭、Esc 关闭、点击遮罩关闭
  • 支持拖动标题栏移动窗口,约束在视口范围内
  • 多实例层级管理:后创建自动在最上层,点击任意弹框自动置顶
  • ModalProvider 单例:统一管理全部 Modal 实例的注册、z-index 分配与批量销毁

Usage

npm install @ezuikit/control-modal
# or
pnpm add @ezuikit/control-modal

ESM / CJS

import '@ezuikit/control-modal/dist/style/style.css';
import Modal, { ModalProvider } from '@ezuikit/control-modal';

// 第一个参数为挂载容器 container,第二个参数为 options
const modal = new Modal('#app', {
  title: '设备信息',
  content: '<p>这里是弹框内容</p>',
  width: 480,
  draggable: true,
  showClose: true,
});

modal.open();

// 关闭 / 置顶 / 销毁
modal.close();
modal.bringToTop();
modal.destroy();

// 事件
modal.on(Modal.EVENTS.dragging, (pos) => console.log('dragging', pos));
modal.on(Modal.EVENTS.close, () => console.log('closed'));

UMD / CDN

<link rel="stylesheet" href="./style/style.css" />
<script src="./index.umd.js"></script>
<script>
  const modal = new Modal(document.body, { title: 'Title', content: 'Hello' });
  modal.open();

  // ModalProvider 通过 Modal.Provider 访问
  Modal.Provider.getInstance().getInstances(); // 获取全部实例
</script>

多实例 + ModalProvider

import Modal, { ModalProvider } from '@ezuikit/control-modal';

// 创建多个实例——后创建者自动在最上层
const m1 = new Modal(document.body, { title: '实例-1', content: '...', open: true });
const m2 = new Modal(document.body, { title: '实例-2', content: '...', open: true });

// 点击任一弹框,该弹框自动置顶(内部调用 bringToTop)

// 手动置顶
m1.bringToTop();

// 通过 ModalProvider 统一管理
const provider = ModalProvider.getInstance();
console.log(provider.count); // 已注册实例数
console.log(provider.getInstances()); // 全部 Modal 实例

// 批量销毁
provider.destroyAll();

构造函数

new Modal(container?, options?)

| 参数 | 类型 | 默认值 | 说明 | | ----------- | ----------------------- | --------------- | --------------------------------------------- | | container | string \| HTMLElement | document.body | 挂载容器,支持 CSS 选择器字符串或 HTMLElement | | options | ModalOptions | — | 配置项,见下表 |

配置项 ModalOptions

| 选项 | 类型 | 默认值 | 说明 | | --------------- | ----------------------- | ---------- | ----------------------------------------------------------------- | | title | string \| HTMLElement | — | 标题 | | content | string \| HTMLElement | — | 内容 | | width | number \| string | 420 | 宽度(number 视为 px) | | height | number \| string | auto | 高度 | | position | 'center' \| { x, y } | 'center' | 展示位置;坐标会约束在视口内 | | draggable | boolean | true | 是否允许拖动标题栏 | | showMask | boolean | true | 是否展示遮罩 | | maskClosable | boolean | true | 点击遮罩是否关闭 | | showHeader | boolean | true | 是否展示头部(标题栏,含标题与关闭按钮,也是拖动手柄) | | showClose | boolean | true | 是否展示 X 关闭按钮 | | closeOnEscape | boolean | true | 按 Esc 是否关闭 | | open | boolean | false | 创建后是否立即打开 | | zIndex | number | 1000 | 期望的最低 z-index(实际由 ModalProvider 分配,确保高于已有实例) | | className | string | — | 根节点自定义类名 | | language | 'zh' \| 'en' | 'zh' | 语言 | | locales | I18nTranslation | — | 自定义文案 | | onOpen | () => void | — | 打开回调 | | onClose | () => void | — | 关闭回调 |

实例方法

| 方法 | 说明 | | ---------------------------------- | ---------------------------------------- | | open() | 打开弹框(打开时自动居中并约束在视口内) | | close() | 关闭弹框 | | isVisible() | 是否可见 | | bringToTop() | 将当前弹框置顶(z-index 升至全局最高) | | setTitle(title) | 设置标题 | | setContent(content) | 设置内容 | | setPosition(x, y) | 设置位置坐标(自动约束在视口内) | | updateOptions(options) | 更新配置(结构变更会重建 DOM) | | on(event, cb) / off(event, cb) | 事件监听 / 取消 | | destroy() | 销毁(释放 DOM、事件、Provider 注册) |

事件 Modal.EVENTS

| 事件 | 说明 | 回调参数 | | ----------- | -------- | --------------- | | open | 打开 | — | | close | 关闭 | — | | dragStart | 开始拖动 | — | | dragging | 拖动中 | { x, y } | | dragEnd | 结束拖动 | { left, top } |

ModalProvider

ModalProvider 是 Modal 实例的单例管理器,统一管理所有 Modal 实例的注册、z-index 分配与批量销毁。

获取实例

import { ModalProvider } from '@ezuikit/control-modal';

const provider = ModalProvider.getInstance();

// UMD 场景
const provider = Modal.Provider.getInstance();

API

| 成员 / 方法 | 说明 | | ------------------------------------- | ------------------------------------------ | | getInstance(): ModalProvider | 获取单例 | | register(modal, minZIndex?): number | 注册实例并分配初始 z-index(内部自动调用) | | unregister(modal): void | 注销实例(modal.destroy() 时自动调用) | | bringToTop(): number | 分配一个全局最高 z-index(内部自动调用) | | getInstances(): Modal[] | 获取全部已注册实例 | | destroyAll(): void | 销毁全部实例 | | count (getter) | 当前已注册的实例数量 | | resetInstance(): void | 重置单例(测试用) |

工作流程

  1. new Modal(...) 时 → 自动调用 ModalProvider.getInstance().register(this) 分配最高 z-index
  2. modal.destroy() 时 → 自动调用 ModalProvider.getInstance().unregister(this) 注销
  3. 点击弹框任意位置 → pointerdownbringToTop() → Provider 分配新的最高 z-index
  4. 无需手动管理 z-index,Provider 全自动处理

边界约束

拖动与窗口 resize 时,左上角坐标会被约束在 [0, 视口宽 - 弹框宽] × [0, 视口高 - 弹框高] 范围内,确保窗口始终完整可见、不超出页面区域。