@ezuikit/control-drawer 0.0.0-stage → 0.0.1-beta.2
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 +147 -2
- package/dist/index.cjs +6 -0
- package/dist/index.esm.js +6 -0
- package/dist/index.umd.js +6 -0
- package/dist/style/index.js +1 -0
- package/dist/style/style/index.scss +174 -0
- package/dist/style/style.css +1 -0
- package/dist/style/style.js +6 -0
- package/dist/types/index.d.ts +149 -0
- package/package.json +45 -3
package/README.md
CHANGED
|
@@ -1,3 +1,148 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ezuikit/control-drawer 使用指南
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
抽屉布局控件。只提供布局骨架:遮罩、从四个方向滑出的面板、标题栏与关闭按钮、开合动画和挂载策略;业务内容通过 `content` 注入。`@ezuikit/control-alarm-message` 基于它实现告警消息面板。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @ezuikit/control-drawer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 快速开始
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import Drawer from '@ezuikit/control-drawer';
|
|
15
|
+
import '@ezuikit/control-drawer/dist/style/style.css';
|
|
16
|
+
|
|
17
|
+
const list = document.createElement('div');
|
|
18
|
+
|
|
19
|
+
// 挂载容器需为定位元素(position 非 static),抽屉相对它铺满;缺省为 document.body(相对视口)
|
|
20
|
+
const drawer = new Drawer(document.getElementById('player')!, {
|
|
21
|
+
title: '告警消息',
|
|
22
|
+
content: list,
|
|
23
|
+
placement: 'right',
|
|
24
|
+
width: 300,
|
|
25
|
+
onOpenChange: (open) => console.log('open =', open),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
drawer.open = true;
|
|
29
|
+
drawer.open = false;
|
|
30
|
+
drawer.destroy();
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
UMD:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<link rel="stylesheet" href="./style/style.css" />
|
|
37
|
+
<script src="./index.umd.js"></script>
|
|
38
|
+
<script>
|
|
39
|
+
const drawer = new Drawer('#player', { title: 'Title', content: '<p>Hello</p>' });
|
|
40
|
+
drawer.open = true;
|
|
41
|
+
</script>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 动态挂载点
|
|
45
|
+
|
|
46
|
+
挂载点晚于控件创建才出现时(如移动端扩展区),用 `getContainer`:首次打开(`open = true`)前不挂载 DOM,每次打开时重新解析并在需要时移动 DOM,返回空时回退到 `container`。
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
const drawer = new Drawer(playerEl, {
|
|
50
|
+
placement: 'bottom',
|
|
51
|
+
height: '100%',
|
|
52
|
+
showMask: false,
|
|
53
|
+
getContainer: () => document.querySelector<HTMLElement>('.ezplayer-mobile-extend'), // 需为定位元素
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 构造函数
|
|
58
|
+
|
|
59
|
+
`new Drawer(container?, options?)`
|
|
60
|
+
|
|
61
|
+
| 参数 | 类型 | 默认 | 说明 |
|
|
62
|
+
| ----------- | ----------------------- | --------------- | -------------------------------------------------------- |
|
|
63
|
+
| `container` | `string \| HTMLElement` | `document.body` | 默认挂载容器,支持元素 ID、CSS 选择器;找不到时回退 body |
|
|
64
|
+
| `options` | `DrawerOptions` | - | 配置项,见下表 |
|
|
65
|
+
|
|
66
|
+
## 配置项
|
|
67
|
+
|
|
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
|
+
| `open` | `boolean` | `false` | 创建后立即打开(仅构造时生效) |
|
|
81
|
+
| `zIndex` | `number` | - | 根节点层级,缺省取 `--edrawer-z-index`(100) |
|
|
82
|
+
| `className` | `string` | - | 追加到根节点的类名,多个用空格分隔 |
|
|
83
|
+
| `getContainer` | `() => HTMLElement \| null \| undefined` | - | 动态挂载点,见上文 |
|
|
84
|
+
| `onOpenChange` | `(open: boolean) => void` | - | 打开/关闭回调,参数为当前状态 |
|
|
85
|
+
|
|
86
|
+
## 方法 / 属性
|
|
87
|
+
|
|
88
|
+
| 成员 | 说明 |
|
|
89
|
+
| ----------------------------------------- | ---------------------------------------------------- |
|
|
90
|
+
| `open` | 布尔属性(getter/setter),打开/关闭抽屉;重复设置相同状态为幂等 |
|
|
91
|
+
| `setTitle(title)` / `setContent(content)` | 更新标题 / 内容,不重建 DOM |
|
|
92
|
+
| `updateOptions(opts)` | 更新配置并重建 DOM,保持当前开合状态且不重播动画 |
|
|
93
|
+
| `destroy()` | 销毁(幂等),移除 DOM、定时器与监听,不触发 `onOpenChange` |
|
|
94
|
+
| `Drawer.VERSION` | 构建时由 Rollup 注入的版本号(静态属性) |
|
|
95
|
+
|
|
96
|
+
## 打开 / 关闭回调
|
|
97
|
+
|
|
98
|
+
通过 `options.onOpenChange` 注册,打开与关闭时同步调用,参数为当前状态 `boolean`(`true` 打开 / `false` 关闭);在动画开始时同步触发,关闭时不等收起动画结束。
|
|
99
|
+
|
|
100
|
+
## 样式与类名
|
|
101
|
+
|
|
102
|
+
统一前缀 `edrawer`(常量 `_DRAWER_PREFIX_CLS_`,SCSS 变量 `$edrawer-prefix-cls`):
|
|
103
|
+
|
|
104
|
+
- 结构:`edrawer`(根)> `edrawer-mask` + `edrawer-panel` > `edrawer-header`(`edrawer-title`、`edrawer-close`)+ `edrawer-body`
|
|
105
|
+
- 状态:`edrawer-left` / `-right` / `-top` / `-bottom`、`edrawer-open`、`edrawer-hidden`、`edrawer-fixed`(挂在 body 上)
|
|
106
|
+
|
|
107
|
+
外观通过 CSS 变量定制,可设在 `className` 对应的根节点上按实例覆盖:
|
|
108
|
+
|
|
109
|
+
| 变量 | 默认 | 说明 |
|
|
110
|
+
| ------------------------------- | ----------------- | ------------------ |
|
|
111
|
+
| `--edrawer-z-index` | `100` | 根节点层级 |
|
|
112
|
+
| `--edrawer-bg` | `#fff` | 面板背景 |
|
|
113
|
+
| `--edrawer-color` | `rgba(0,0,0,.88)` | 面板文字色 |
|
|
114
|
+
| `--edrawer-mask-bg` | `rgba(0,0,0,.3)` | 遮罩色 |
|
|
115
|
+
| `--edrawer-border-color` | `rgba(0,0,0,.1)` | 面板内侧边框 |
|
|
116
|
+
| `--edrawer-max-width` | `100%` | 左右方向的最大宽度 |
|
|
117
|
+
| `--edrawer-max-height` | `100%` | 上下方向的最大高度 |
|
|
118
|
+
| `--edrawer-header-padding` | `12px 16px` | 头部内边距 |
|
|
119
|
+
| `--edrawer-header-border-color` | `rgba(0,0,0,.08)` | 头部分隔线 |
|
|
120
|
+
| `--edrawer-title-color` | `#333` | 标题色 |
|
|
121
|
+
| `--edrawer-title-font-size` | `14px` | 标题字号 |
|
|
122
|
+
| `--edrawer-close-color` | `rgba(0,0,0,.4)` | 关闭按钮色 |
|
|
123
|
+
| `--edrawer-close-hover-color` | `#333` | 关闭按钮悬停色 |
|
|
124
|
+
|
|
125
|
+
```css
|
|
126
|
+
/* 例:告警消息面板在 PC 端最多占容器 80% 宽 */
|
|
127
|
+
.ezuikit-alarm-message-drawer {
|
|
128
|
+
--edrawer-max-width: 80%;
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 注意事项
|
|
133
|
+
|
|
134
|
+
**挂载容器必须是定位元素。** 根节点是 `position: absolute` 铺满容器;容器为 `static` 时会相对更外层的定位祖先铺开。挂载到 `document.body` 时自动切换为 `position: fixed`(相对视口)。
|
|
135
|
+
|
|
136
|
+
**字符串按 HTML 插入。** `title` / `content` / `setTitle` / `setContent` 传字符串时写入 `innerHTML`,只能传可信内容;不可信数据请自行转义或传 `HTMLElement`。
|
|
137
|
+
|
|
138
|
+
**动画时长固定 300ms。** JS 常量 `_DRAWER_DURATION_` 与 SCSS 变量 `$edrawer-duration` 必须同步修改;只在宿主 CSS 里改 `transition` 时长不会改变 JS 的隐藏时机。系统开启"减少动效"时过渡被关闭。
|
|
139
|
+
|
|
140
|
+
**`updateOptions` 会重建 DOM。** 以 `HTMLElement` 传入的内容会被移动到新节点,引用与其上的监听保留,但内部滚动位置会重置;只改文案时用 `setTitle` / `setContent`。
|
|
141
|
+
|
|
142
|
+
**显式传 `undefined` 会覆盖默认值。** 配置按 `Object.assign({}, 默认配置, options)` 浅合并,DOM 节点与函数按引用保留;`{ width: undefined }` 会让面板失去默认宽度,不需要的字段请不要传。
|
|
143
|
+
|
|
144
|
+
**Esc 监听挂在 `document` 上**,仅在打开期间存在,多个抽屉同时打开时一次 Esc 会全部关闭。
|
|
145
|
+
|
|
146
|
+
**事件冒泡。** 根节点拦截 `dblclick` 冒泡,避免在播放器容器内双击触发全屏切换;`click` 不拦截,点击遮罩关闭后事件仍会冒泡到宿主。关闭按钮的点击会阻止冒泡。
|
|
147
|
+
|
|
148
|
+
**无障碍。** 面板带 `role="dialog"`,有头部时通过 `aria-labelledby` 关联标题;关闭按钮为 `<button type="button">`,内联 SVG 图标 `aria-hidden="true"`,未设置 `aria-label`。未做焦点管理与焦点陷阱。
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @ezuikit/control-drawer v0.0.1-beta.2
|
|
3
|
+
* Copyright (c) 2026-10-01 03:43:12 Ezviz-OpenBiz
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
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 _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._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){"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),this.options.open&&(this.open=!0)}var _proto=Drawer.prototype;return _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._clearHideTimer(),this._teardownDom(),this._render(),parent&&this._attach(parent),document.removeEventListener("keydown",this._onKeydown),this._open&&this.options.closeOnEscape&&document.addEventListener("keydown",this._onKeydown)}},_proto.destroy=function(){this._destroyed||(this._destroyed=!0,this._open=!1,this._clearHideTimer(),document.removeEventListener("keydown",this._onKeydown),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===document.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._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.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 width="1em" height="1em" viewBox="0 0 14 14" fill="currentColor" focusable="false" aria-hidden="true">\n <path d="M13.3 0.7c-0.4-0.4-1-0.4-1.4 0L7 5.6 2.1 0.7c-0.4-0.4-1-0.4-1.4 0s-0.4 1 0 1.4L5.6 7 0.7 11.9c-0.4 0.4-0.4 1 0 1.4 0.2 0.2 0.5 0.3 0.7 0.3s0.5-0.1 0.7-0.3L7 8.4l4.9 4.9c0.2 0.2 0.5 0.3 0.7 0.3s0.5-0.1 0.7-0.3c0.4-0.4 0.4-1 0-1.4L8.4 7l4.9-4.9C13.7 1.7 13.7 1.1 13.3 0.7z"/>\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._clearHideTimer=function(){null!==this._hideTimer&&(clearTimeout(this._hideTimer),this._hideTimer=null)},_proto._reflow=function(el){return el.offsetHeight},_create_class(Drawer,[{key:"open",get:function(){return this._open},set:function(open){var _this=this,root=this._$root;!this._destroyed&&this._open!==open&&root&&(this._open=open,this._clearHideTimer(),open?(this._attach(this._resolveMountTarget()),root.classList.remove("edrawer-hidden"),this._reflow(root),root.classList.add("edrawer-open"),this.options.closeOnEscape&&document.addEventListener("keydown",this._onKeydown)):(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")},300),document.removeEventListener("keydown",this._onKeydown)),null==this.options.onOpenChange||this.options.onOpenChange.call(this.options,open))}}]),Drawer}();Drawer.VERSION="0.0.1-beta.2",module.exports=Drawer;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @ezuikit/control-drawer v0.0.1-beta.2
|
|
3
|
+
* Copyright (c) 2026-10-01 03:43:12 Ezviz-OpenBiz
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
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 _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._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){"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),this.options.open&&(this.open=!0)}var _proto=Drawer.prototype;return _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._clearHideTimer(),this._teardownDom(),this._render(),parent&&this._attach(parent),document.removeEventListener("keydown",this._onKeydown),this._open&&this.options.closeOnEscape&&document.addEventListener("keydown",this._onKeydown)}},_proto.destroy=function(){this._destroyed||(this._destroyed=!0,this._open=!1,this._clearHideTimer(),document.removeEventListener("keydown",this._onKeydown),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===document.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._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.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 width="1em" height="1em" viewBox="0 0 14 14" fill="currentColor" focusable="false" aria-hidden="true">\n <path d="M13.3 0.7c-0.4-0.4-1-0.4-1.4 0L7 5.6 2.1 0.7c-0.4-0.4-1-0.4-1.4 0s-0.4 1 0 1.4L5.6 7 0.7 11.9c-0.4 0.4-0.4 1 0 1.4 0.2 0.2 0.5 0.3 0.7 0.3s0.5-0.1 0.7-0.3L7 8.4l4.9 4.9c0.2 0.2 0.5 0.3 0.7 0.3s0.5-0.1 0.7-0.3c0.4-0.4 0.4-1 0-1.4L8.4 7l4.9-4.9C13.7 1.7 13.7 1.1 13.3 0.7z"/>\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._clearHideTimer=function(){null!==this._hideTimer&&(clearTimeout(this._hideTimer),this._hideTimer=null)},_proto._reflow=function(el){return el.offsetHeight},_create_class(Drawer,[{key:"open",get:function(){return this._open},set:function(open){var _this=this,root=this._$root;!this._destroyed&&this._open!==open&&root&&(this._open=open,this._clearHideTimer(),open?(this._attach(this._resolveMountTarget()),root.classList.remove("edrawer-hidden"),this._reflow(root),root.classList.add("edrawer-open"),this.options.closeOnEscape&&document.addEventListener("keydown",this._onKeydown)):(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")},300),document.removeEventListener("keydown",this._onKeydown)),null==this.options.onOpenChange||this.options.onOpenChange.call(this.options,open))}}]),Drawer}();Drawer.VERSION="0.0.1-beta.2";export{Drawer as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @ezuikit/control-drawer v0.0.1-beta.2
|
|
3
|
+
* Copyright (c) 2026-10-01 03:43:12 Ezviz-OpenBiz
|
|
4
|
+
* Released under the MIT License.
|
|
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 _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 _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._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){"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),this.options.open&&(this.open=!0)}var _proto=Drawer.prototype;return _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._clearHideTimer(),this._teardownDom(),this._render(),parent&&this._attach(parent),document.removeEventListener("keydown",this._onKeydown),this._open&&this.options.closeOnEscape&&document.addEventListener("keydown",this._onKeydown)}},_proto.destroy=function(){this._destroyed||(this._destroyed=!0,this._open=!1,this._clearHideTimer(),document.removeEventListener("keydown",this._onKeydown),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===document.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._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.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 width="1em" height="1em" viewBox="0 0 14 14" fill="currentColor" focusable="false" aria-hidden="true">\n <path d="M13.3 0.7c-0.4-0.4-1-0.4-1.4 0L7 5.6 2.1 0.7c-0.4-0.4-1-0.4-1.4 0s-0.4 1 0 1.4L5.6 7 0.7 11.9c-0.4 0.4-0.4 1 0 1.4 0.2 0.2 0.5 0.3 0.7 0.3s0.5-0.1 0.7-0.3L7 8.4l4.9 4.9c0.2 0.2 0.5 0.3 0.7 0.3s0.5-0.1 0.7-0.3c0.4-0.4 0.4-1 0-1.4L8.4 7l4.9-4.9C13.7 1.7 13.7 1.1 13.3 0.7z"/>\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._clearHideTimer=function(){null!==this._hideTimer&&(clearTimeout(this._hideTimer),this._hideTimer=null)},_proto._reflow=function(el){return el.offsetHeight},_create_class(Drawer,[{key:"open",get:function(){return this._open},set:function(open){var _this=this,root=this._$root;!this._destroyed&&this._open!==open&&root&&(this._open=open,this._clearHideTimer(),open?(this._attach(this._resolveMountTarget()),root.classList.remove("edrawer-hidden"),this._reflow(root),root.classList.add("edrawer-open"),this.options.closeOnEscape&&document.addEventListener("keydown",this._onKeydown)):(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")},300),document.removeEventListener("keydown",this._onKeydown)),null==this.options.onOpenChange||this.options.onOpenChange.call(this.options,open))}}]),Drawer}();return Drawer.VERSION="0.0.1-beta.2",Drawer});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './style/index.scss';
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------------
|
|
2
|
+
// Drawer 抽屉布局骨架
|
|
3
|
+
// 结构:.edrawer(根,铺满挂载容器) > .edrawer-mask(遮罩) + .edrawer-panel(面板)
|
|
4
|
+
// .edrawer-panel > .edrawer-header(.edrawer-title + .edrawer-close) + .edrawer-body
|
|
5
|
+
// 外观通过 --edrawer-* 变量定制,缺省值见各 var() 的回退值。
|
|
6
|
+
// -----------------------------------------------------------------------------
|
|
7
|
+
$edrawer-prefix-cls: 'edrawer';
|
|
8
|
+
// 开合过渡时长,需与 src/constant.ts 中的 _DRAWER_DURATION_ 保持一致
|
|
9
|
+
$edrawer-duration: 0.3s;
|
|
10
|
+
|
|
11
|
+
.#{$edrawer-prefix-cls} {
|
|
12
|
+
position: absolute;
|
|
13
|
+
top: 0;
|
|
14
|
+
right: 0;
|
|
15
|
+
bottom: 0;
|
|
16
|
+
left: 0;
|
|
17
|
+
z-index: var(--edrawer-z-index, 100);
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
// 根节点不拦截指针事件:不展示遮罩时,面板以外的区域仍可操作底层内容
|
|
21
|
+
pointer-events: none;
|
|
22
|
+
|
|
23
|
+
// 挂载到 document.body 时相对视口定位
|
|
24
|
+
&-fixed {
|
|
25
|
+
position: fixed;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 遮罩
|
|
29
|
+
&-mask {
|
|
30
|
+
position: absolute;
|
|
31
|
+
top: 0;
|
|
32
|
+
right: 0;
|
|
33
|
+
bottom: 0;
|
|
34
|
+
left: 0;
|
|
35
|
+
background-color: var(--edrawer-mask-bg, rgba(0, 0, 0, 0.3));
|
|
36
|
+
opacity: 0;
|
|
37
|
+
transition: opacity $edrawer-duration ease;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 面板
|
|
41
|
+
&-panel {
|
|
42
|
+
position: absolute;
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
box-sizing: border-box;
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
background-color: var(--edrawer-bg, #fff);
|
|
48
|
+
color: var(--edrawer-color, rgba(0, 0, 0, 0.88));
|
|
49
|
+
transition: transform $edrawer-duration ease;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 弹出方向:收起态面板位于容器外侧
|
|
53
|
+
&-left &-panel,
|
|
54
|
+
&-right &-panel {
|
|
55
|
+
top: 0;
|
|
56
|
+
bottom: 0;
|
|
57
|
+
max-width: var(--edrawer-max-width, 100%);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
&-top &-panel,
|
|
61
|
+
&-bottom &-panel {
|
|
62
|
+
left: 0;
|
|
63
|
+
right: 0;
|
|
64
|
+
max-height: var(--edrawer-max-height, 100%);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&-right &-panel {
|
|
68
|
+
right: 0;
|
|
69
|
+
border-left: 1px solid var(--edrawer-border-color, rgba(0, 0, 0, 0.1));
|
|
70
|
+
transform: translateX(100%);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&-left &-panel {
|
|
74
|
+
left: 0;
|
|
75
|
+
border-right: 1px solid var(--edrawer-border-color, rgba(0, 0, 0, 0.1));
|
|
76
|
+
transform: translateX(-100%);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&-top &-panel {
|
|
80
|
+
top: 0;
|
|
81
|
+
border-bottom: 1px solid var(--edrawer-border-color, rgba(0, 0, 0, 0.1));
|
|
82
|
+
transform: translateY(-100%);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&-bottom &-panel {
|
|
86
|
+
bottom: 0;
|
|
87
|
+
border-top: 1px solid var(--edrawer-border-color, rgba(0, 0, 0, 0.1));
|
|
88
|
+
transform: translateY(100%);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 打开态(.edrawer.edrawer-open,优先级高于方向规则,不依赖书写顺序):遮罩淡入、面板滑入,二者恢复可交互
|
|
92
|
+
&.#{$edrawer-prefix-cls}-open &-mask {
|
|
93
|
+
opacity: 1;
|
|
94
|
+
pointer-events: auto;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
&.#{$edrawer-prefix-cls}-open &-panel {
|
|
98
|
+
transform: translate(0, 0);
|
|
99
|
+
pointer-events: auto;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 头部
|
|
103
|
+
&-header {
|
|
104
|
+
display: flex;
|
|
105
|
+
flex: 0 0 auto;
|
|
106
|
+
align-items: center;
|
|
107
|
+
justify-content: space-between;
|
|
108
|
+
box-sizing: border-box;
|
|
109
|
+
padding: var(--edrawer-header-padding, 8px 16px);
|
|
110
|
+
border-bottom: 1px solid var(--edrawer-header-border-color, rgba(0, 0, 0, 0.08));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
&-title {
|
|
114
|
+
flex: 1 1 auto;
|
|
115
|
+
min-width: 0;
|
|
116
|
+
overflow: hidden;
|
|
117
|
+
color: var(--edrawer-title-color, #333);
|
|
118
|
+
font-size: var(--edrawer-title-font-size, 12px);
|
|
119
|
+
font-weight: 500;
|
|
120
|
+
line-height: 1.5;
|
|
121
|
+
white-space: nowrap;
|
|
122
|
+
text-overflow: ellipsis;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 关闭按钮
|
|
126
|
+
&-close {
|
|
127
|
+
display: inline-flex;
|
|
128
|
+
flex: 0 0 auto;
|
|
129
|
+
align-items: center;
|
|
130
|
+
justify-content: center;
|
|
131
|
+
margin-left: 12px;
|
|
132
|
+
padding: 4px;
|
|
133
|
+
border: none;
|
|
134
|
+
border-radius: 4px;
|
|
135
|
+
background: transparent;
|
|
136
|
+
color: var(--edrawer-close-color, rgba(0, 0, 0, 0.4));
|
|
137
|
+
cursor: pointer;
|
|
138
|
+
transition: color 0.2s;
|
|
139
|
+
font-size: 14px;
|
|
140
|
+
|
|
141
|
+
&:hover {
|
|
142
|
+
color: var(--edrawer-close-hover-color, #333);
|
|
143
|
+
background: transparent;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
svg {
|
|
147
|
+
display: block;
|
|
148
|
+
width: 14px;
|
|
149
|
+
height: 14px;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 内容区:占满头部以外的空间,内容超出时滚动
|
|
154
|
+
&-body {
|
|
155
|
+
position: relative;
|
|
156
|
+
flex: 1 1 auto;
|
|
157
|
+
min-height: 0;
|
|
158
|
+
overflow: auto;
|
|
159
|
+
box-sizing: border-box;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// 隐藏态(收起动画结束后)
|
|
163
|
+
&-hidden {
|
|
164
|
+
display: none !important;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 尊重「减少动效」偏好
|
|
169
|
+
@media (prefers-reduced-motion: reduce) {
|
|
170
|
+
.#{$edrawer-prefix-cls}-mask,
|
|
171
|
+
.#{$edrawer-prefix-cls}-panel {
|
|
172
|
+
transition: none;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +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 .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 .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,8px 16px)}.edrawer-title{color:var(--edrawer-title-color,#333);flex:1 1 auto;font-size:var(--edrawer-title-font-size,12px);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;color:var(--edrawer-close-color,rgba(0,0,0,.4));cursor:pointer;display:inline-flex;flex:0 0 auto;font-size:14px;justify-content:center;margin-left:12px;padding:4px;transition:color .2s}.edrawer-close:hover{background:transparent;color:var(--edrawer-close-hover-color,#333)}.edrawer-close svg{display:block;height:14px;width:14px}.edrawer-body{box-sizing:border-box;flex:1 1 auto;min-height:0;overflow:auto;position:relative}.edrawer-hidden{display:none!important}@media (prefers-reduced-motion:reduce){.edrawer-mask,.edrawer-panel{transition:none}}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 抽屉弹出方向
|
|
3
|
+
*/
|
|
4
|
+
type DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';
|
|
5
|
+
/** 事件监听回调 */
|
|
6
|
+
type DrawerListener = (...args: unknown[]) => void;
|
|
7
|
+
/**
|
|
8
|
+
* 动态挂载点解析函数:返回挂载元素;返回 null / undefined 时回退到构造函数传入的 container。
|
|
9
|
+
*/
|
|
10
|
+
type DrawerContainerGetter = () => HTMLElement | null | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Drawer 配置项
|
|
13
|
+
*/
|
|
14
|
+
interface DrawerOptions {
|
|
15
|
+
/** 标题:字符串按 HTML 插入(须为可信内容),也可传 HTMLElement */
|
|
16
|
+
title?: string | HTMLElement;
|
|
17
|
+
/** 内容:字符串按 HTML 插入(须为可信内容),也可传 HTMLElement */
|
|
18
|
+
content?: string | HTMLElement;
|
|
19
|
+
/** 弹出方向,默认 'right' */
|
|
20
|
+
placement?: DrawerPlacement;
|
|
21
|
+
/** 面板宽度,placement 为 left / right 时生效;number 视为 px,默认 300 */
|
|
22
|
+
width?: number | string;
|
|
23
|
+
/** 面板高度,placement 为 top / bottom 时生效;number 视为 px,默认 300 */
|
|
24
|
+
height?: number | string;
|
|
25
|
+
/** 是否展示遮罩,默认 true */
|
|
26
|
+
showMask?: boolean;
|
|
27
|
+
/** 点击遮罩是否关闭,默认 true */
|
|
28
|
+
maskClosable?: boolean;
|
|
29
|
+
/** 是否展示头部(标题 + 关闭按钮),默认 true */
|
|
30
|
+
showHeader?: boolean;
|
|
31
|
+
/** 是否展示关闭(X)按钮(位于头部,showHeader 为 false 时无效),默认 true */
|
|
32
|
+
showClose?: boolean;
|
|
33
|
+
/** 按下 Esc 是否关闭,默认 true */
|
|
34
|
+
closeOnEscape?: boolean;
|
|
35
|
+
/** 创建后是否立即打开,默认 false(仅构造时生效) */
|
|
36
|
+
open?: boolean;
|
|
37
|
+
/** 根节点层级,缺省使用样式变量 `--edrawer-z-index`(默认 100) */
|
|
38
|
+
zIndex?: number;
|
|
39
|
+
/** 追加到根节点的自定义类名,多个用空格分隔 */
|
|
40
|
+
className?: string;
|
|
41
|
+
/**
|
|
42
|
+
* 动态挂载点。配置后首次 open() 前不挂载 DOM,每次 open() 时调用它决定挂载位置,
|
|
43
|
+
* 返回 null / undefined 时回退到 container。适用于挂载点晚于控件创建才出现的场景(如移动端扩展区)。
|
|
44
|
+
*/
|
|
45
|
+
getContainer?: DrawerContainerGetter;
|
|
46
|
+
/** 打开/关闭回调 */
|
|
47
|
+
onOpenChange?: (open: boolean) => void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Drawer 抽屉布局控件。
|
|
52
|
+
*
|
|
53
|
+
* 只负责抽屉的布局骨架,业务内容通过 `content` / {@link Drawer.setContent} 注入:
|
|
54
|
+
* 1. 遮罩 + 从左 / 右 / 上 / 下滑出的面板,带开合过渡动画;
|
|
55
|
+
* 2. 头部(标题 + 关闭按钮),支持点击遮罩、Esc 关闭;
|
|
56
|
+
* 3. 默认相对挂载容器定位(容器需为定位元素),挂载到 document.body 时相对视口定位;
|
|
57
|
+
* 4. 支持通过 `getContainer` 在每次打开时动态解析挂载点(如移动端扩展区)。
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const drawer = new Drawer('#player', {
|
|
62
|
+
* title: '告警消息',
|
|
63
|
+
* content: listElement,
|
|
64
|
+
* placement: 'right',
|
|
65
|
+
* width: 300,
|
|
66
|
+
* });
|
|
67
|
+
* drawer.on(Drawer.EVENTS.close, () => console.log('closed'));
|
|
68
|
+
* drawer.open();
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
declare class Drawer {
|
|
72
|
+
/** 构建时由 Rollup 注入版本号 */
|
|
73
|
+
static VERSION: string;
|
|
74
|
+
/** 配置项 */
|
|
75
|
+
options: DrawerOptions;
|
|
76
|
+
/** 默认挂载容器 */
|
|
77
|
+
private _container;
|
|
78
|
+
private _$root;
|
|
79
|
+
private _$mask;
|
|
80
|
+
private _$title;
|
|
81
|
+
private _$close;
|
|
82
|
+
private _$body;
|
|
83
|
+
/** 标题节点 id(面板 aria-labelledby 引用) */
|
|
84
|
+
private readonly _titleId;
|
|
85
|
+
private _open;
|
|
86
|
+
private _destroyed;
|
|
87
|
+
/** 收起动画结束后隐藏根节点的定时器 */
|
|
88
|
+
private _hideTimer;
|
|
89
|
+
/**
|
|
90
|
+
* @param container 默认挂载容器,支持 CSS 选择器、元素 ID 或 HTMLElement,缺省或找不到时为 document.body。
|
|
91
|
+
* 非 body 容器需为定位元素(position 非 static),抽屉相对它铺满定位。
|
|
92
|
+
* @param options 配置项
|
|
93
|
+
*/
|
|
94
|
+
constructor(container?: string | HTMLElement, options?: DrawerOptions);
|
|
95
|
+
/**
|
|
96
|
+
* 打开/关闭抽屉。配置了 `getContainer` 时,会先解析本次挂载点并在需要时移动 DOM。
|
|
97
|
+
*/
|
|
98
|
+
set open(open: boolean);
|
|
99
|
+
/**
|
|
100
|
+
* 当前是否处于打开状态
|
|
101
|
+
*/
|
|
102
|
+
get open(): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* 设置标题(showHeader 为 false 时仅更新配置)
|
|
105
|
+
* @param title 字符串(按 HTML 插入,须为可信内容)或 HTMLElement
|
|
106
|
+
*/
|
|
107
|
+
setTitle(title: string | HTMLElement): void;
|
|
108
|
+
/**
|
|
109
|
+
* 设置内容
|
|
110
|
+
* @param content 字符串(按 HTML 插入,须为可信内容)或 HTMLElement
|
|
111
|
+
*/
|
|
112
|
+
setContent(content: string | HTMLElement): void;
|
|
113
|
+
/**
|
|
114
|
+
* 更新配置。方向、尺寸、遮罩、头部等结构性配置通过重建 DOM 生效,
|
|
115
|
+
* 重建后保持当前打开 / 关闭状态(直接处于终态,不重播动画);`open` 仅在构造时生效。
|
|
116
|
+
* @param options 新配置
|
|
117
|
+
*/
|
|
118
|
+
updateOptions(options: Partial<DrawerOptions>): void;
|
|
119
|
+
/**
|
|
120
|
+
* 销毁,移除 DOM、定时器与全部监听(幂等)。销毁时不会派发 close 事件。
|
|
121
|
+
*/
|
|
122
|
+
destroy(): void;
|
|
123
|
+
private _resolveContainer;
|
|
124
|
+
/** 按 CSS 选择器查找元素,非法选择器返回 null 而不是抛错 */
|
|
125
|
+
private _query;
|
|
126
|
+
/** 本次打开的挂载点:优先 getContainer(),为空时回退到默认容器 */
|
|
127
|
+
private _resolveMountTarget;
|
|
128
|
+
/** 将根节点挂载到目标容器(已在该容器内则不移动) */
|
|
129
|
+
private _attach;
|
|
130
|
+
/** 规范化弹出方向,非法值回退到 right */
|
|
131
|
+
private _getPlacement;
|
|
132
|
+
private _toSize;
|
|
133
|
+
private _render;
|
|
134
|
+
/** 将字符串(HTML)或节点写入目标元素 */
|
|
135
|
+
private _mount;
|
|
136
|
+
/** 移除 DOM 与元素级监听,并释放全部节点引用 */
|
|
137
|
+
private _teardownDom;
|
|
138
|
+
private _clearHideTimer;
|
|
139
|
+
/** 读取布局属性以强制浏览器回流 */
|
|
140
|
+
private _reflow;
|
|
141
|
+
private readonly _onCloseClick;
|
|
142
|
+
private readonly _onMaskClick;
|
|
143
|
+
/** 阻止抽屉内双击冒泡到播放器容器触发全屏切换 */
|
|
144
|
+
private readonly _onRootDblClick;
|
|
145
|
+
private readonly _onKeydown;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export { Drawer as default };
|
|
149
|
+
export type { DrawerContainerGetter, DrawerListener, DrawerOptions, DrawerPlacement };
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ezuikit/control-drawer",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.1-beta.2",
|
|
4
|
+
"description": "drawer layout control for ezviz",
|
|
5
|
+
"title": "drawer",
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.esm.js",
|
|
8
|
+
"types": "dist/types/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/types/index.d.ts",
|
|
12
|
+
"import": "./dist/index.esm.js",
|
|
13
|
+
"require": "./dist/index.cjs",
|
|
14
|
+
"default": "./dist/index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./dist/style/style.css": "./dist/style/style.css",
|
|
17
|
+
"./dist/style": "./dist/style/index.js",
|
|
18
|
+
"./dist/style/index": "./dist/style/index.js",
|
|
19
|
+
"./dist/style/index.js": "./dist/style/index.js",
|
|
20
|
+
"./dist/style/style": "./dist/style/style.js",
|
|
21
|
+
"./dist/style/style.js": "./dist/style/style.js",
|
|
22
|
+
"./dist/style/index.scss": "./dist/style/index.scss"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"ezuikit",
|
|
26
|
+
"drawer",
|
|
27
|
+
"panel",
|
|
28
|
+
"layout"
|
|
29
|
+
],
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"author": "Ezviz-OpenBiz",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"dependencies": {},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"registry": "https://registry.npmjs.org/",
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/Ezviz-OpenBiz/EZUIKit-player-controls.git"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/Ezviz-OpenBiz/EZUIKit-player-controls/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/Ezviz-OpenBiz/EZUIKit-player-controls#readme"
|
|
6
48
|
}
|