wok-ui-ext 0.1.0
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/LICENSE +21 -0
- package/README.en.md +75 -0
- package/README.md +75 -0
- package/dist/alert/index.d.ts +10 -0
- package/dist/alert/index.js +48 -0
- package/dist/alert/style.css +116 -0
- package/dist/avatar/index.d.ts +9 -0
- package/dist/avatar/index.js +30 -0
- package/dist/avatar/style.css +32 -0
- package/dist/badge/index.d.ts +32 -0
- package/dist/badge/index.js +61 -0
- package/dist/badge/style.css +68 -0
- package/dist/breadcrumb/index.d.ts +25 -0
- package/dist/breadcrumb/index.js +47 -0
- package/dist/breadcrumb/style.css +35 -0
- package/dist/button/index.d.ts +34 -0
- package/dist/button/index.js +57 -0
- package/dist/button/style.css +133 -0
- package/dist/card/index.d.ts +25 -0
- package/dist/card/index.js +29 -0
- package/dist/card/style.css +23 -0
- package/dist/collapse/index.d.ts +89 -0
- package/dist/collapse/index.js +213 -0
- package/dist/collapse/style.css +76 -0
- package/dist/context-menu/context-menu.d.ts +113 -0
- package/dist/context-menu/context-menu.js +150 -0
- package/dist/context-menu/index.d.ts +30 -0
- package/dist/context-menu/index.js +42 -0
- package/dist/context-menu/style.css +46 -0
- package/dist/date-picker/calendar-panel.d.ts +44 -0
- package/dist/date-picker/calendar-panel.js +180 -0
- package/dist/date-picker/date-picker.d.ts +29 -0
- package/dist/date-picker/date-picker.js +81 -0
- package/dist/date-picker/date-utils.d.ts +63 -0
- package/dist/date-picker/date-utils.js +130 -0
- package/dist/date-picker/index.d.ts +7 -0
- package/dist/date-picker/index.js +5 -0
- package/dist/date-picker/layer.d.ts +19 -0
- package/dist/date-picker/layer.js +36 -0
- package/dist/date-picker/range-picker.d.ts +30 -0
- package/dist/date-picker/range-picker.js +117 -0
- package/dist/date-picker/style.css +161 -0
- package/dist/description-list/index.d.ts +37 -0
- package/dist/description-list/index.js +145 -0
- package/dist/description-list/style.css +63 -0
- package/dist/divider/index.d.ts +29 -0
- package/dist/divider/index.js +29 -0
- package/dist/divider/style.css +50 -0
- package/dist/drawer/index.d.ts +51 -0
- package/dist/drawer/index.js +183 -0
- package/dist/drawer/style.css +100 -0
- package/dist/dropdown/index.d.ts +38 -0
- package/dist/dropdown/index.js +97 -0
- package/dist/dropdown/style.css +39 -0
- package/dist/empty/index.d.ts +11 -0
- package/dist/empty/index.js +20 -0
- package/dist/empty/style.css +19 -0
- package/dist/floating-layer/index.d.ts +109 -0
- package/dist/floating-layer/index.js +337 -0
- package/dist/floating-layer/style.css +5 -0
- package/dist/form/form-item/index.d.ts +26 -0
- package/dist/form/form-item/index.js +21 -0
- package/dist/form/form-item/style.css +33 -0
- package/dist/form/form-modal/index.d.ts +18 -0
- package/dist/form/form-modal/index.js +38 -0
- package/dist/form/form.d.ts +21 -0
- package/dist/form/form.js +28 -0
- package/dist/form/index.d.ts +4 -0
- package/dist/form/index.js +4 -0
- package/dist/form/select/index.d.ts +48 -0
- package/dist/form/select/index.js +94 -0
- package/dist/form/select/style.css +29 -0
- package/dist/global.css +71 -0
- package/dist/i18n/de-DE.d.ts +2 -0
- package/dist/i18n/de-DE.js +36 -0
- package/dist/i18n/en-US.d.ts +2 -0
- package/dist/i18n/en-US.js +36 -0
- package/dist/i18n/es-ES.d.ts +2 -0
- package/dist/i18n/es-ES.js +36 -0
- package/dist/i18n/fr-FR.d.ts +2 -0
- package/dist/i18n/fr-FR.js +36 -0
- package/dist/i18n/index.d.ts +12 -0
- package/dist/i18n/index.js +39 -0
- package/dist/i18n/ja-JP.d.ts +2 -0
- package/dist/i18n/ja-JP.js +36 -0
- package/dist/i18n/ko-KR.d.ts +2 -0
- package/dist/i18n/ko-KR.js +36 -0
- package/dist/i18n/messages.d.ts +40 -0
- package/dist/i18n/messages.js +1 -0
- package/dist/i18n/wok-ui/de-DE.d.ts +2 -0
- package/dist/i18n/wok-ui/de-DE.js +20 -0
- package/dist/i18n/wok-ui/es-ES.d.ts +2 -0
- package/dist/i18n/wok-ui/es-ES.js +20 -0
- package/dist/i18n/wok-ui/fr-FR.d.ts +2 -0
- package/dist/i18n/wok-ui/fr-FR.js +20 -0
- package/dist/i18n/wok-ui/ja-JP.d.ts +2 -0
- package/dist/i18n/wok-ui/ja-JP.js +20 -0
- package/dist/i18n/wok-ui/ko-KR.d.ts +2 -0
- package/dist/i18n/wok-ui/ko-KR.js +20 -0
- package/dist/i18n/wok-ui/zh-TW.d.ts +2 -0
- package/dist/i18n/wok-ui/zh-TW.js +20 -0
- package/dist/i18n/zh-CN.d.ts +2 -0
- package/dist/i18n/zh-CN.js +36 -0
- package/dist/i18n/zh-TW.d.ts +2 -0
- package/dist/i18n/zh-TW.js +36 -0
- package/dist/icons.d.ts +88 -0
- package/dist/icons.js +176 -0
- package/dist/image/index.d.ts +38 -0
- package/dist/image/index.js +97 -0
- package/dist/image/style.css +72 -0
- package/dist/image-preview/index.d.ts +26 -0
- package/dist/image-preview/index.js +134 -0
- package/dist/image-preview/style.css +96 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +45 -0
- package/dist/list/index.d.ts +32 -0
- package/dist/list/index.js +42 -0
- package/dist/list/list-item.d.ts +27 -0
- package/dist/list/list-item.js +51 -0
- package/dist/list/style.css +20 -0
- package/dist/loading/index.d.ts +10 -0
- package/dist/loading/index.js +46 -0
- package/dist/loading/style.css +48 -0
- package/dist/menu/index.d.ts +38 -0
- package/dist/menu/index.js +62 -0
- package/dist/menu/leaf-item.d.ts +12 -0
- package/dist/menu/leaf-item.js +41 -0
- package/dist/menu/style.css +117 -0
- package/dist/menu/sub-menu.d.ts +21 -0
- package/dist/menu/sub-menu.js +85 -0
- package/dist/menu/types.d.ts +36 -0
- package/dist/menu/types.js +1 -0
- package/dist/menu/utils.d.ts +11 -0
- package/dist/menu/utils.js +24 -0
- package/dist/modal/index.d.ts +23 -0
- package/dist/modal/index.js +79 -0
- package/dist/modal/modal.d.ts +76 -0
- package/dist/modal/modal.js +188 -0
- package/dist/modal/style.css +90 -0
- package/dist/pagination/index.d.ts +31 -0
- package/dist/pagination/index.js +215 -0
- package/dist/pagination/style.css +50 -0
- package/dist/popconfirm/api.d.ts +43 -0
- package/dist/popconfirm/api.js +77 -0
- package/dist/popconfirm/component.d.ts +47 -0
- package/dist/popconfirm/component.js +48 -0
- package/dist/popconfirm/index.d.ts +3 -0
- package/dist/popconfirm/index.js +3 -0
- package/dist/popconfirm/style.css +22 -0
- package/dist/popover/api.d.ts +36 -0
- package/dist/popover/api.js +61 -0
- package/dist/popover/component.d.ts +38 -0
- package/dist/popover/component.js +51 -0
- package/dist/popover/index.d.ts +3 -0
- package/dist/popover/index.js +3 -0
- package/dist/popover/style.css +102 -0
- package/dist/progress/index.d.ts +34 -0
- package/dist/progress/index.js +70 -0
- package/dist/progress/style.css +37 -0
- package/dist/quick-input/index.d.ts +2 -0
- package/dist/quick-input/index.js +2 -0
- package/dist/quick-input/number.d.ts +35 -0
- package/dist/quick-input/number.js +68 -0
- package/dist/quick-input/text.d.ts +20 -0
- package/dist/quick-input/text.js +61 -0
- package/dist/result/index.d.ts +39 -0
- package/dist/result/index.js +71 -0
- package/dist/result/style.css +41 -0
- package/dist/search-box/index.d.ts +26 -0
- package/dist/search-box/index.js +60 -0
- package/dist/search-box/style.css +22 -0
- package/dist/segmented/index.d.ts +42 -0
- package/dist/segmented/index.js +61 -0
- package/dist/segmented/style.css +28 -0
- package/dist/skeleton/index.d.ts +22 -0
- package/dist/skeleton/index.js +68 -0
- package/dist/skeleton/style.css +31 -0
- package/dist/steps/index.d.ts +46 -0
- package/dist/steps/index.js +95 -0
- package/dist/steps/style.css +181 -0
- package/dist/switch/index.d.ts +32 -0
- package/dist/switch/index.js +74 -0
- package/dist/switch/style.css +52 -0
- package/dist/table/body.d.ts +21 -0
- package/dist/table/body.js +35 -0
- package/dist/table/column.d.ts +78 -0
- package/dist/table/column.js +113 -0
- package/dist/table/header.d.ts +13 -0
- package/dist/table/header.js +15 -0
- package/dist/table/index.d.ts +41 -0
- package/dist/table/index.js +84 -0
- package/dist/table/row.d.ts +25 -0
- package/dist/table/row.js +74 -0
- package/dist/table/style.css +98 -0
- package/dist/tabs/index.d.ts +49 -0
- package/dist/tabs/index.js +76 -0
- package/dist/tabs/style.css +41 -0
- package/dist/tag/index.d.ts +53 -0
- package/dist/tag/index.js +100 -0
- package/dist/tag/style.css +134 -0
- package/dist/text/index.d.ts +104 -0
- package/dist/text/index.js +143 -0
- package/dist/text/style.css +113 -0
- package/dist/theme/index.d.ts +14 -0
- package/dist/theme/index.js +94 -0
- package/dist/theme/themes.d.ts +3 -0
- package/dist/theme/themes.js +323 -0
- package/dist/theme/types.d.ts +58 -0
- package/dist/theme/types.js +1 -0
- package/dist/timeline/index.d.ts +28 -0
- package/dist/timeline/index.js +35 -0
- package/dist/timeline/style.css +53 -0
- package/dist/toast/index.d.ts +53 -0
- package/dist/toast/index.js +131 -0
- package/dist/toast/style.css +76 -0
- package/dist/tooltip/api.d.ts +44 -0
- package/dist/tooltip/api.js +103 -0
- package/dist/tooltip/component.d.ts +28 -0
- package/dist/tooltip/component.js +35 -0
- package/dist/tooltip/index.d.ts +3 -0
- package/dist/tooltip/index.js +3 -0
- package/dist/tooltip/style.css +46 -0
- package/dist/tree/dragging-img.d.ts +13 -0
- package/dist/tree/dragging-img.js +23 -0
- package/dist/tree/index.d.ts +180 -0
- package/dist/tree/index.js +385 -0
- package/dist/tree/node-info.d.ts +63 -0
- package/dist/tree/node-info.js +128 -0
- package/dist/tree/node.d.ts +132 -0
- package/dist/tree/node.js +264 -0
- package/dist/tree/style.css +99 -0
- package/dist/upload/index.d.ts +48 -0
- package/dist/upload/index.js +141 -0
- package/dist/upload/style.css +41 -0
- package/package.json +51 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DivModule } from 'wok-ui';
|
|
2
|
+
import './style.less';
|
|
3
|
+
export interface ImageOptions {
|
|
4
|
+
src: string;
|
|
5
|
+
alt?: string;
|
|
6
|
+
/** object-fit 属性,默认 cover */
|
|
7
|
+
fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down';
|
|
8
|
+
width?: number | string;
|
|
9
|
+
height?: number | string;
|
|
10
|
+
/** 加载失败时的兜底图片 */
|
|
11
|
+
fallbackSrc?: string;
|
|
12
|
+
/** 点击回调 */
|
|
13
|
+
onClick?: () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 图片组件
|
|
17
|
+
*
|
|
18
|
+
* 支持加载中占位、加载失败兜底、object-fit 控制。
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* new Image({
|
|
23
|
+
* src: 'https://example.com/photo.jpg',
|
|
24
|
+
* fit: 'cover',
|
|
25
|
+
* width: 200,
|
|
26
|
+
* height: 150,
|
|
27
|
+
* fallbackSrc: '/assets/fallback.png',
|
|
28
|
+
* onClick: () => previewImage([{ src: 'https://...' }])
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare class Image extends DivModule {
|
|
33
|
+
private opts;
|
|
34
|
+
constructor(opts: ImageOptions);
|
|
35
|
+
private handleError;
|
|
36
|
+
/** 更新图片 src */
|
|
37
|
+
setSrc(src: string): void;
|
|
38
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { DivModule } from 'wok-ui';
|
|
2
|
+
import './style.css';
|
|
3
|
+
import { IconCircleNotch, IconImage } from '../icons';
|
|
4
|
+
/**
|
|
5
|
+
* 图片组件
|
|
6
|
+
*
|
|
7
|
+
* 支持加载中占位、加载失败兜底、object-fit 控制。
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* new Image({
|
|
12
|
+
* src: 'https://example.com/photo.jpg',
|
|
13
|
+
* fit: 'cover',
|
|
14
|
+
* width: 200,
|
|
15
|
+
* height: 150,
|
|
16
|
+
* fallbackSrc: '/assets/fallback.png',
|
|
17
|
+
* onClick: () => previewImage([{ src: 'https://...' }])
|
|
18
|
+
* })
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export class Image extends DivModule {
|
|
22
|
+
constructor(opts) {
|
|
23
|
+
super('wok-ui-ext-image');
|
|
24
|
+
this.opts = opts;
|
|
25
|
+
const { src, alt, fit, width, height, onClick } = opts;
|
|
26
|
+
// 尺寸
|
|
27
|
+
if (width) {
|
|
28
|
+
this.el.style.width = typeof width === 'number' ? `${width}px` : width;
|
|
29
|
+
}
|
|
30
|
+
if (height) {
|
|
31
|
+
this.el.style.height = typeof height === 'number' ? `${height}px` : height;
|
|
32
|
+
}
|
|
33
|
+
// 点击
|
|
34
|
+
if (onClick) {
|
|
35
|
+
this.el.addEventListener('click', onClick);
|
|
36
|
+
this.el.style.cursor = 'pointer';
|
|
37
|
+
}
|
|
38
|
+
// 加载中占位(默认可见)
|
|
39
|
+
this.addChild({
|
|
40
|
+
classNames: ['wok-ui-ext-image-placeholder'],
|
|
41
|
+
children: new IconCircleNotch()
|
|
42
|
+
});
|
|
43
|
+
// 加载失败占位(默认隐藏)
|
|
44
|
+
this.addChild({
|
|
45
|
+
classNames: ['wok-ui-ext-image-error'],
|
|
46
|
+
children: new IconImage()
|
|
47
|
+
});
|
|
48
|
+
// 真实图片
|
|
49
|
+
this.addChild({
|
|
50
|
+
tag: 'img',
|
|
51
|
+
classNames: ['wok-ui-ext-image-img'],
|
|
52
|
+
attrs: {
|
|
53
|
+
src,
|
|
54
|
+
alt: alt ?? ''
|
|
55
|
+
},
|
|
56
|
+
style: {
|
|
57
|
+
objectFit: fit || undefined
|
|
58
|
+
},
|
|
59
|
+
preHandle: el => {
|
|
60
|
+
const img = el;
|
|
61
|
+
img.addEventListener('load', () => {
|
|
62
|
+
this.el.classList.add('loaded');
|
|
63
|
+
});
|
|
64
|
+
img.addEventListener('error', () => {
|
|
65
|
+
this.handleError();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
handleError() {
|
|
71
|
+
if (this.opts.fallbackSrc) {
|
|
72
|
+
// 有 fallbackSrc,替换 img 的 src 再试一次
|
|
73
|
+
const imgEl = this.el.querySelector('img');
|
|
74
|
+
if (imgEl) {
|
|
75
|
+
imgEl.src = this.opts.fallbackSrc;
|
|
76
|
+
// fallback 也失败则显示错误状态
|
|
77
|
+
imgEl.addEventListener('error', () => {
|
|
78
|
+
this.el.classList.add('error');
|
|
79
|
+
});
|
|
80
|
+
imgEl.addEventListener('load', () => {
|
|
81
|
+
this.el.classList.add('loaded');
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.el.classList.add('error');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** 更新图片 src */
|
|
90
|
+
setSrc(src) {
|
|
91
|
+
this.el.classList.remove('loaded', 'error');
|
|
92
|
+
const imgEl = this.el.querySelector('img');
|
|
93
|
+
if (imgEl) {
|
|
94
|
+
imgEl.src = src;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
.wok-ui-ext-image {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
background: var(--bg-base);
|
|
8
|
+
border-radius: var(--radius-sm);
|
|
9
|
+
min-width: 40px;
|
|
10
|
+
min-height: 40px;
|
|
11
|
+
}
|
|
12
|
+
.wok-ui-ext-image .wok-ui-ext-image-placeholder {
|
|
13
|
+
position: absolute;
|
|
14
|
+
inset: 0;
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
color: var(--text-tertiary);
|
|
19
|
+
font-size: 24px;
|
|
20
|
+
opacity: 1;
|
|
21
|
+
transition: opacity 0.2s;
|
|
22
|
+
z-index: 1;
|
|
23
|
+
}
|
|
24
|
+
.wok-ui-ext-image .wok-ui-ext-image-placeholder svg.spin {
|
|
25
|
+
animation: image-spin 1s linear infinite;
|
|
26
|
+
}
|
|
27
|
+
.wok-ui-ext-image .wok-ui-ext-image-error {
|
|
28
|
+
position: absolute;
|
|
29
|
+
inset: 0;
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
background: var(--bg-card);
|
|
34
|
+
color: var(--text-tertiary);
|
|
35
|
+
font-size: 32px;
|
|
36
|
+
opacity: 0;
|
|
37
|
+
transition: opacity 0.2s;
|
|
38
|
+
z-index: 1;
|
|
39
|
+
}
|
|
40
|
+
.wok-ui-ext-image .wok-ui-ext-image-img {
|
|
41
|
+
width: 100%;
|
|
42
|
+
height: 100%;
|
|
43
|
+
object-fit: cover;
|
|
44
|
+
opacity: 0;
|
|
45
|
+
transition: opacity 0.2s;
|
|
46
|
+
z-index: 2;
|
|
47
|
+
}
|
|
48
|
+
.wok-ui-ext-image.loaded .wok-ui-ext-image-placeholder {
|
|
49
|
+
opacity: 0;
|
|
50
|
+
pointer-events: none;
|
|
51
|
+
}
|
|
52
|
+
.wok-ui-ext-image.loaded .wok-ui-ext-image-img {
|
|
53
|
+
opacity: 1;
|
|
54
|
+
}
|
|
55
|
+
.wok-ui-ext-image.error .wok-ui-ext-image-placeholder {
|
|
56
|
+
opacity: 0;
|
|
57
|
+
pointer-events: none;
|
|
58
|
+
}
|
|
59
|
+
.wok-ui-ext-image.error .wok-ui-ext-image-img {
|
|
60
|
+
opacity: 0;
|
|
61
|
+
}
|
|
62
|
+
.wok-ui-ext-image.error .wok-ui-ext-image-error {
|
|
63
|
+
opacity: 1;
|
|
64
|
+
}
|
|
65
|
+
@keyframes image-spin {
|
|
66
|
+
from {
|
|
67
|
+
transform: rotate(0deg);
|
|
68
|
+
}
|
|
69
|
+
to {
|
|
70
|
+
transform: rotate(360deg);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import './style.less';
|
|
2
|
+
export interface ImagePreviewItem {
|
|
3
|
+
src: string;
|
|
4
|
+
alt?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* 打开图片预览
|
|
8
|
+
*
|
|
9
|
+
* 全屏遮罩查看图片,支持单张/多张预览、键盘导航。
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // 单张预览
|
|
14
|
+
* previewImage({ src: 'https://...' })
|
|
15
|
+
*
|
|
16
|
+
* // 多张预览
|
|
17
|
+
* previewImage([
|
|
18
|
+
* { src: 'https://...', alt: '图1' },
|
|
19
|
+
* { src: 'https://...', alt: '图2' }
|
|
20
|
+
* ])
|
|
21
|
+
*
|
|
22
|
+
* // 指定初始索引
|
|
23
|
+
* previewImage(images, 2)
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function previewImage(images: ImagePreviewItem | ImagePreviewItem[], initialIndex?: number): void;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { FullRenderingModule } from 'wok-ui';
|
|
2
|
+
import { showModal } from '../modal';
|
|
3
|
+
import { IconChevronLeft, IconChevronRight, IconTimes } from '../icons';
|
|
4
|
+
import './style.css';
|
|
5
|
+
/**
|
|
6
|
+
* 图片预览模块
|
|
7
|
+
*
|
|
8
|
+
* 渲染图片、页码与导航控件,键盘导航和遮罩点击关闭等监听在模块生命周期内管理。
|
|
9
|
+
*/
|
|
10
|
+
class ImagePreview extends FullRenderingModule {
|
|
11
|
+
constructor(list, initialIndex, onClose) {
|
|
12
|
+
super('wok-ui-ext-preview');
|
|
13
|
+
this.list = list;
|
|
14
|
+
this.onClose = onClose;
|
|
15
|
+
this.currentIdx = initialIndex;
|
|
16
|
+
this.render();
|
|
17
|
+
}
|
|
18
|
+
buildContent() {
|
|
19
|
+
// 关闭按钮(右上角 X)
|
|
20
|
+
this.addChild({
|
|
21
|
+
tag: 'button',
|
|
22
|
+
classNames: ['wok-ui-ext-preview-close'],
|
|
23
|
+
attrs: { 'aria-label': 'Close preview' },
|
|
24
|
+
children: new IconTimes(),
|
|
25
|
+
onClick: () => this.onClose()
|
|
26
|
+
});
|
|
27
|
+
// 图片容器
|
|
28
|
+
this.addChild({
|
|
29
|
+
classNames: ['wok-ui-ext-preview-body'],
|
|
30
|
+
children: add => {
|
|
31
|
+
if (this.list.length > 1) {
|
|
32
|
+
add({
|
|
33
|
+
classNames: ['wok-ui-ext-preview-counter'],
|
|
34
|
+
children: `${this.currentIdx + 1} / ${this.list.length}`
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
add({
|
|
38
|
+
tag: 'img',
|
|
39
|
+
classNames: ['wok-ui-ext-preview-img'],
|
|
40
|
+
attrs: {
|
|
41
|
+
src: this.list[this.currentIdx].src,
|
|
42
|
+
alt: this.list[this.currentIdx].alt ?? ''
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
// 左右导航箭头
|
|
48
|
+
if (this.list.length > 1) {
|
|
49
|
+
this.addChild({
|
|
50
|
+
tag: 'button',
|
|
51
|
+
classNames: ['wok-ui-ext-preview-nav', 'wok-ui-ext-preview-nav-prev'],
|
|
52
|
+
attrs: { 'aria-label': 'Previous image' },
|
|
53
|
+
children: new IconChevronLeft(),
|
|
54
|
+
onClick: () => this.navigate(-1)
|
|
55
|
+
}, {
|
|
56
|
+
tag: 'button',
|
|
57
|
+
classNames: ['wok-ui-ext-preview-nav', 'wok-ui-ext-preview-nav-next'],
|
|
58
|
+
attrs: { 'aria-label': 'Next image' },
|
|
59
|
+
children: new IconChevronRight(),
|
|
60
|
+
onClick: () => this.navigate(1)
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
navigate(dir) {
|
|
65
|
+
const next = this.currentIdx + dir;
|
|
66
|
+
if (next < 0 || next >= this.list.length)
|
|
67
|
+
return;
|
|
68
|
+
this.currentIdx = next;
|
|
69
|
+
this.render();
|
|
70
|
+
}
|
|
71
|
+
mount(parentEl) {
|
|
72
|
+
super.mount(parentEl);
|
|
73
|
+
// 键盘左右方向键导航
|
|
74
|
+
this.keydownListener = (e) => {
|
|
75
|
+
if (e.key === 'ArrowLeft') {
|
|
76
|
+
this.navigate(-1);
|
|
77
|
+
}
|
|
78
|
+
else if (e.key === 'ArrowRight') {
|
|
79
|
+
this.navigate(1);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
document.addEventListener('keydown', this.keydownListener);
|
|
83
|
+
// 点击遮罩关闭:容器(preview-active)占满全屏,点击容器空白区域即视为点击遮罩
|
|
84
|
+
const container = this.el.parentElement;
|
|
85
|
+
if (container) {
|
|
86
|
+
this.containerClickListener = (e) => {
|
|
87
|
+
if (e.target === container) {
|
|
88
|
+
this.onClose();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
container.addEventListener('click', this.containerClickListener);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
destroy() {
|
|
95
|
+
if (this.keydownListener) {
|
|
96
|
+
document.removeEventListener('keydown', this.keydownListener);
|
|
97
|
+
this.keydownListener = undefined;
|
|
98
|
+
}
|
|
99
|
+
if (this.containerClickListener) {
|
|
100
|
+
const container = this.el.parentElement;
|
|
101
|
+
container?.removeEventListener('click', this.containerClickListener);
|
|
102
|
+
this.containerClickListener = undefined;
|
|
103
|
+
}
|
|
104
|
+
super.destroy();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 打开图片预览
|
|
109
|
+
*
|
|
110
|
+
* 全屏遮罩查看图片,支持单张/多张预览、键盘导航。
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* // 单张预览
|
|
115
|
+
* previewImage({ src: 'https://...' })
|
|
116
|
+
*
|
|
117
|
+
* // 多张预览
|
|
118
|
+
* previewImage([
|
|
119
|
+
* { src: 'https://...', alt: '图1' },
|
|
120
|
+
* { src: 'https://...', alt: '图2' }
|
|
121
|
+
* ])
|
|
122
|
+
*
|
|
123
|
+
* // 指定初始索引
|
|
124
|
+
* previewImage(images, 2)
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export function previewImage(images, initialIndex) {
|
|
128
|
+
const list = Array.isArray(images) ? images : [images];
|
|
129
|
+
const handle = showModal({
|
|
130
|
+
replaceByBody: true,
|
|
131
|
+
className: 'wok-ui-ext-preview-active',
|
|
132
|
+
body: new ImagePreview(list, initialIndex ?? 0, () => handle.close())
|
|
133
|
+
});
|
|
134
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
.wok-ui-ext-modal-overlay .wok-ui-ext-modal-container.wok-ui-ext-preview-active {
|
|
2
|
+
max-width: none;
|
|
3
|
+
width: 100vw;
|
|
4
|
+
height: 100vh;
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
position: relative;
|
|
9
|
+
}
|
|
10
|
+
.wok-ui-ext-preview-close {
|
|
11
|
+
position: absolute;
|
|
12
|
+
top: 20px;
|
|
13
|
+
right: 20px;
|
|
14
|
+
z-index: 10;
|
|
15
|
+
width: 40px;
|
|
16
|
+
height: 40px;
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
border: none;
|
|
21
|
+
background: rgba(255, 255, 255, 0.1);
|
|
22
|
+
border-radius: 50%;
|
|
23
|
+
color: white;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
transition: background 0.15s;
|
|
26
|
+
font-size: 20px;
|
|
27
|
+
}
|
|
28
|
+
.wok-ui-ext-preview-close:hover {
|
|
29
|
+
background: rgba(255, 255, 255, 0.25);
|
|
30
|
+
}
|
|
31
|
+
.wok-ui-ext-preview-close svg {
|
|
32
|
+
width: 20px;
|
|
33
|
+
height: 20px;
|
|
34
|
+
}
|
|
35
|
+
.wok-ui-ext-preview-body {
|
|
36
|
+
display: flex;
|
|
37
|
+
flex-direction: column;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: center;
|
|
40
|
+
width: 100%;
|
|
41
|
+
height: 100%;
|
|
42
|
+
}
|
|
43
|
+
.wok-ui-ext-preview-counter {
|
|
44
|
+
margin-bottom: 12px;
|
|
45
|
+
color: rgba(255, 255, 255, 0.7);
|
|
46
|
+
font-size: 14px;
|
|
47
|
+
user-select: none;
|
|
48
|
+
}
|
|
49
|
+
.wok-ui-ext-preview-img {
|
|
50
|
+
max-width: 100%;
|
|
51
|
+
max-height: 100%;
|
|
52
|
+
object-fit: contain;
|
|
53
|
+
animation: wok-ui-ext-preview-zoom-in 0.25s ease;
|
|
54
|
+
user-select: none;
|
|
55
|
+
}
|
|
56
|
+
.wok-ui-ext-preview-nav {
|
|
57
|
+
position: absolute;
|
|
58
|
+
top: 50%;
|
|
59
|
+
transform: translateY(-50%);
|
|
60
|
+
z-index: 10;
|
|
61
|
+
width: 48px;
|
|
62
|
+
height: 48px;
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
justify-content: center;
|
|
66
|
+
border: none;
|
|
67
|
+
background: rgba(255, 255, 255, 0.1);
|
|
68
|
+
border-radius: 50%;
|
|
69
|
+
color: white;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
transition: background 0.15s;
|
|
72
|
+
font-size: 24px;
|
|
73
|
+
}
|
|
74
|
+
.wok-ui-ext-preview-nav:hover {
|
|
75
|
+
background: rgba(255, 255, 255, 0.25);
|
|
76
|
+
}
|
|
77
|
+
.wok-ui-ext-preview-nav svg {
|
|
78
|
+
width: 24px;
|
|
79
|
+
height: 24px;
|
|
80
|
+
}
|
|
81
|
+
.wok-ui-ext-preview-nav-prev {
|
|
82
|
+
left: 20px;
|
|
83
|
+
}
|
|
84
|
+
.wok-ui-ext-preview-nav-next {
|
|
85
|
+
right: 20px;
|
|
86
|
+
}
|
|
87
|
+
@keyframes wok-ui-ext-preview-zoom-in {
|
|
88
|
+
from {
|
|
89
|
+
opacity: 0;
|
|
90
|
+
transform: scale(0.95);
|
|
91
|
+
}
|
|
92
|
+
to {
|
|
93
|
+
opacity: 1;
|
|
94
|
+
transform: scale(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export * from './card';
|
|
2
|
+
export * from './pagination';
|
|
3
|
+
export * from './dropdown';
|
|
4
|
+
export * from './tag';
|
|
5
|
+
export * from './badge';
|
|
6
|
+
export * from './button';
|
|
7
|
+
export * from './switch';
|
|
8
|
+
export * from './empty';
|
|
9
|
+
export * from './tooltip';
|
|
10
|
+
export * from './avatar';
|
|
11
|
+
export * from './skeleton';
|
|
12
|
+
export * from './progress';
|
|
13
|
+
export * from './segmented';
|
|
14
|
+
export * from './toast';
|
|
15
|
+
export * from './form';
|
|
16
|
+
export * from './upload';
|
|
17
|
+
export * from './table';
|
|
18
|
+
export * from './tabs';
|
|
19
|
+
export * from './quick-input';
|
|
20
|
+
export * from './modal';
|
|
21
|
+
export * from './description-list';
|
|
22
|
+
export * from './tree';
|
|
23
|
+
export * from './context-menu';
|
|
24
|
+
export * from './divider';
|
|
25
|
+
export * from './date-picker';
|
|
26
|
+
export * from './image';
|
|
27
|
+
export * from './image-preview';
|
|
28
|
+
export * from './loading';
|
|
29
|
+
export * from './search-box';
|
|
30
|
+
export * from './steps';
|
|
31
|
+
export * from './text';
|
|
32
|
+
export * from './alert';
|
|
33
|
+
export * from './breadcrumb';
|
|
34
|
+
export * from './timeline';
|
|
35
|
+
export * from './drawer';
|
|
36
|
+
export * from './menu';
|
|
37
|
+
export * from './floating-layer';
|
|
38
|
+
export * from './popover';
|
|
39
|
+
export * from './popconfirm';
|
|
40
|
+
export * from './collapse';
|
|
41
|
+
export * from './list';
|
|
42
|
+
export * from './result';
|
|
43
|
+
export * from './icons';
|
|
44
|
+
export * from './theme';
|
|
45
|
+
export { getWokUiExtI18n } from './i18n';
|
|
46
|
+
export type { WokUiExtI18nMessages } from './i18n';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export * from './card';
|
|
2
|
+
export * from './pagination';
|
|
3
|
+
export * from './dropdown';
|
|
4
|
+
export * from './tag';
|
|
5
|
+
export * from './badge';
|
|
6
|
+
export * from './button';
|
|
7
|
+
export * from './switch';
|
|
8
|
+
export * from './empty';
|
|
9
|
+
export * from './tooltip';
|
|
10
|
+
export * from './avatar';
|
|
11
|
+
export * from './skeleton';
|
|
12
|
+
export * from './progress';
|
|
13
|
+
export * from './segmented';
|
|
14
|
+
export * from './toast';
|
|
15
|
+
export * from './form';
|
|
16
|
+
export * from './upload';
|
|
17
|
+
export * from './table';
|
|
18
|
+
export * from './tabs';
|
|
19
|
+
export * from './quick-input';
|
|
20
|
+
export * from './modal';
|
|
21
|
+
export * from './description-list';
|
|
22
|
+
export * from './tree';
|
|
23
|
+
export * from './context-menu';
|
|
24
|
+
export * from './divider';
|
|
25
|
+
export * from './date-picker';
|
|
26
|
+
export * from './image';
|
|
27
|
+
export * from './image-preview';
|
|
28
|
+
export * from './loading';
|
|
29
|
+
export * from './search-box';
|
|
30
|
+
export * from './steps';
|
|
31
|
+
export * from './text';
|
|
32
|
+
export * from './alert';
|
|
33
|
+
export * from './breadcrumb';
|
|
34
|
+
export * from './timeline';
|
|
35
|
+
export * from './drawer';
|
|
36
|
+
export * from './menu';
|
|
37
|
+
export * from './floating-layer';
|
|
38
|
+
export * from './popover';
|
|
39
|
+
export * from './popconfirm';
|
|
40
|
+
export * from './collapse';
|
|
41
|
+
export * from './list';
|
|
42
|
+
export * from './result';
|
|
43
|
+
export * from './icons';
|
|
44
|
+
export * from './theme';
|
|
45
|
+
export { getWokUiExtI18n } from './i18n';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DivModule, SubModulesOpt } from 'wok-ui';
|
|
2
|
+
import './style.less';
|
|
3
|
+
export interface ListOptions {
|
|
4
|
+
/** 列表项 */
|
|
5
|
+
items: SubModulesOpt[];
|
|
6
|
+
/** 空状态文案 */
|
|
7
|
+
emptyText?: string;
|
|
8
|
+
/** 是否带边框,默认为 true,传 false 关闭边框 */
|
|
9
|
+
bordered?: boolean;
|
|
10
|
+
/** 尺寸 */
|
|
11
|
+
size?: 'default' | 'small' | 'large';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 通用数据列表
|
|
15
|
+
*
|
|
16
|
+
* 轻量级的数据展示列表,适合作为 Table 的替代方案。
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* new List({
|
|
21
|
+
* items: users.map(user => new ListItem({
|
|
22
|
+
* title: user.name,
|
|
23
|
+
* description: user.email
|
|
24
|
+
* })),
|
|
25
|
+
* bordered: true,
|
|
26
|
+
* size: 'small'
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare class List extends DivModule {
|
|
31
|
+
constructor(opts: ListOptions);
|
|
32
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DivModule } from 'wok-ui';
|
|
2
|
+
import { Empty } from '../empty';
|
|
3
|
+
import './style.css';
|
|
4
|
+
/**
|
|
5
|
+
* 通用数据列表
|
|
6
|
+
*
|
|
7
|
+
* 轻量级的数据展示列表,适合作为 Table 的替代方案。
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* new List({
|
|
12
|
+
* items: users.map(user => new ListItem({
|
|
13
|
+
* title: user.name,
|
|
14
|
+
* description: user.email
|
|
15
|
+
* })),
|
|
16
|
+
* bordered: true,
|
|
17
|
+
* size: 'small'
|
|
18
|
+
* })
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export class List extends DivModule {
|
|
22
|
+
constructor(opts) {
|
|
23
|
+
super('wok-ui-ext-list');
|
|
24
|
+
// 默认带边框,传 bordered: false 关闭边框
|
|
25
|
+
if (opts.bordered !== false) {
|
|
26
|
+
this.el.classList.add('bordered');
|
|
27
|
+
}
|
|
28
|
+
if (opts.size && opts.size !== 'default') {
|
|
29
|
+
this.el.classList.add(opts.size);
|
|
30
|
+
}
|
|
31
|
+
if (!opts.items || opts.items.length === 0) {
|
|
32
|
+
this.addChild(new Empty({ text: opts.emptyText, noBorder: true }));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
opts.items.forEach(item => {
|
|
36
|
+
this.addChild({
|
|
37
|
+
classNames: 'wok-ui-ext-list-item',
|
|
38
|
+
children: item
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DivModule, SubModulesOpt } from 'wok-ui';
|
|
2
|
+
export interface ListItemOptions {
|
|
3
|
+
/** 标题 */
|
|
4
|
+
title: string | SubModulesOpt;
|
|
5
|
+
/** 描述(可选) */
|
|
6
|
+
description?: string | SubModulesOpt;
|
|
7
|
+
/** 右侧额外内容 */
|
|
8
|
+
extra?: SubModulesOpt;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 列表项
|
|
12
|
+
*
|
|
13
|
+
* 配合 List 使用的标准列表项,包含标题、描述和额外操作区。
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* new ListItem({
|
|
18
|
+
* title: '用户名称',
|
|
19
|
+
* description: 'user@example.com',
|
|
20
|
+
* extra: new Tag({ text: '管理员' })
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class ListItem extends DivModule {
|
|
25
|
+
private opts;
|
|
26
|
+
constructor(opts: ListItemOptions);
|
|
27
|
+
}
|