@ezuikit/control-drawer 0.0.1-beta.6 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -44
- package/dist/index.cjs +3 -3
- package/dist/index.esm.js +3 -3
- package/dist/index.umd.js +3 -3
- package/dist/style/style/index.scss +22 -23
- package/dist/style/style.css +1 -1
- package/dist/style/style.js +2 -2
- package/dist/types/index.d.ts +101 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
pnpm add @ezuikit/control-drawer
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
> **仅限浏览器环境。** 构造函数会直接访问 `document` 并创建 DOM,必须在客户端创建(Next.js / Nuxt 等 SSR 框架里放到 `useEffect` / `onMounted` 等仅客户端执行的钩子中,或用动态导入关闭 SSR)。在 Node 服务端 `new Drawer()` 会抛出 `ReferenceError: document is not defined`;仅 `import` 模块不会出错。
|
|
12
|
+
|
|
11
13
|
## 快速开始
|
|
12
14
|
|
|
13
15
|
```ts
|
|
@@ -65,62 +67,132 @@ const drawer = new Drawer(playerEl, {
|
|
|
65
67
|
|
|
66
68
|
## 配置项
|
|
67
69
|
|
|
68
|
-
| 参数 | 类型 | 默认 | 说明
|
|
69
|
-
| --------------- | ---------------------------------------- | --------- |
|
|
70
|
-
| `title` | `string \| HTMLElement` | - | 标题,字符串按 HTML 插入
|
|
71
|
-
| `content` | `string \| HTMLElement` | - | 内容,字符串按 HTML 插入
|
|
72
|
-
| `placement` | `'left' \| 'right' \| 'top' \| 'bottom'` | `'right'` | 弹出方向,非法值回退 `right`
|
|
73
|
-
| `width` | `number \| string` | `300` | 面板宽度(左右方向生效),number 视为 px
|
|
74
|
-
| `height` | `number \| string` | `300` | 面板高度(上下方向生效),number 视为 px
|
|
75
|
-
| `showMask` | `boolean` | `true` | 遮罩;关闭后面板以外区域可操作底层内容
|
|
76
|
-
| `maskClosable` | `boolean` | `true` | 点击遮罩关闭
|
|
77
|
-
| `showHeader` | `boolean` | `true` | 头部(标题 + 关闭按钮)
|
|
78
|
-
| `showClose` | `boolean` | `true` | 关闭按钮,`showHeader` 为 `false` 时无效
|
|
79
|
-
| `closeOnEscape` | `boolean` | `true` | Esc 关闭
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
70
|
+
| 参数 | 类型 | 默认 | 说明 |
|
|
71
|
+
| --------------- | ---------------------------------------- | --------- | ---------------------------------------------------------------------------- |
|
|
72
|
+
| `title` | `string \| HTMLElement` | - | 标题,字符串按 HTML 插入 |
|
|
73
|
+
| `content` | `string \| HTMLElement` | - | 内容,字符串按 HTML 插入 |
|
|
74
|
+
| `placement` | `'left' \| 'right' \| 'top' \| 'bottom'` | `'right'` | 弹出方向,非法值回退 `right` |
|
|
75
|
+
| `width` | `number \| string` | `300` | 面板宽度(左右方向生效),number 视为 px |
|
|
76
|
+
| `height` | `number \| string` | `300` | 面板高度(上下方向生效),number 视为 px |
|
|
77
|
+
| `showMask` | `boolean` | `true` | 遮罩;关闭后面板以外区域可操作底层内容 |
|
|
78
|
+
| `maskClosable` | `boolean` | `true` | 点击遮罩关闭 |
|
|
79
|
+
| `showHeader` | `boolean` | `true` | 头部(标题 + 关闭按钮) |
|
|
80
|
+
| `showClose` | `boolean` | `true` | 关闭按钮,`showHeader` 为 `false` 时无效 |
|
|
81
|
+
| `closeOnEscape` | `boolean` | `true` | Esc 关闭 |
|
|
82
|
+
| `duration` | `number` | `300` | 开合动画时长(ms),非有限数 / 负数回退 300,自动同步到 `--edrawer-duration` |
|
|
83
|
+
| `open` | `boolean` | `false` | 创建后立即打开(仅构造时生效) |
|
|
84
|
+
| `zIndex` | `number` | - | 根节点层级,缺省取 `--edrawer-z-index`(100) |
|
|
85
|
+
| `className` | `string` | - | 追加到根节点的类名,多个用空格分隔 |
|
|
86
|
+
| `getContainer` | `() => HTMLElement \| null \| undefined` | - | 动态挂载点,见上文 |
|
|
87
|
+
| `onOpenChange` | `(open: boolean) => void` | - | 打开/关闭回调,参数为当前状态 |
|
|
88
|
+
| `onOpenStart` | `() => void` | - | 打开开始(动画开始前同步触发) |
|
|
89
|
+
| `onOpenEnd` | `() => void` | - | 打开结束(过渡结束后触发) |
|
|
90
|
+
| `onCloseStart` | `() => void` | - | 关闭开始(动画开始前同步触发) |
|
|
91
|
+
| `onCloseEnd` | `() => void` | - | 关闭结束(过渡结束、根节点隐藏后触发) |
|
|
85
92
|
|
|
86
93
|
## 方法 / 属性
|
|
87
94
|
|
|
88
|
-
| 成员 | 说明
|
|
89
|
-
| ----------------------------------------- |
|
|
90
|
-
| `open` | 布尔属性(getter/setter
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
+
| 成员 | 说明 |
|
|
96
|
+
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
97
|
+
| `open` | 布尔属性(getter/setter),打开/关闭抽屉;重复设置相同状态为幂等,销毁后设置无效;`getContainer` 抛错时异常向上抛出,状态与回调均保持不变 |
|
|
98
|
+
| `options` | 当前生效的配置对象(实例独享,已与默认配置合并) |
|
|
99
|
+
| `setTitle(title)` / `setContent(content)` | 更新标题 / 内容,不重建 DOM |
|
|
100
|
+
| `updateOptions(opts)` | 更新配置并重建 DOM,保持当前开合状态且不重播动画 |
|
|
101
|
+
| `destroy()` | 销毁(幂等),移除 DOM、定时器与监听,不触发任何回调 |
|
|
102
|
+
| `Drawer.VERSION` | 构建时由 Rollup 注入的版本号(静态属性) |
|
|
103
|
+
|
|
104
|
+
没有事件订阅(无 `on` / `off`),状态变化统一通过配置项回调通知,见下节。
|
|
105
|
+
|
|
106
|
+
类型从入口导出:`import Drawer, { type DrawerOptions, type DrawerPlacement, type DrawerContainerGetter } from '@ezuikit/control-drawer'`。
|
|
107
|
+
|
|
108
|
+
### 继承
|
|
109
|
+
|
|
110
|
+
`@ezuikit/control-alarm-message`、`@ezuikit/control-broadcast` 都以子类方式复用 Drawer。子类可重写 `open` 访问器,需 getter / setter 成对重写,并通过 `super.open` 复用基类逻辑:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
class MyDrawer extends Drawer {
|
|
114
|
+
get open() {
|
|
115
|
+
return super.open;
|
|
116
|
+
}
|
|
117
|
+
set open(value: boolean) {
|
|
118
|
+
// 自定义逻辑
|
|
119
|
+
super.open = value;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**构造配置 `open: true` 对子类不会自动生效。** 基类构造函数先于子类字段初始化执行,此时触发 `open` 访问器与回调会读到未初始化的子类状态(例如重写的 `open` 里访问子类字段会抛 `TypeError`)。因此直接 `new Drawer({ open: true })` 仍会自动打开,而子类实例(`new.target !== Drawer`)不会;子类需在自己的构造函数末尾(字段与回调都就绪后)调用受保护方法 `applyInitialOpen()`:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
class MyDrawer extends Drawer {
|
|
128
|
+
private readonly logs: string[] = [];
|
|
129
|
+
|
|
130
|
+
constructor(container: HTMLElement, options: DrawerOptions) {
|
|
131
|
+
super(container, options);
|
|
132
|
+
this.options.onOpenChange = (open) => this.logs.push(`open=${open}`);
|
|
133
|
+
this.applyInitialOpen(); // 按 options.open 决定是否打开;open 缺省或为 false 时什么也不做
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
不需要构造即打开的子类(如 AlarmMessage、Broadcast)无需处理,构造后设置 `open = true` 即可。
|
|
95
139
|
|
|
96
140
|
## 打开 / 关闭回调
|
|
97
141
|
|
|
98
|
-
|
|
142
|
+
抽屉在开合过程中按生命周期派发回调,触发顺序如下:
|
|
143
|
+
|
|
144
|
+
- 打开:`onOpenStart`(同步,动画开始前)→ `onOpenEnd`(过渡结束后)
|
|
145
|
+
- 关闭:`onCloseStart`(同步,动画开始前)→ `onCloseEnd`(过渡结束、根节点隐藏后)
|
|
146
|
+
|
|
147
|
+
另有 `onOpenChange(open)`:打开与关闭时同步调用,参数为当前状态 `boolean`,在 `onOpenStart` / `onCloseStart` 之后触发。完整顺序:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
open = true → onOpenStart → onOpenChange(true) → (duration 后)onOpenEnd
|
|
151
|
+
open = false → onCloseStart → onOpenChange(false) → (duration 后)onCloseEnd
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
- 结束回调依赖与过渡时长(`duration`,默认 300ms)一致的定时器,而非 `transitionend`;`duration: 0` 在下一个定时器周期触发。
|
|
155
|
+
- 反向切换(如打开动画中途关闭)会取消尚未触发的结束回调,`destroy()` 与 `updateOptions()`(重建 DOM)同样会取消。
|
|
156
|
+
- 点击关闭按钮 / 遮罩、按 Esc 与直接设置 `open = false` 走同一条路径,回调一致。
|
|
157
|
+
- 直接 `new Drawer({ open: true })` 同样会触发 `onOpenStart` / `onOpenChange(true)` / `onOpenEnd`(子类见上文“继承”)。
|
|
158
|
+
- `destroy()` 不触发任何回调。
|
|
159
|
+
|
|
160
|
+
**在开始回调里再次改变状态。** `onOpenStart` / `onCloseStart` 内可以再设置 `open`、调用 `updateOptions()` 或 `destroy()`,以回调内的最终状态为准,被覆盖的那次开合不再继续(其 `onOpenChange` 与结束回调不会触发):
|
|
161
|
+
|
|
162
|
+
| 回调内的操作 | 结果 |
|
|
163
|
+
| ------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
164
|
+
| `onOpenStart` 内 `open = false` | 保持关闭,只触发 `onCloseStart` / `onOpenChange(false)`,不触发 `onOpenChange(true)` 与 `onOpenEnd` |
|
|
165
|
+
| `onCloseStart` 内 `open = true` | 保持打开,不触发 `onCloseEnd` |
|
|
166
|
+
| 开始回调内 `destroy()` | 不再渲染,不残留 Esc 监听与定时器,后续回调均不触发 |
|
|
167
|
+
| 开始回调内 `updateOptions()` | 以重建后的节点完成本次开合 |
|
|
99
168
|
|
|
100
169
|
## 样式与类名
|
|
101
170
|
|
|
102
|
-
统一前缀 `edrawer`(常量 `
|
|
171
|
+
统一前缀 `edrawer`(常量 `__DRAWER_PREFIX_CLS__`,SCSS 变量 `$edrawer-prefix-cls`):
|
|
103
172
|
|
|
104
173
|
- 结构:`edrawer`(根)> `edrawer-mask` + `edrawer-panel` > `edrawer-header`(`edrawer-title`、`edrawer-close`)+ `edrawer-body`
|
|
105
174
|
- 状态:`edrawer-left` / `-right` / `-top` / `-bottom`、`edrawer-open`、`edrawer-hidden`、`edrawer-fixed`(挂在 body 上)
|
|
106
175
|
|
|
107
176
|
外观通过 CSS 变量定制,可设在 `className` 对应的根节点上按实例覆盖:
|
|
108
177
|
|
|
109
|
-
| 变量 | 默认 | 说明
|
|
110
|
-
| ------------------------------- | ----------------- |
|
|
111
|
-
| `--edrawer-z-index` | `100` | 根节点层级
|
|
112
|
-
| `--edrawer-
|
|
113
|
-
| `--edrawer-
|
|
114
|
-
| `--edrawer-
|
|
115
|
-
| `--edrawer-
|
|
116
|
-
| `--edrawer-
|
|
117
|
-
| `--edrawer-max-
|
|
118
|
-
| `--edrawer-
|
|
119
|
-
| `--edrawer-header-
|
|
120
|
-
| `--edrawer-
|
|
121
|
-
| `--edrawer-
|
|
122
|
-
| `--edrawer-
|
|
123
|
-
| `--edrawer-
|
|
178
|
+
| 变量 | 默认 | 说明 |
|
|
179
|
+
| ------------------------------- | ----------------- | -------------------- |
|
|
180
|
+
| `--edrawer-z-index` | `100` | 根节点层级 |
|
|
181
|
+
| `--edrawer-duration` | `0.3s` | 开合动画时长 |
|
|
182
|
+
| `--edrawer-bg` | `#fff` | 面板背景 |
|
|
183
|
+
| `--edrawer-color` | `rgba(0,0,0,.88)` | 面板文字色 |
|
|
184
|
+
| `--edrawer-mask-bg` | `rgba(0,0,0,.3)` | 遮罩色 |
|
|
185
|
+
| `--edrawer-border-color` | `rgba(0,0,0,.1)` | 面板内侧边框 |
|
|
186
|
+
| `--edrawer-max-width` | `100%` | 左右方向的最大宽度 |
|
|
187
|
+
| `--edrawer-max-height` | `100%` | 上下方向的最大高度 |
|
|
188
|
+
| `--edrawer-header-height` | `40px` | 头部高度(含分隔线) |
|
|
189
|
+
| `--edrawer-header-padding` | `0 16px` | 头部内边距 |
|
|
190
|
+
| `--edrawer-header-border-color` | `rgba(0,0,0,.08)` | 头部分隔线 |
|
|
191
|
+
| `--edrawer-title-color` | `#333` | 标题色 |
|
|
192
|
+
| `--edrawer-title-font-size` | `14px` | 标题字号 |
|
|
193
|
+
| `--edrawer-close-color` | `rgba(0,0,0,.45)` | 关闭按钮色 |
|
|
194
|
+
| `--edrawer-close-hover-color` | `rgba(0,0,0,.88)` | 关闭按钮悬停色 |
|
|
195
|
+
| `--edrawer-close-hover-bg` | `rgba(0,0,0,.06)` | 关闭按钮悬停背景 |
|
|
124
196
|
|
|
125
197
|
```css
|
|
126
198
|
/* 例:告警消息面板在 PC 端最多占容器 80% 宽 */
|
|
@@ -135,14 +207,18 @@ const drawer = new Drawer(playerEl, {
|
|
|
135
207
|
|
|
136
208
|
**字符串按 HTML 插入。** `title` / `content` / `setTitle` / `setContent` 传字符串时写入 `innerHTML`,只能传可信内容;不可信数据请自行转义或传 `HTMLElement`。
|
|
137
209
|
|
|
138
|
-
|
|
210
|
+
**动画时长可配。** 通过 `duration`(ms)配置开合时长,默认 300;组件会把该值写入根节点的 `--edrawer-duration`,使遮罩/面板的 CSS 过渡与 JS 定时器保持一致。只在宿主 CSS 里改 `transition` 时长不会改变 JS 的隐藏时机。面板为 CSS `transition: transform` 滑入滑出,遮罩为 `transition: opacity` 淡入淡出,不使用 `@keyframes`。组件内置样式不响应 `prefers-reduced-motion`(Windows 关闭"显示动画"、远程桌面 / 虚拟机、省电模式下浏览器都会命中该偏好,会导致抽屉瞬间出现);需要尊重该偏好的宿主可自行追加 `@media (prefers-reduced-motion: reduce) { .edrawer-mask, .edrawer-panel { transition: none; } }`。
|
|
139
211
|
|
|
140
212
|
**`updateOptions` 会重建 DOM。** 以 `HTMLElement` 传入的内容会被移动到新节点,引用与其上的监听保留,但内部滚动位置会重置;只改文案时用 `setTitle` / `setContent`。
|
|
141
213
|
|
|
142
214
|
**显式传 `undefined` 会覆盖默认值。** 配置按 `Object.assign({}, 默认配置, options)` 浅合并,DOM 节点与函数按引用保留;`{ width: undefined }` 会让面板失去默认宽度,不需要的字段请不要传。
|
|
143
215
|
|
|
144
|
-
**Esc
|
|
216
|
+
**Esc 监听挂在容器所属的 `document` 上**,仅在打开期间存在(兼容旧浏览器的 `Esc` 键值)。容器位于 iframe 等其它文档内时,监听注册在该 iframe 的 `document` 上(在 iframe 内按 Esc 才会关闭,顶层页面按 Esc 不会);`getContainer` 把抽屉移到另一个文档时监听随之迁移。以下按键不会关闭抽屉:输入法组合输入中的 Esc(`isComposing` / `keyCode === 229`,用于取消候选词),以及已被内部控件调用 `preventDefault()` 处理过的 Esc(如抽屉内的下拉框)。同一文档中多个抽屉同时打开时,一次 Esc 会全部关闭。
|
|
217
|
+
|
|
218
|
+
**挂载到 `body` 判定为 `fixed`** 时,同样以挂载点自身所属文档的 `body` 为准,iframe 内挂到其 `body` 时也相对该 iframe 视口定位。
|
|
219
|
+
|
|
220
|
+
**`getContainer` 的调用时机。** 仅在 `open = true` 时调用(构造与 `updateOptions` 都不调用);已打开状态下 `updateOptions` 沿用当前挂载点。返回空值回退到构造函数传入的 `container`;返回的元素与当前父节点相同时不移动 DOM。
|
|
145
221
|
|
|
146
222
|
**事件冒泡。** 根节点拦截 `dblclick` 冒泡,避免在播放器容器内双击触发全屏切换;`click` 不拦截,点击遮罩关闭后事件仍会冒泡到宿主。关闭按钮的点击会阻止冒泡。
|
|
147
223
|
|
|
148
|
-
**无障碍。** 面板带 `role="dialog"`,有头部时通过 `aria-labelledby` 关联标题;关闭按钮为 `<button type="button"
|
|
224
|
+
**无障碍。** 面板带 `role="dialog"`,有头部时通过 `aria-labelledby` 关联标题;关闭按钮为 `<button type="button">`,带 `aria-label="close"`,内联 SVG 图标 `aria-hidden="true"`。未做焦点管理与焦点陷阱。
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* @ezuikit/control-drawer v0.0.1
|
|
3
|
-
* Copyright (c) 2026-
|
|
2
|
+
* @ezuikit/control-drawer v0.0.1
|
|
3
|
+
* Copyright (c) 2026-11-09 13:32:10 Ezviz-OpenBiz
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
"use strict";var
|
|
6
|
+
"use strict";var __DRAWER_PLACEMENTS__=["left","right","top","bottom"],__$DRAWER_DEFAULT_OPTIONS$__={placement:"right",width:300,height:300,showMask:!0,maskClosable:!0,showHeader:!0,showClose:!0,closeOnEscape:!0,open:!1};function _create_class(Constructor,protoProps,staticProps){return protoProps&&function(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||!1,descriptor.configurable=!0,"value"in descriptor&&(descriptor.writable=!0),Object.defineProperty(target,descriptor.key,descriptor)}}(Constructor.prototype,protoProps),Constructor}var _uid=0,Drawer=function(){function Drawer(container,options){var left,right,_this=this;this._$root=null,this._$mask=null,this._$title=null,this._$close=null,this._$body=null,this._open=!1,this._destroyed=!1,this._hideTimer=null,this._openTimer=null,this._keydownDoc=null,this._onCloseClick=function(e){e.stopPropagation(),_this.open=!1},this._onMaskClick=function(){_this.options.maskClosable&&(_this.open=!1)},this._onRootDblClick=function(e){e.stopPropagation()},this._onKeydown=function(e){e.isComposing||229===e.keyCode||e.defaultPrevented||"Escape"!==e.key&&"Esc"!==e.key||(_this.open=!1)},this.options=Object.assign({},__$DRAWER_DEFAULT_OPTIONS$__,null!=options?options:{}),this._container=this._resolveContainer(container),this._titleId="edrawer-title-"+ ++_uid,this._render(),this.options.getContainer||this._attach(this._container),left=this,((null!=(right=Drawer)&&"undefined"!=typeof Symbol&&right[Symbol.hasInstance]?right[Symbol.hasInstance](left):left instanceof right)?this.constructor:void 0)===Drawer&&this.applyInitialOpen()}var _proto=Drawer.prototype;return _proto.applyInitialOpen=function(){this.options.open&&(this.open=!0)},_proto.setTitle=function(title){this._destroyed||(this.options.title=title,this._$title&&this._mount(this._$title,title))},_proto.setContent=function(content){this._destroyed||(this.options.content=content,this._$body&&this._mount(this._$body,content))},_proto.updateOptions=function(options){var _ref,_this__$root;if(!this._destroyed){this.options=Object.assign(this.options,options);var parent=null!=(_ref=null==(_this__$root=this._$root)?void 0:_this__$root.parentElement)?_ref:null;this._clearTimers(),this._teardownDom(),this._render(),parent&&this._attach(parent),this._unbindEscape(),this._open&&this.options.closeOnEscape&&this._bindEscape()}},_proto.destroy=function(){this._destroyed||(this._destroyed=!0,this._open=!1,this._clearTimers(),this._unbindEscape(),this._teardownDom())},_proto._resolveContainer=function(container){return"string"==typeof container?document.getElementById(container)||this._query(container)||document.body:container||document.body},_proto._query=function(selector){try{return document.querySelector(selector)}catch(unused){return null}},_proto._resolveMountTarget=function(){return(null==this.options.getContainer?void 0:this.options.getContainer.call(this.options))||this._container},_proto._attach=function(target){var root=this._$root;if(root){root.parentNode!==target&&target.appendChild(root);target===target.ownerDocument.body?root.classList.add("edrawer-fixed"):root.classList.remove("edrawer-fixed")}},_proto._getPlacement=function(){var placement=this.options.placement;return placement&&__DRAWER_PLACEMENTS__.includes(placement)?placement:"right"},_proto._getDuration=function(){var duration=this.options.duration;return"number"==typeof duration&&Number.isFinite(duration)&&duration>=0?duration:300},_proto._toSize=function(value){return null==value||""===value?null:"number"==typeof value?value+"px":value},_proto._render=function(){var placement=this._getPlacement(),_this_options=this.options,showMask=_this_options.showMask,showHeader=_this_options.showHeader,showClose=_this_options.showClose,className=_this_options.className,zIndex=_this_options.zIndex,title=_this_options.title,content=_this_options.content,root=document.createElement("div");if(root.className="edrawer edrawer-"+placement+" "+"edrawer-"+(this._open?"open":"hidden"),className&&className.split(/\s+/).forEach(function(cls){cls&&root.classList.add(cls)}),"number"==typeof zIndex&&(root.style.zIndex=""+zIndex),root.style.setProperty("--edrawer-duration",this._getDuration()+"ms"),root.addEventListener("dblclick",this._onRootDblClick),showMask){var mask=document.createElement("div");mask.className="edrawer-mask",mask.addEventListener("click",this._onMaskClick),root.appendChild(mask),this._$mask=mask}var panel=document.createElement("div");panel.className="edrawer-panel",panel.setAttribute("role","dialog");var horizontal="left"===placement||"right"===placement,size=this._toSize(horizontal?this.options.width:this.options.height);if(size&&(horizontal?panel.style.width=size:panel.style.height=size),showHeader){var header=document.createElement("div");header.className="edrawer-header";var titleEl=document.createElement("div");if(titleEl.className="edrawer-title",titleEl.id=this._titleId,void 0!==title&&this._mount(titleEl,title),header.appendChild(titleEl),panel.setAttribute("aria-labelledby",this._titleId),this._$title=titleEl,showClose){var close=document.createElement("button");close.type="button",close.className="edrawer-close",close.setAttribute("aria-label","close"),close.innerHTML='<svg viewBox="0 0 24 24" fill="none" width="1em" height="1em" stroke="currentColor" focusable="false" aria-hidden="true">\n <path d="M0 0L15.9998 0" stroke-linecap="round" stroke-width="1.5" transform="matrix(0.707099,0.707114,-0.707114,0.707099,6.34277,6.34326)" />\n <path d="M0 0L15.9998 0" stroke-linecap="round" stroke-width="1.5" transform="matrix(0.707099,-0.707114,0.707114,0.707099,6.34277,17.6567)" />\n</svg>',close.addEventListener("click",this._onCloseClick),header.appendChild(close),this._$close=close}panel.appendChild(header)}var body=document.createElement("div");body.className="edrawer-body",void 0!==content&&this._mount(body,content),panel.appendChild(body),root.appendChild(panel),this._$root=root,this._$body=body},_proto._mount=function(target,content){"string"!=typeof content?(target.innerHTML="",content&&target.appendChild(content)):target.innerHTML=content},_proto._teardownDom=function(){var _this__$close,_this__$mask,_this__$root_parentNode;(null==(_this__$close=this._$close)||_this__$close.removeEventListener("click",this._onCloseClick),null==(_this__$mask=this._$mask)||_this__$mask.removeEventListener("click",this._onMaskClick),this._$root)&&(this._$root.removeEventListener("dblclick",this._onRootDblClick),null==(_this__$root_parentNode=this._$root.parentNode)||_this__$root_parentNode.removeChild(this._$root));this._$root=null,this._$mask=null,this._$title=null,this._$close=null,this._$body=null},_proto._clearTimers=function(){null!==this._hideTimer&&(clearTimeout(this._hideTimer),this._hideTimer=null),null!==this._openTimer&&(clearTimeout(this._openTimer),this._openTimer=null)},_proto._bindEscape=function(){var _ref,_this__$root;this._unbindEscape();var doc=null!=(_ref=null==(_this__$root=this._$root)?void 0:_this__$root.ownerDocument)?_ref:document;doc.addEventListener("keydown",this._onKeydown),this._keydownDoc=doc},_proto._unbindEscape=function(){var _this__keydownDoc;null==(_this__keydownDoc=this._keydownDoc)||_this__keydownDoc.removeEventListener("keydown",this._onKeydown),this._keydownDoc=null},_proto._reflow=function(el){return el.offsetHeight},_create_class(Drawer,[{key:"open",get:function(){return this._open},set:function(open){var _this=this;if(!this._destroyed&&this._open!==open&&this._$root){var target=open?this._resolveMountTarget():null;this._open=open,this._clearTimers();var duration=this._getDuration();open?null==this.options.onOpenStart||this.options.onOpenStart.call(this.options):null==this.options.onCloseStart||this.options.onCloseStart.call(this.options);var root=this._$root;!this._destroyed&&this._open===open&&root&&(open?(this._attach(target),root.classList.remove("edrawer-hidden"),this._reflow(root),root.classList.add("edrawer-open"),this.options.closeOnEscape&&this._bindEscape(),this._openTimer=setTimeout(function(){_this._openTimer=null,null==_this.options.onOpenEnd||_this.options.onOpenEnd.call(_this.options)},duration)):(root.classList.remove("edrawer-open"),this._hideTimer=setTimeout(function(){var _this__$root;_this._hideTimer=null,null==(_this__$root=_this._$root)||_this__$root.classList.add("edrawer-hidden"),null==_this.options.onCloseEnd||_this.options.onCloseEnd.call(_this.options)},duration),this._unbindEscape()),null==this.options.onOpenChange||this.options.onOpenChange.call(this.options,open))}}}]),Drawer}();Drawer.VERSION="0.0.1",module.exports=Drawer;
|
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* @ezuikit/control-drawer v0.0.1
|
|
3
|
-
* Copyright (c) 2026-
|
|
2
|
+
* @ezuikit/control-drawer v0.0.1
|
|
3
|
+
* Copyright (c) 2026-11-09 13:32:10 Ezviz-OpenBiz
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
var
|
|
6
|
+
var __DRAWER_PLACEMENTS__=["left","right","top","bottom"],__$DRAWER_DEFAULT_OPTIONS$__={placement:"right",width:300,height:300,showMask:!0,maskClosable:!0,showHeader:!0,showClose:!0,closeOnEscape:!0,open:!1};function _create_class(Constructor,protoProps,staticProps){return protoProps&&function(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||!1,descriptor.configurable=!0,"value"in descriptor&&(descriptor.writable=!0),Object.defineProperty(target,descriptor.key,descriptor)}}(Constructor.prototype,protoProps),Constructor}var _uid=0,Drawer=function(){function Drawer(container,options){var left,right,_this=this;this._$root=null,this._$mask=null,this._$title=null,this._$close=null,this._$body=null,this._open=!1,this._destroyed=!1,this._hideTimer=null,this._openTimer=null,this._keydownDoc=null,this._onCloseClick=function(e){e.stopPropagation(),_this.open=!1},this._onMaskClick=function(){_this.options.maskClosable&&(_this.open=!1)},this._onRootDblClick=function(e){e.stopPropagation()},this._onKeydown=function(e){e.isComposing||229===e.keyCode||e.defaultPrevented||"Escape"!==e.key&&"Esc"!==e.key||(_this.open=!1)},this.options=Object.assign({},__$DRAWER_DEFAULT_OPTIONS$__,null!=options?options:{}),this._container=this._resolveContainer(container),this._titleId="edrawer-title-"+ ++_uid,this._render(),this.options.getContainer||this._attach(this._container),left=this,((null!=(right=Drawer)&&"undefined"!=typeof Symbol&&right[Symbol.hasInstance]?right[Symbol.hasInstance](left):left instanceof right)?this.constructor:void 0)===Drawer&&this.applyInitialOpen()}var _proto=Drawer.prototype;return _proto.applyInitialOpen=function(){this.options.open&&(this.open=!0)},_proto.setTitle=function(title){this._destroyed||(this.options.title=title,this._$title&&this._mount(this._$title,title))},_proto.setContent=function(content){this._destroyed||(this.options.content=content,this._$body&&this._mount(this._$body,content))},_proto.updateOptions=function(options){var _ref,_this__$root;if(!this._destroyed){this.options=Object.assign(this.options,options);var parent=null!=(_ref=null==(_this__$root=this._$root)?void 0:_this__$root.parentElement)?_ref:null;this._clearTimers(),this._teardownDom(),this._render(),parent&&this._attach(parent),this._unbindEscape(),this._open&&this.options.closeOnEscape&&this._bindEscape()}},_proto.destroy=function(){this._destroyed||(this._destroyed=!0,this._open=!1,this._clearTimers(),this._unbindEscape(),this._teardownDom())},_proto._resolveContainer=function(container){return"string"==typeof container?document.getElementById(container)||this._query(container)||document.body:container||document.body},_proto._query=function(selector){try{return document.querySelector(selector)}catch(unused){return null}},_proto._resolveMountTarget=function(){return(null==this.options.getContainer?void 0:this.options.getContainer.call(this.options))||this._container},_proto._attach=function(target){var root=this._$root;if(root){root.parentNode!==target&&target.appendChild(root);target===target.ownerDocument.body?root.classList.add("edrawer-fixed"):root.classList.remove("edrawer-fixed")}},_proto._getPlacement=function(){var placement=this.options.placement;return placement&&__DRAWER_PLACEMENTS__.includes(placement)?placement:"right"},_proto._getDuration=function(){var duration=this.options.duration;return"number"==typeof duration&&Number.isFinite(duration)&&duration>=0?duration:300},_proto._toSize=function(value){return null==value||""===value?null:"number"==typeof value?value+"px":value},_proto._render=function(){var placement=this._getPlacement(),_this_options=this.options,showMask=_this_options.showMask,showHeader=_this_options.showHeader,showClose=_this_options.showClose,className=_this_options.className,zIndex=_this_options.zIndex,title=_this_options.title,content=_this_options.content,root=document.createElement("div");if(root.className="edrawer edrawer-"+placement+" "+"edrawer-"+(this._open?"open":"hidden"),className&&className.split(/\s+/).forEach(function(cls){cls&&root.classList.add(cls)}),"number"==typeof zIndex&&(root.style.zIndex=""+zIndex),root.style.setProperty("--edrawer-duration",this._getDuration()+"ms"),root.addEventListener("dblclick",this._onRootDblClick),showMask){var mask=document.createElement("div");mask.className="edrawer-mask",mask.addEventListener("click",this._onMaskClick),root.appendChild(mask),this._$mask=mask}var panel=document.createElement("div");panel.className="edrawer-panel",panel.setAttribute("role","dialog");var horizontal="left"===placement||"right"===placement,size=this._toSize(horizontal?this.options.width:this.options.height);if(size&&(horizontal?panel.style.width=size:panel.style.height=size),showHeader){var header=document.createElement("div");header.className="edrawer-header";var titleEl=document.createElement("div");if(titleEl.className="edrawer-title",titleEl.id=this._titleId,void 0!==title&&this._mount(titleEl,title),header.appendChild(titleEl),panel.setAttribute("aria-labelledby",this._titleId),this._$title=titleEl,showClose){var close=document.createElement("button");close.type="button",close.className="edrawer-close",close.setAttribute("aria-label","close"),close.innerHTML='<svg viewBox="0 0 24 24" fill="none" width="1em" height="1em" stroke="currentColor" focusable="false" aria-hidden="true">\n <path d="M0 0L15.9998 0" stroke-linecap="round" stroke-width="1.5" transform="matrix(0.707099,0.707114,-0.707114,0.707099,6.34277,6.34326)" />\n <path d="M0 0L15.9998 0" stroke-linecap="round" stroke-width="1.5" transform="matrix(0.707099,-0.707114,0.707114,0.707099,6.34277,17.6567)" />\n</svg>',close.addEventListener("click",this._onCloseClick),header.appendChild(close),this._$close=close}panel.appendChild(header)}var body=document.createElement("div");body.className="edrawer-body",void 0!==content&&this._mount(body,content),panel.appendChild(body),root.appendChild(panel),this._$root=root,this._$body=body},_proto._mount=function(target,content){"string"!=typeof content?(target.innerHTML="",content&&target.appendChild(content)):target.innerHTML=content},_proto._teardownDom=function(){var _this__$close,_this__$mask,_this__$root_parentNode;(null==(_this__$close=this._$close)||_this__$close.removeEventListener("click",this._onCloseClick),null==(_this__$mask=this._$mask)||_this__$mask.removeEventListener("click",this._onMaskClick),this._$root)&&(this._$root.removeEventListener("dblclick",this._onRootDblClick),null==(_this__$root_parentNode=this._$root.parentNode)||_this__$root_parentNode.removeChild(this._$root));this._$root=null,this._$mask=null,this._$title=null,this._$close=null,this._$body=null},_proto._clearTimers=function(){null!==this._hideTimer&&(clearTimeout(this._hideTimer),this._hideTimer=null),null!==this._openTimer&&(clearTimeout(this._openTimer),this._openTimer=null)},_proto._bindEscape=function(){var _ref,_this__$root;this._unbindEscape();var doc=null!=(_ref=null==(_this__$root=this._$root)?void 0:_this__$root.ownerDocument)?_ref:document;doc.addEventListener("keydown",this._onKeydown),this._keydownDoc=doc},_proto._unbindEscape=function(){var _this__keydownDoc;null==(_this__keydownDoc=this._keydownDoc)||_this__keydownDoc.removeEventListener("keydown",this._onKeydown),this._keydownDoc=null},_proto._reflow=function(el){return el.offsetHeight},_create_class(Drawer,[{key:"open",get:function(){return this._open},set:function(open){var _this=this;if(!this._destroyed&&this._open!==open&&this._$root){var target=open?this._resolveMountTarget():null;this._open=open,this._clearTimers();var duration=this._getDuration();open?null==this.options.onOpenStart||this.options.onOpenStart.call(this.options):null==this.options.onCloseStart||this.options.onCloseStart.call(this.options);var root=this._$root;!this._destroyed&&this._open===open&&root&&(open?(this._attach(target),root.classList.remove("edrawer-hidden"),this._reflow(root),root.classList.add("edrawer-open"),this.options.closeOnEscape&&this._bindEscape(),this._openTimer=setTimeout(function(){_this._openTimer=null,null==_this.options.onOpenEnd||_this.options.onOpenEnd.call(_this.options)},duration)):(root.classList.remove("edrawer-open"),this._hideTimer=setTimeout(function(){var _this__$root;_this._hideTimer=null,null==(_this__$root=_this._$root)||_this__$root.classList.add("edrawer-hidden"),null==_this.options.onCloseEnd||_this.options.onCloseEnd.call(_this.options)},duration),this._unbindEscape()),null==this.options.onOpenChange||this.options.onOpenChange.call(this.options,open))}}}]),Drawer}();Drawer.VERSION="0.0.1";export{Drawer as default};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* @ezuikit/control-drawer v0.0.1
|
|
3
|
-
* Copyright (c) 2026-
|
|
2
|
+
* @ezuikit/control-drawer v0.0.1
|
|
3
|
+
* Copyright (c) 2026-11-09 13:32:10 Ezviz-OpenBiz
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
!function(global,factory){"object"==typeof exports&&"undefined"!=typeof module?module.exports=factory():"function"==typeof define&&define.amd?define(factory):(global="undefined"!=typeof globalThis?globalThis:global||self).Drawer=factory()}(this,function(){"use strict";var
|
|
6
|
+
!function(global,factory){"object"==typeof exports&&"undefined"!=typeof module?module.exports=factory():"function"==typeof define&&define.amd?define(factory):(global="undefined"!=typeof globalThis?globalThis:global||self).Drawer=factory()}(this,function(){"use strict";var __DRAWER_PLACEMENTS__=["left","right","top","bottom"],__$DRAWER_DEFAULT_OPTIONS$__={placement:"right",width:300,height:300,showMask:!0,maskClosable:!0,showHeader:!0,showClose:!0,closeOnEscape:!0,open:!1};function _create_class(Constructor,protoProps,staticProps){return protoProps&&function(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||!1,descriptor.configurable=!0,"value"in descriptor&&(descriptor.writable=!0),Object.defineProperty(target,descriptor.key,descriptor)}}(Constructor.prototype,protoProps),Constructor}var _uid=0,Drawer=function(){function Drawer(container,options){var left,right,_this=this;this._$root=null,this._$mask=null,this._$title=null,this._$close=null,this._$body=null,this._open=!1,this._destroyed=!1,this._hideTimer=null,this._openTimer=null,this._keydownDoc=null,this._onCloseClick=function(e){e.stopPropagation(),_this.open=!1},this._onMaskClick=function(){_this.options.maskClosable&&(_this.open=!1)},this._onRootDblClick=function(e){e.stopPropagation()},this._onKeydown=function(e){e.isComposing||229===e.keyCode||e.defaultPrevented||"Escape"!==e.key&&"Esc"!==e.key||(_this.open=!1)},this.options=Object.assign({},__$DRAWER_DEFAULT_OPTIONS$__,null!=options?options:{}),this._container=this._resolveContainer(container),this._titleId="edrawer-title-"+ ++_uid,this._render(),this.options.getContainer||this._attach(this._container),left=this,((null!=(right=Drawer)&&"undefined"!=typeof Symbol&&right[Symbol.hasInstance]?right[Symbol.hasInstance](left):left instanceof right)?this.constructor:void 0)===Drawer&&this.applyInitialOpen()}var _proto=Drawer.prototype;return _proto.applyInitialOpen=function(){this.options.open&&(this.open=!0)},_proto.setTitle=function(title){this._destroyed||(this.options.title=title,this._$title&&this._mount(this._$title,title))},_proto.setContent=function(content){this._destroyed||(this.options.content=content,this._$body&&this._mount(this._$body,content))},_proto.updateOptions=function(options){var _ref,_this__$root;if(!this._destroyed){this.options=Object.assign(this.options,options);var parent=null!=(_ref=null==(_this__$root=this._$root)?void 0:_this__$root.parentElement)?_ref:null;this._clearTimers(),this._teardownDom(),this._render(),parent&&this._attach(parent),this._unbindEscape(),this._open&&this.options.closeOnEscape&&this._bindEscape()}},_proto.destroy=function(){this._destroyed||(this._destroyed=!0,this._open=!1,this._clearTimers(),this._unbindEscape(),this._teardownDom())},_proto._resolveContainer=function(container){return"string"==typeof container?document.getElementById(container)||this._query(container)||document.body:container||document.body},_proto._query=function(selector){try{return document.querySelector(selector)}catch(unused){return null}},_proto._resolveMountTarget=function(){return(null==this.options.getContainer?void 0:this.options.getContainer.call(this.options))||this._container},_proto._attach=function(target){var root=this._$root;if(root){root.parentNode!==target&&target.appendChild(root);target===target.ownerDocument.body?root.classList.add("edrawer-fixed"):root.classList.remove("edrawer-fixed")}},_proto._getPlacement=function(){var placement=this.options.placement;return placement&&__DRAWER_PLACEMENTS__.includes(placement)?placement:"right"},_proto._getDuration=function(){var duration=this.options.duration;return"number"==typeof duration&&Number.isFinite(duration)&&duration>=0?duration:300},_proto._toSize=function(value){return null==value||""===value?null:"number"==typeof value?value+"px":value},_proto._render=function(){var placement=this._getPlacement(),_this_options=this.options,showMask=_this_options.showMask,showHeader=_this_options.showHeader,showClose=_this_options.showClose,className=_this_options.className,zIndex=_this_options.zIndex,title=_this_options.title,content=_this_options.content,root=document.createElement("div");if(root.className="edrawer edrawer-"+placement+" "+"edrawer-"+(this._open?"open":"hidden"),className&&className.split(/\s+/).forEach(function(cls){cls&&root.classList.add(cls)}),"number"==typeof zIndex&&(root.style.zIndex=""+zIndex),root.style.setProperty("--edrawer-duration",this._getDuration()+"ms"),root.addEventListener("dblclick",this._onRootDblClick),showMask){var mask=document.createElement("div");mask.className="edrawer-mask",mask.addEventListener("click",this._onMaskClick),root.appendChild(mask),this._$mask=mask}var panel=document.createElement("div");panel.className="edrawer-panel",panel.setAttribute("role","dialog");var horizontal="left"===placement||"right"===placement,size=this._toSize(horizontal?this.options.width:this.options.height);if(size&&(horizontal?panel.style.width=size:panel.style.height=size),showHeader){var header=document.createElement("div");header.className="edrawer-header";var titleEl=document.createElement("div");if(titleEl.className="edrawer-title",titleEl.id=this._titleId,void 0!==title&&this._mount(titleEl,title),header.appendChild(titleEl),panel.setAttribute("aria-labelledby",this._titleId),this._$title=titleEl,showClose){var close=document.createElement("button");close.type="button",close.className="edrawer-close",close.setAttribute("aria-label","close"),close.innerHTML='<svg viewBox="0 0 24 24" fill="none" width="1em" height="1em" stroke="currentColor" focusable="false" aria-hidden="true">\n <path d="M0 0L15.9998 0" stroke-linecap="round" stroke-width="1.5" transform="matrix(0.707099,0.707114,-0.707114,0.707099,6.34277,6.34326)" />\n <path d="M0 0L15.9998 0" stroke-linecap="round" stroke-width="1.5" transform="matrix(0.707099,-0.707114,0.707114,0.707099,6.34277,17.6567)" />\n</svg>',close.addEventListener("click",this._onCloseClick),header.appendChild(close),this._$close=close}panel.appendChild(header)}var body=document.createElement("div");body.className="edrawer-body",void 0!==content&&this._mount(body,content),panel.appendChild(body),root.appendChild(panel),this._$root=root,this._$body=body},_proto._mount=function(target,content){"string"!=typeof content?(target.innerHTML="",content&&target.appendChild(content)):target.innerHTML=content},_proto._teardownDom=function(){var _this__$close,_this__$mask,_this__$root_parentNode;(null==(_this__$close=this._$close)||_this__$close.removeEventListener("click",this._onCloseClick),null==(_this__$mask=this._$mask)||_this__$mask.removeEventListener("click",this._onMaskClick),this._$root)&&(this._$root.removeEventListener("dblclick",this._onRootDblClick),null==(_this__$root_parentNode=this._$root.parentNode)||_this__$root_parentNode.removeChild(this._$root));this._$root=null,this._$mask=null,this._$title=null,this._$close=null,this._$body=null},_proto._clearTimers=function(){null!==this._hideTimer&&(clearTimeout(this._hideTimer),this._hideTimer=null),null!==this._openTimer&&(clearTimeout(this._openTimer),this._openTimer=null)},_proto._bindEscape=function(){var _ref,_this__$root;this._unbindEscape();var doc=null!=(_ref=null==(_this__$root=this._$root)?void 0:_this__$root.ownerDocument)?_ref:document;doc.addEventListener("keydown",this._onKeydown),this._keydownDoc=doc},_proto._unbindEscape=function(){var _this__keydownDoc;null==(_this__keydownDoc=this._keydownDoc)||_this__keydownDoc.removeEventListener("keydown",this._onKeydown),this._keydownDoc=null},_proto._reflow=function(el){return el.offsetHeight},_create_class(Drawer,[{key:"open",get:function(){return this._open},set:function(open){var _this=this;if(!this._destroyed&&this._open!==open&&this._$root){var target=open?this._resolveMountTarget():null;this._open=open,this._clearTimers();var duration=this._getDuration();open?null==this.options.onOpenStart||this.options.onOpenStart.call(this.options):null==this.options.onCloseStart||this.options.onCloseStart.call(this.options);var root=this._$root;!this._destroyed&&this._open===open&&root&&(open?(this._attach(target),root.classList.remove("edrawer-hidden"),this._reflow(root),root.classList.add("edrawer-open"),this.options.closeOnEscape&&this._bindEscape(),this._openTimer=setTimeout(function(){_this._openTimer=null,null==_this.options.onOpenEnd||_this.options.onOpenEnd.call(_this.options)},duration)):(root.classList.remove("edrawer-open"),this._hideTimer=setTimeout(function(){var _this__$root;_this._hideTimer=null,null==(_this__$root=_this._$root)||_this__$root.classList.add("edrawer-hidden"),null==_this.options.onCloseEnd||_this.options.onCloseEnd.call(_this.options)},duration),this._unbindEscape()),null==this.options.onOpenChange||this.options.onOpenChange.call(this.options,open))}}}]),Drawer}();return Drawer.VERSION="0.0.1",Drawer});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// 外观通过 --edrawer-* 变量定制,缺省值见各 var() 的回退值。
|
|
6
6
|
// -----------------------------------------------------------------------------
|
|
7
7
|
$edrawer-prefix-cls: 'edrawer';
|
|
8
|
-
// 开合过渡时长(默认回退值):可通过根节点上的 --edrawer-duration 按实例覆盖,需与 JS 默认
|
|
8
|
+
// 开合过渡时长(默认回退值):可通过根节点上的 --edrawer-duration 按实例覆盖,需与 JS 默认 __DRAWER_DURATION__(300ms)保持一致
|
|
9
9
|
$edrawer-duration: 0.3s;
|
|
10
10
|
|
|
11
11
|
.#{$edrawer-prefix-cls} {
|
|
@@ -19,6 +19,7 @@ $edrawer-duration: 0.3s;
|
|
|
19
19
|
box-sizing: border-box;
|
|
20
20
|
// 根节点不拦截指针事件:不展示遮罩时,面板以外的区域仍可操作底层内容
|
|
21
21
|
pointer-events: none;
|
|
22
|
+
text-align: left;
|
|
22
23
|
|
|
23
24
|
// 挂载到 document.body 时相对视口定位
|
|
24
25
|
&-fixed {
|
|
@@ -47,6 +48,7 @@ $edrawer-duration: 0.3s;
|
|
|
47
48
|
background-color: var(--edrawer-bg, #fff);
|
|
48
49
|
color: var(--edrawer-color, rgba(0, 0, 0, 0.88));
|
|
49
50
|
transition: transform var(--edrawer-duration, #{$edrawer-duration}) ease;
|
|
51
|
+
text-align: left;
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
// 弹出方向:收起态面板位于容器外侧
|
|
@@ -99,14 +101,15 @@ $edrawer-duration: 0.3s;
|
|
|
99
101
|
pointer-events: auto;
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
//
|
|
104
|
+
// 头部:固定高度(含底部 1px 分隔线),内容垂直居中,避免被头部内的子元素(如日期栏)撑高
|
|
103
105
|
&-header {
|
|
104
106
|
display: flex;
|
|
105
107
|
flex: 0 0 auto;
|
|
106
108
|
align-items: center;
|
|
107
109
|
justify-content: space-between;
|
|
108
110
|
box-sizing: border-box;
|
|
109
|
-
|
|
111
|
+
height: var(--edrawer-header-height, 40px);
|
|
112
|
+
padding: var(--edrawer-header-padding, 0 16px);
|
|
110
113
|
border-bottom: 1px solid var(--edrawer-header-border-color, rgba(0, 0, 0, 0.08));
|
|
111
114
|
}
|
|
112
115
|
|
|
@@ -115,7 +118,7 @@ $edrawer-duration: 0.3s;
|
|
|
115
118
|
min-width: 0;
|
|
116
119
|
overflow: hidden;
|
|
117
120
|
color: var(--edrawer-title-color, #333);
|
|
118
|
-
font-size: var(--edrawer-title-font-size,
|
|
121
|
+
font-size: var(--edrawer-title-font-size, 14px);
|
|
119
122
|
font-weight: 500;
|
|
120
123
|
line-height: 1.5;
|
|
121
124
|
white-space: nowrap;
|
|
@@ -124,29 +127,33 @@ $edrawer-duration: 0.3s;
|
|
|
124
127
|
|
|
125
128
|
// 关闭按钮
|
|
126
129
|
&-close {
|
|
127
|
-
display: inline-flex;
|
|
128
130
|
flex: 0 0 auto;
|
|
131
|
+
display: inline-flex;
|
|
129
132
|
align-items: center;
|
|
130
133
|
justify-content: center;
|
|
134
|
+
width: 28px;
|
|
135
|
+
height: 28px;
|
|
131
136
|
margin-left: 12px;
|
|
132
|
-
padding:
|
|
137
|
+
padding: 0;
|
|
133
138
|
border: none;
|
|
134
|
-
border-radius: 4px;
|
|
135
139
|
background: transparent;
|
|
136
|
-
|
|
140
|
+
border-radius: 4px;
|
|
141
|
+
color: var(--edrawer-close-color, rgba(0, 0, 0, 0.45));
|
|
137
142
|
cursor: pointer;
|
|
138
|
-
|
|
139
|
-
|
|
143
|
+
box-sizing: border-box;
|
|
144
|
+
transition:
|
|
145
|
+
color 0.2s,
|
|
146
|
+
background-color 0.2s;
|
|
140
147
|
|
|
141
148
|
&:hover {
|
|
142
|
-
color: var(--edrawer-close-hover-color,
|
|
143
|
-
background:
|
|
149
|
+
color: var(--edrawer-close-hover-color, rgba(0, 0, 0, 0.88));
|
|
150
|
+
background-color: var(--edrawer-close-hover-bg, rgba(0, 0, 0, 0.06));
|
|
144
151
|
}
|
|
145
152
|
|
|
146
|
-
svg {
|
|
153
|
+
& svg {
|
|
154
|
+
width: 16px;
|
|
155
|
+
height: 16px;
|
|
147
156
|
display: block;
|
|
148
|
-
width: 14px;
|
|
149
|
-
height: 14px;
|
|
150
157
|
}
|
|
151
158
|
}
|
|
152
159
|
|
|
@@ -164,11 +171,3 @@ $edrawer-duration: 0.3s;
|
|
|
164
171
|
display: none !important;
|
|
165
172
|
}
|
|
166
173
|
}
|
|
167
|
-
|
|
168
|
-
// 尊重「减少动效」偏好
|
|
169
|
-
@media (prefers-reduced-motion: reduce) {
|
|
170
|
-
.#{$edrawer-prefix-cls}-mask,
|
|
171
|
-
.#{$edrawer-prefix-cls}-panel {
|
|
172
|
-
transition: none;
|
|
173
|
-
}
|
|
174
|
-
}
|
package/dist/style/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.edrawer{bottom:0;box-sizing:border-box;left:0;overflow:hidden;pointer-events:none;position:absolute;right:0;top:0;z-index:var(--edrawer-z-index,100)}.edrawer-fixed{position:fixed}.edrawer-mask{background-color:var(--edrawer-mask-bg,rgba(0,0,0,.3));bottom:0;left:0;opacity:0;position:absolute;right:0;top:0;transition:opacity var(--edrawer-duration,.3s) ease}.edrawer-panel{background-color:var(--edrawer-bg,#fff);box-sizing:border-box;color:var(--edrawer-color,rgba(0,0,0,.88));display:flex;flex-direction:column;overflow:hidden;position:absolute;transition:transform var(--edrawer-duration,.3s) ease}.edrawer-left .edrawer-panel,.edrawer-right .edrawer-panel{bottom:0;max-width:var(--edrawer-max-width,100%);top:0}.edrawer-bottom .edrawer-panel,.edrawer-top .edrawer-panel{left:0;max-height:var(--edrawer-max-height,100%);right:0}.edrawer-right .edrawer-panel{border-left:1px solid var(--edrawer-border-color,rgba(0,0,0,.1));right:0;transform:translateX(100%)}.edrawer-left .edrawer-panel{border-right:1px solid var(--edrawer-border-color,rgba(0,0,0,.1));left:0;transform:translateX(-100%)}.edrawer-top .edrawer-panel{border-bottom:1px solid var(--edrawer-border-color,rgba(0,0,0,.1));top:0;transform:translateY(-100%)}.edrawer-bottom .edrawer-panel{border-top:1px solid var(--edrawer-border-color,rgba(0,0,0,.1));bottom:0;transform:translateY(100%)}.edrawer.edrawer-open .edrawer-mask{opacity:1;pointer-events:auto}.edrawer.edrawer-open .edrawer-panel{pointer-events:auto;transform:translate(0)}.edrawer-header{align-items:center;border-bottom:1px solid var(--edrawer-header-border-color,rgba(0,0,0,.08));box-sizing:border-box;display:flex;flex:0 0 auto;justify-content:space-between;padding:var(--edrawer-header-padding,
|
|
1
|
+
.edrawer{bottom:0;box-sizing:border-box;left:0;overflow:hidden;pointer-events:none;position:absolute;right:0;text-align:left;top:0;z-index:var(--edrawer-z-index,100)}.edrawer-fixed{position:fixed}.edrawer-mask{background-color:var(--edrawer-mask-bg,rgba(0,0,0,.3));bottom:0;left:0;opacity:0;position:absolute;right:0;top:0;transition:opacity var(--edrawer-duration,.3s) ease}.edrawer-panel{background-color:var(--edrawer-bg,#fff);box-sizing:border-box;color:var(--edrawer-color,rgba(0,0,0,.88));display:flex;flex-direction:column;overflow:hidden;position:absolute;text-align:left;transition:transform var(--edrawer-duration,.3s) ease}.edrawer-left .edrawer-panel,.edrawer-right .edrawer-panel{bottom:0;max-width:var(--edrawer-max-width,100%);top:0}.edrawer-bottom .edrawer-panel,.edrawer-top .edrawer-panel{left:0;max-height:var(--edrawer-max-height,100%);right:0}.edrawer-right .edrawer-panel{border-left:1px solid var(--edrawer-border-color,rgba(0,0,0,.1));right:0;transform:translateX(100%)}.edrawer-left .edrawer-panel{border-right:1px solid var(--edrawer-border-color,rgba(0,0,0,.1));left:0;transform:translateX(-100%)}.edrawer-top .edrawer-panel{border-bottom:1px solid var(--edrawer-border-color,rgba(0,0,0,.1));top:0;transform:translateY(-100%)}.edrawer-bottom .edrawer-panel{border-top:1px solid var(--edrawer-border-color,rgba(0,0,0,.1));bottom:0;transform:translateY(100%)}.edrawer.edrawer-open .edrawer-mask{opacity:1;pointer-events:auto}.edrawer.edrawer-open .edrawer-panel{pointer-events:auto;transform:translate(0)}.edrawer-header{align-items:center;border-bottom:1px solid var(--edrawer-header-border-color,rgba(0,0,0,.08));box-sizing:border-box;display:flex;flex:0 0 auto;height:var(--edrawer-header-height,40px);justify-content:space-between;padding:var(--edrawer-header-padding,0 16px)}.edrawer-title{color:var(--edrawer-title-color,#333);flex:1 1 auto;font-size:var(--edrawer-title-font-size,14px);font-weight:500;line-height:1.5;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.edrawer-close{align-items:center;background:transparent;border:none;border-radius:4px;box-sizing:border-box;color:var(--edrawer-close-color,rgba(0,0,0,.45));cursor:pointer;display:inline-flex;flex:0 0 auto;height:28px;justify-content:center;margin-left:12px;padding:0;transition:color .2s,background-color .2s;width:28px}.edrawer-close:hover{background-color:var(--edrawer-close-hover-bg,rgba(0,0,0,.06));color:var(--edrawer-close-hover-color,rgba(0,0,0,.88))}.edrawer-close svg{display:block;height:16px;width:16px}.edrawer-body{box-sizing:border-box;flex:1 1 auto;min-height:0;overflow:auto;position:relative}.edrawer-hidden{display:none!important}
|
package/dist/style/style.js
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
* 抽屉弹出方向
|
|
3
3
|
*/
|
|
4
4
|
type DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';
|
|
5
|
-
/** 事件监听回调 */
|
|
6
|
-
type DrawerListener = (...args: unknown[]) => void;
|
|
7
5
|
/**
|
|
8
6
|
* 动态挂载点解析函数:返回挂载元素;返回 null / undefined 时回退到构造函数传入的 container。
|
|
9
7
|
*/
|
|
@@ -32,7 +30,7 @@ interface DrawerOptions {
|
|
|
32
30
|
showClose?: boolean;
|
|
33
31
|
/** 按下 Esc 是否关闭,默认 true */
|
|
34
32
|
closeOnEscape?: boolean;
|
|
35
|
-
/** 开合动画时长(ms),默认 300
|
|
33
|
+
/** 开合动画时长(ms),默认 300;非有限数或负数回退到默认值。会写入根节点的 `--edrawer-duration`,使 CSS 过渡与 JS 定时器一致 */
|
|
36
34
|
duration?: number;
|
|
37
35
|
/** 创建后是否立即打开,默认 false(仅构造时生效) */
|
|
38
36
|
open?: boolean;
|
|
@@ -74,9 +72,12 @@ interface DrawerOptions {
|
|
|
74
72
|
* placement: 'right',
|
|
75
73
|
* width: 300,
|
|
76
74
|
* });
|
|
77
|
-
* drawer.
|
|
78
|
-
* drawer.open
|
|
75
|
+
* drawer.open = true; // 打开
|
|
76
|
+
* drawer.open = false; // 关闭
|
|
77
|
+
* drawer.destroy();
|
|
79
78
|
* ```
|
|
79
|
+
*
|
|
80
|
+
* 无事件订阅机制,状态变化通过配置项回调通知:`onOpenChange`、`onOpenStart` / `onOpenEnd`、`onCloseStart` / `onCloseEnd`。
|
|
80
81
|
*/
|
|
81
82
|
declare class Drawer {
|
|
82
83
|
/** 构建时由 Rollup 注入版本号 */
|
|
@@ -98,38 +99,124 @@ declare class Drawer {
|
|
|
98
99
|
private _hideTimer;
|
|
99
100
|
/** 打开动画结束后回调的定时器 */
|
|
100
101
|
private _openTimer;
|
|
102
|
+
/** 当前注册了 Esc 监听的 document(容器可能在 iframe 等其它文档内,需与注册时一致才能正确移除) */
|
|
103
|
+
private _keydownDoc;
|
|
101
104
|
/**
|
|
102
105
|
* @param container 默认挂载容器,支持 CSS 选择器、元素 ID 或 HTMLElement,缺省或找不到时为 document.body。
|
|
103
106
|
* 非 body 容器需为定位元素(position 非 static),抽屉相对它铺满定位。
|
|
104
107
|
* @param options 配置项
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* // 元素 ID / CSS 选择器 / HTMLElement 均可;缺省挂载到 document.body(fixed 定位)
|
|
112
|
+
* const drawer = new Drawer('#player', { title: '告警消息', placement: 'right', width: 300 });
|
|
113
|
+
*
|
|
114
|
+
* // 底部抽屉,挂载点晚于控件创建才出现:每次打开时通过 getContainer 解析
|
|
115
|
+
* const mobile = new Drawer(playerEl, {
|
|
116
|
+
* placement: 'bottom',
|
|
117
|
+
* height: '100%',
|
|
118
|
+
* showMask: false,
|
|
119
|
+
* getContainer: () => document.querySelector<HTMLElement>('.ezplayer-mobile-extend'),
|
|
120
|
+
* });
|
|
121
|
+
* ```
|
|
105
122
|
*/
|
|
106
123
|
constructor(container?: string | HTMLElement, options?: DrawerOptions);
|
|
124
|
+
/**
|
|
125
|
+
* 应用构造配置 `open: true`(配置为 false 或缺省时不做任何事)。
|
|
126
|
+
*
|
|
127
|
+
* 直接 `new Drawer()` 时由构造函数自动调用;**子类不会被自动调用**,需在自己的构造函数末尾
|
|
128
|
+
* (自身字段与回调都初始化完成之后)手动调用一次,否则 `open: true` 对子类不生效。
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* class MyDrawer extends Drawer {
|
|
133
|
+
* private readonly logs: string[] = [];
|
|
134
|
+
*
|
|
135
|
+
* constructor(container: HTMLElement, options: DrawerOptions) {
|
|
136
|
+
* super(container, options);
|
|
137
|
+
* this.options.onOpenChange = (open) => this.logs.push(`open=${open}`);
|
|
138
|
+
* this.applyInitialOpen(); // 所有字段与回调就绪后再按配置打开
|
|
139
|
+
* }
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
protected applyInitialOpen(): void;
|
|
107
144
|
/**
|
|
108
145
|
* 打开/关闭抽屉。配置了 `getContainer` 时,会先解析本次挂载点并在需要时移动 DOM。
|
|
146
|
+
* 重复设置相同状态、销毁后设置均为空操作;`getContainer` 抛错时状态保持不变。
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* const drawer = new Drawer('#player', {
|
|
151
|
+
* onOpenChange: (open) => console.log('open =', open),
|
|
152
|
+
* onCloseEnd: () => console.log('收起动画结束'),
|
|
153
|
+
* });
|
|
154
|
+
* drawer.open = true; // 打开:onOpenStart → onOpenChange(true) → onOpenEnd
|
|
155
|
+
* drawer.open = true; // 重复设置,空操作
|
|
156
|
+
* drawer.open = !drawer.open; // 切换(此时为关闭)
|
|
157
|
+
* ```
|
|
109
158
|
*/
|
|
110
159
|
set open(open: boolean);
|
|
111
160
|
/**
|
|
112
|
-
*
|
|
161
|
+
* 当前是否处于打开状态(关闭动画进行中已视为关闭)
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* if (drawer.open) drawer.open = false;
|
|
166
|
+
* ```
|
|
113
167
|
*/
|
|
114
168
|
get open(): boolean;
|
|
115
169
|
/**
|
|
116
170
|
* 设置标题(showHeader 为 false 时仅更新配置)
|
|
117
171
|
* @param title 字符串(按 HTML 插入,须为可信内容)或 HTMLElement
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* drawer.setTitle('告警消息(3)');
|
|
176
|
+
*
|
|
177
|
+
* const title = document.createElement('strong');
|
|
178
|
+
* title.textContent = '告警消息';
|
|
179
|
+
* drawer.setTitle(title);
|
|
180
|
+
* ```
|
|
118
181
|
*/
|
|
119
182
|
setTitle(title: string | HTMLElement): void;
|
|
120
183
|
/**
|
|
121
184
|
* 设置内容
|
|
122
185
|
* @param content 字符串(按 HTML 插入,须为可信内容)或 HTMLElement
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```ts
|
|
189
|
+
* drawer.setContent('<p>暂无数据</p>');
|
|
190
|
+
*
|
|
191
|
+
* const list = document.createElement('ul');
|
|
192
|
+
* drawer.setContent(list); // 节点被移入内容区,引用与其上的监听保留
|
|
193
|
+
* ```
|
|
123
194
|
*/
|
|
124
195
|
setContent(content: string | HTMLElement): void;
|
|
125
196
|
/**
|
|
126
197
|
* 更新配置。方向、尺寸、遮罩、头部等结构性配置通过重建 DOM 生效,
|
|
127
198
|
* 重建后保持当前打开 / 关闭状态(直接处于终态,不重播动画);`open` 仅在构造时生效。
|
|
128
199
|
* @param options 新配置
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* // 切换弹出方向与尺寸:重建 DOM,保持当前开合状态且不重播动画
|
|
204
|
+
* drawer.updateOptions({ placement: 'bottom', height: '60%' });
|
|
205
|
+
*
|
|
206
|
+
* // 只改文案请用 setTitle / setContent,避免重建 DOM 重置内容区滚动位置
|
|
207
|
+
* drawer.updateOptions({ closeOnEscape: false, maskClosable: false });
|
|
208
|
+
* ```
|
|
129
209
|
*/
|
|
130
210
|
updateOptions(options: Partial<DrawerOptions>): void;
|
|
131
211
|
/**
|
|
132
|
-
* 销毁,移除 DOM
|
|
212
|
+
* 销毁,移除 DOM、定时器与全部监听(幂等)。销毁时不会触发任何回调。
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* drawer.destroy();
|
|
217
|
+
* drawer.destroy(); // 幂等
|
|
218
|
+
* drawer.open = true; // 销毁后无效
|
|
219
|
+
* ```
|
|
133
220
|
*/
|
|
134
221
|
destroy(): void;
|
|
135
222
|
private _resolveContainer;
|
|
@@ -141,6 +228,8 @@ declare class Drawer {
|
|
|
141
228
|
private _attach;
|
|
142
229
|
/** 规范化弹出方向,非法值回退到 right */
|
|
143
230
|
private _getPlacement;
|
|
231
|
+
/** 开合动画时长(ms):非有限数或负数回退到默认值,避免 `NaN` 写入 CSS 变量与定时器 */
|
|
232
|
+
private _getDuration;
|
|
144
233
|
private _toSize;
|
|
145
234
|
private _render;
|
|
146
235
|
/** 将字符串(HTML)或节点写入目标元素 */
|
|
@@ -148,6 +237,10 @@ declare class Drawer {
|
|
|
148
237
|
/** 移除 DOM 与元素级监听,并释放全部节点引用 */
|
|
149
238
|
private _teardownDom;
|
|
150
239
|
private _clearTimers;
|
|
240
|
+
/** 在根节点所属文档上注册 Esc 监听(容器可能位于 iframe 等其它文档内,监听必须挂在同一文档才能收到按键) */
|
|
241
|
+
private _bindEscape;
|
|
242
|
+
/** 从注册时的文档上移除 Esc 监听(幂等) */
|
|
243
|
+
private _unbindEscape;
|
|
151
244
|
/** 读取布局属性以强制浏览器回流 */
|
|
152
245
|
private _reflow;
|
|
153
246
|
private readonly _onCloseClick;
|
|
@@ -158,4 +251,4 @@ declare class Drawer {
|
|
|
158
251
|
}
|
|
159
252
|
|
|
160
253
|
export { Drawer as default };
|
|
161
|
-
export type { DrawerContainerGetter,
|
|
254
|
+
export type { DrawerContainerGetter, DrawerOptions, DrawerPlacement };
|