@chenzy-design/core 0.3.1 → 0.4.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/dist/ai-chat-dialogue.d.ts +300 -0
- package/dist/ai-chat-dialogue.d.ts.map +1 -0
- package/dist/ai-chat-dialogue.js +699 -0
- package/dist/ai-chat-dialogue.js.map +1 -0
- package/dist/ai-chat-dialogue.test.d.ts +2 -0
- package/dist/ai-chat-dialogue.test.d.ts.map +1 -0
- package/dist/ai-chat-dialogue.test.js +338 -0
- package/dist/ai-chat-dialogue.test.js.map +1 -0
- package/dist/ai-chat-input.d.ts +191 -0
- package/dist/ai-chat-input.d.ts.map +1 -0
- package/dist/ai-chat-input.js +274 -0
- package/dist/ai-chat-input.js.map +1 -0
- package/dist/ai-chat-input.test.d.ts +2 -0
- package/dist/ai-chat-input.test.d.ts.map +1 -0
- package/dist/ai-chat-input.test.js +339 -0
- package/dist/ai-chat-input.test.js.map +1 -0
- package/dist/audio-player.d.ts +154 -0
- package/dist/audio-player.d.ts.map +1 -0
- package/dist/audio-player.js +254 -0
- package/dist/audio-player.js.map +1 -0
- package/dist/audio-player.test.d.ts +2 -0
- package/dist/audio-player.test.d.ts.map +1 -0
- package/dist/audio-player.test.js +275 -0
- package/dist/audio-player.test.js.map +1 -0
- package/dist/back-top.d.ts +4 -1
- package/dist/back-top.d.ts.map +1 -1
- package/dist/back-top.js +5 -2
- package/dist/back-top.js.map +1 -1
- package/dist/back-top.test.js +3 -2
- package/dist/back-top.test.js.map +1 -1
- package/dist/calendar.d.ts +132 -44
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +413 -70
- package/dist/calendar.js.map +1 -1
- package/dist/calendar.test.js +160 -76
- package/dist/calendar.test.js.map +1 -1
- package/dist/chat.d.ts +172 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +210 -0
- package/dist/chat.js.map +1 -0
- package/dist/chat.test.d.ts +2 -0
- package/dist/chat.test.d.ts.map +1 -0
- package/dist/chat.test.js +181 -0
- package/dist/chat.test.js.map +1 -0
- package/dist/code-highlight.d.ts +30 -0
- package/dist/code-highlight.d.ts.map +1 -0
- package/dist/code-highlight.js +37 -0
- package/dist/code-highlight.js.map +1 -0
- package/dist/code-highlight.test.d.ts +2 -0
- package/dist/code-highlight.test.d.ts.map +1 -0
- package/dist/code-highlight.test.js +36 -0
- package/dist/code-highlight.test.js.map +1 -0
- package/dist/collapsible.d.ts +41 -0
- package/dist/collapsible.d.ts.map +1 -0
- package/dist/collapsible.js +33 -0
- package/dist/collapsible.js.map +1 -0
- package/dist/collapsible.test.d.ts +2 -0
- package/dist/collapsible.test.d.ts.map +1 -0
- package/dist/collapsible.test.js +57 -0
- package/dist/collapsible.test.js.map +1 -0
- package/dist/color-value.d.ts +60 -0
- package/dist/color-value.d.ts.map +1 -0
- package/dist/color-value.js +165 -0
- package/dist/color-value.js.map +1 -0
- package/dist/color-value.test.d.ts +2 -0
- package/dist/color-value.test.d.ts.map +1 -0
- package/dist/color-value.test.js +104 -0
- package/dist/color-value.test.js.map +1 -0
- package/dist/config-provider.d.ts +76 -37
- package/dist/config-provider.d.ts.map +1 -1
- package/dist/config-provider.js +107 -32
- package/dist/config-provider.js.map +1 -1
- package/dist/config-provider.test.js +123 -60
- package/dist/config-provider.test.js.map +1 -1
- package/dist/cropper.d.ts +164 -0
- package/dist/cropper.d.ts.map +1 -0
- package/dist/cropper.js +841 -0
- package/dist/cropper.js.map +1 -0
- package/dist/cropper.test.d.ts +2 -0
- package/dist/cropper.test.d.ts.map +1 -0
- package/dist/cropper.test.js +259 -0
- package/dist/cropper.test.js.map +1 -0
- package/dist/drag-move.d.ts +119 -0
- package/dist/drag-move.d.ts.map +1 -0
- package/dist/drag-move.js +237 -0
- package/dist/drag-move.js.map +1 -0
- package/dist/drag-move.test.d.ts +2 -0
- package/dist/drag-move.test.d.ts.map +1 -0
- package/dist/drag-move.test.js +304 -0
- package/dist/drag-move.test.js.map +1 -0
- package/dist/editable.d.ts +24 -4
- package/dist/editable.d.ts.map +1 -1
- package/dist/editable.js +18 -0
- package/dist/editable.js.map +1 -1
- package/dist/editable.test.js +55 -2
- package/dist/editable.test.js.map +1 -1
- package/dist/ellipsis.d.ts +13 -0
- package/dist/ellipsis.d.ts.map +1 -1
- package/dist/ellipsis.js +36 -0
- package/dist/ellipsis.js.map +1 -1
- package/dist/ellipsis.test.js +37 -1
- package/dist/ellipsis.test.js.map +1 -1
- package/dist/form-path.d.ts +19 -0
- package/dist/form-path.d.ts.map +1 -0
- package/dist/form-path.js +97 -0
- package/dist/form-path.js.map +1 -0
- package/dist/form-path.test.d.ts +2 -0
- package/dist/form-path.test.d.ts.map +1 -0
- package/dist/form-path.test.js +57 -0
- package/dist/form-path.test.js.map +1 -0
- package/dist/form-validate.d.ts +13 -0
- package/dist/form-validate.d.ts.map +1 -0
- package/dist/form-validate.js +204 -0
- package/dist/form-validate.js.map +1 -0
- package/dist/form.d.ts +91 -18
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +170 -115
- package/dist/form.js.map +1 -1
- package/dist/form.test.js +349 -76
- package/dist/form.test.js.map +1 -1
- package/dist/highlight.d.ts +42 -32
- package/dist/highlight.d.ts.map +1 -1
- package/dist/highlight.js +67 -41
- package/dist/highlight.js.map +1 -1
- package/dist/highlight.test.js +73 -32
- package/dist/highlight.test.js.map +1 -1
- package/dist/hotkeys.d.ts +151 -0
- package/dist/hotkeys.d.ts.map +1 -0
- package/dist/hotkeys.js +188 -0
- package/dist/hotkeys.js.map +1 -0
- package/dist/hotkeys.test.d.ts +2 -0
- package/dist/hotkeys.test.d.ts.map +1 -0
- package/dist/hotkeys.test.js +170 -0
- package/dist/hotkeys.test.js.map +1 -0
- package/dist/index.d.ts +33 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -13
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +34 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +54 -0
- package/dist/input.js.map +1 -0
- package/dist/input.test.d.ts +2 -0
- package/dist/input.test.d.ts.map +1 -0
- package/dist/input.test.js +56 -0
- package/dist/input.test.js.map +1 -0
- package/dist/markdown-render.d.ts +49 -0
- package/dist/markdown-render.d.ts.map +1 -0
- package/dist/markdown-render.js +61 -0
- package/dist/markdown-render.js.map +1 -0
- package/dist/markdown-render.test.d.ts +2 -0
- package/dist/markdown-render.test.d.ts.map +1 -0
- package/dist/markdown-render.test.js +106 -0
- package/dist/markdown-render.test.js.map +1 -0
- package/dist/notification.d.ts +40 -31
- package/dist/notification.d.ts.map +1 -1
- package/dist/notification.js +86 -70
- package/dist/notification.js.map +1 -1
- package/dist/notification.test.js +62 -39
- package/dist/notification.test.js.map +1 -1
- package/dist/numeral.d.ts +32 -0
- package/dist/numeral.d.ts.map +1 -0
- package/dist/numeral.js +67 -0
- package/dist/numeral.js.map +1 -0
- package/dist/numeral.test.d.ts +2 -0
- package/dist/numeral.test.d.ts.map +1 -0
- package/dist/numeral.test.js +59 -0
- package/dist/numeral.test.js.map +1 -0
- package/dist/overflow-list.d.ts +9 -40
- package/dist/overflow-list.d.ts.map +1 -1
- package/dist/overflow-list.js +9 -70
- package/dist/overflow-list.js.map +1 -1
- package/dist/overflow-list.test.js +1 -122
- package/dist/overflow-list.test.js.map +1 -1
- package/dist/pagination.d.ts +17 -0
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +48 -0
- package/dist/pagination.js.map +1 -1
- package/dist/pagination.test.js +40 -1
- package/dist/pagination.test.js.map +1 -1
- package/dist/pincode.d.ts +79 -0
- package/dist/pincode.d.ts.map +1 -0
- package/dist/pincode.js +119 -0
- package/dist/pincode.js.map +1 -0
- package/dist/pincode.test.d.ts +2 -0
- package/dist/pincode.test.d.ts.map +1 -0
- package/dist/pincode.test.js +151 -0
- package/dist/pincode.test.js.map +1 -0
- package/dist/progress.d.ts +32 -30
- package/dist/progress.d.ts.map +1 -1
- package/dist/progress.js +257 -64
- package/dist/progress.js.map +1 -1
- package/dist/progress.test.js +50 -47
- package/dist/progress.test.js.map +1 -1
- package/dist/resizable.d.ts +200 -0
- package/dist/resizable.d.ts.map +1 -0
- package/dist/resizable.js +329 -0
- package/dist/resizable.js.map +1 -0
- package/dist/resizable.test.d.ts +2 -0
- package/dist/resizable.test.d.ts.map +1 -0
- package/dist/resizable.test.js +302 -0
- package/dist/resizable.test.js.map +1 -0
- package/dist/scroll-list.d.ts +69 -62
- package/dist/scroll-list.d.ts.map +1 -1
- package/dist/scroll-list.js +103 -144
- package/dist/scroll-list.js.map +1 -1
- package/dist/scroll-list.test.js +100 -110
- package/dist/scroll-list.test.js.map +1 -1
- package/dist/sidebar.d.ts +46 -0
- package/dist/sidebar.d.ts.map +1 -0
- package/dist/sidebar.js +65 -0
- package/dist/sidebar.js.map +1 -0
- package/dist/sidebar.test.d.ts +2 -0
- package/dist/sidebar.test.d.ts.map +1 -0
- package/dist/sidebar.test.js +88 -0
- package/dist/sidebar.test.js.map +1 -0
- package/dist/spin.d.ts +5 -5
- package/dist/spin.d.ts.map +1 -1
- package/dist/spin.js +13 -39
- package/dist/spin.js.map +1 -1
- package/dist/spin.test.js +2 -26
- package/dist/spin.test.js.map +1 -1
- package/dist/toast.d.ts +33 -30
- package/dist/toast.d.ts.map +1 -1
- package/dist/toast.js +77 -72
- package/dist/toast.js.map +1 -1
- package/dist/toast.test.js +63 -37
- package/dist/toast.test.js.map +1 -1
- package/dist/tree.d.ts +22 -5
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +61 -9
- package/dist/tree.js.map +1 -1
- package/dist/tree.test.js +72 -1
- package/dist/tree.test.js.map +1 -1
- package/dist/user-guide.d.ts +73 -0
- package/dist/user-guide.d.ts.map +1 -0
- package/dist/user-guide.js +95 -0
- package/dist/user-guide.js.map +1 -0
- package/dist/user-guide.test.d.ts +2 -0
- package/dist/user-guide.test.d.ts.map +1 -0
- package/dist/user-guide.test.js +109 -0
- package/dist/user-guide.test.js.map +1 -0
- package/dist/video-player.d.ts +196 -0
- package/dist/video-player.d.ts.map +1 -0
- package/dist/video-player.js +461 -0
- package/dist/video-player.js.map +1 -0
- package/dist/video-player.test.d.ts +2 -0
- package/dist/video-player.test.d.ts.map +1 -0
- package/dist/video-player.test.js +435 -0
- package/dist/video-player.test.js.map +1 -0
- package/package.json +17 -1
- package/dist/banner.d.ts +0 -19
- package/dist/banner.d.ts.map +0 -1
- package/dist/banner.js +0 -20
- package/dist/banner.js.map +0 -1
- package/dist/banner.test.d.ts +0 -2
- package/dist/banner.test.d.ts.map +0 -1
- package/dist/banner.test.js +0 -29
- package/dist/banner.test.js.map +0 -1
- package/dist/breakpoints.d.ts +0 -30
- package/dist/breakpoints.d.ts.map +0 -1
- package/dist/breakpoints.js +0 -45
- package/dist/breakpoints.js.map +0 -1
- package/dist/breakpoints.test.d.ts +0 -2
- package/dist/breakpoints.test.d.ts.map +0 -1
- package/dist/breakpoints.test.js +0 -46
- package/dist/breakpoints.test.js.map +0 -1
- package/dist/lottie-icon.d.ts +0 -88
- package/dist/lottie-icon.d.ts.map +0 -1
- package/dist/lottie-icon.js +0 -84
- package/dist/lottie-icon.js.map +0 -1
- package/dist/lottie-icon.test.d.ts +0 -2
- package/dist/lottie-icon.test.d.ts.map +0 -1
- package/dist/lottie-icon.test.js +0 -88
- package/dist/lottie-icon.test.js.map +0 -1
- package/dist/sider.d.ts +0 -26
- package/dist/sider.d.ts.map +0 -1
- package/dist/sider.js +0 -55
- package/dist/sider.js.map +0 -1
- package/dist/sider.test.d.ts +0 -2
- package/dist/sider.test.d.ts.map +0 -1
- package/dist/sider.test.js +0 -29
- package/dist/sider.test.js.map +0 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { compileToHast } from './markdown-render.js';
|
|
3
|
+
/** 递归收集所有 element 的 tagName。 */
|
|
4
|
+
function tagNames(root) {
|
|
5
|
+
const out = [];
|
|
6
|
+
function walk(node) {
|
|
7
|
+
if (node.type === 'element')
|
|
8
|
+
out.push(node.tagName);
|
|
9
|
+
if ('children' in node) {
|
|
10
|
+
for (const child of node.children)
|
|
11
|
+
walk(child);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
walk(root);
|
|
15
|
+
return out;
|
|
16
|
+
}
|
|
17
|
+
/** 递归拼接所有 text 节点内容。 */
|
|
18
|
+
function textContent(root) {
|
|
19
|
+
let out = '';
|
|
20
|
+
function walk(node) {
|
|
21
|
+
if (node.type === 'text')
|
|
22
|
+
out += node.value;
|
|
23
|
+
if ('children' in node) {
|
|
24
|
+
for (const child of node.children)
|
|
25
|
+
walk(child);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
walk(root);
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
describe('compileToHast', () => {
|
|
32
|
+
it('compiles basic markdown into hast elements', async () => {
|
|
33
|
+
const root = await compileToHast('# Title\n\nHello **world**.');
|
|
34
|
+
const tags = tagNames(root);
|
|
35
|
+
expect(tags).toContain('h1');
|
|
36
|
+
expect(tags).toContain('p');
|
|
37
|
+
expect(tags).toContain('strong');
|
|
38
|
+
expect(textContent(root)).toContain('Title');
|
|
39
|
+
expect(textContent(root)).toContain('world');
|
|
40
|
+
});
|
|
41
|
+
it('renders GFM tables when remarkGfm is on (default)', async () => {
|
|
42
|
+
const md = ['| a | b |', '| - | - |', '| 1 | 2 |'].join('\n');
|
|
43
|
+
const root = await compileToHast(md);
|
|
44
|
+
const tags = tagNames(root);
|
|
45
|
+
expect(tags).toContain('table');
|
|
46
|
+
expect(tags).toContain('thead');
|
|
47
|
+
expect(tags).toContain('td');
|
|
48
|
+
});
|
|
49
|
+
it('renders GFM strikethrough (del)', async () => {
|
|
50
|
+
const root = await compileToHast('~~gone~~');
|
|
51
|
+
expect(tagNames(root)).toContain('del');
|
|
52
|
+
});
|
|
53
|
+
it('renders GFM task list items with checkboxes', async () => {
|
|
54
|
+
const root = await compileToHast('- [x] done\n- [ ] todo');
|
|
55
|
+
const tags = tagNames(root);
|
|
56
|
+
expect(tags).toContain('ul');
|
|
57
|
+
expect(tags).toContain('li');
|
|
58
|
+
expect(tags).toContain('input');
|
|
59
|
+
});
|
|
60
|
+
it('remarkGfm=false disables tables/strikethrough', async () => {
|
|
61
|
+
const md = ['| a | b |', '| - | - |', '| 1 | 2 |'].join('\n');
|
|
62
|
+
const root = await compileToHast(md, { remarkGfm: false });
|
|
63
|
+
expect(tagNames(root)).not.toContain('table');
|
|
64
|
+
const strike = await compileToHast('~~gone~~', { remarkGfm: false });
|
|
65
|
+
expect(tagNames(strike)).not.toContain('del');
|
|
66
|
+
});
|
|
67
|
+
it('strips raw HTML by default (Semi format=md behavior)', async () => {
|
|
68
|
+
const root = await compileToHast('before <span class="x">raw</span> after');
|
|
69
|
+
const tags = tagNames(root);
|
|
70
|
+
// raw <span> 不作为 element 出现;文本正文保留。
|
|
71
|
+
expect(tags).not.toContain('span');
|
|
72
|
+
});
|
|
73
|
+
it('passes through custom remark plugins', async () => {
|
|
74
|
+
let called = false;
|
|
75
|
+
// remark 插件:transformer 被调用即证明进入管线。
|
|
76
|
+
const remarkProbe = () => () => {
|
|
77
|
+
called = true;
|
|
78
|
+
};
|
|
79
|
+
await compileToHast('# hi', { remarkPlugins: [remarkProbe] });
|
|
80
|
+
expect(called).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
it('passes through custom rehype plugins (can mutate hast)', async () => {
|
|
83
|
+
// rehype 插件:给根追加一个 <hr> element,验证 hast 层插件生效。
|
|
84
|
+
const rehypeAppendHr = () => (tree) => {
|
|
85
|
+
tree.children.push({
|
|
86
|
+
type: 'element',
|
|
87
|
+
tagName: 'hr',
|
|
88
|
+
properties: {},
|
|
89
|
+
children: [],
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
const root = await compileToHast('text', { rehypePlugins: [rehypeAppendHr] });
|
|
93
|
+
expect(tagNames(root)).toContain('hr');
|
|
94
|
+
});
|
|
95
|
+
it('accepts [plugin, options] tuple form', async () => {
|
|
96
|
+
let received;
|
|
97
|
+
const remarkWithOpts = (opts) => () => {
|
|
98
|
+
received = opts;
|
|
99
|
+
};
|
|
100
|
+
await compileToHast('# hi', {
|
|
101
|
+
remarkPlugins: [[remarkWithOpts, { flag: 1 }]],
|
|
102
|
+
});
|
|
103
|
+
expect(received).toEqual({ flag: 1 });
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=markdown-render.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-render.test.js","sourceRoot":"","sources":["../src/markdown-render.test.ts"],"names":[],"mappings":"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"}
|
package/dist/notification.d.ts
CHANGED
|
@@ -1,59 +1,68 @@
|
|
|
1
1
|
export type NotificationType = 'default' | 'success' | 'info' | 'warning' | 'error';
|
|
2
|
-
export type
|
|
3
|
-
|
|
4
|
-
export type NotificationTheme = '
|
|
2
|
+
export type NotificationPosition = 'top' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
|
|
3
|
+
/** 填充样式:normal(默认白色)| light(多色浅填充),对齐 Semi theme。 */
|
|
4
|
+
export type NotificationTheme = 'normal' | 'light';
|
|
5
5
|
export type NotificationDirection = 'ltr' | 'rtl';
|
|
6
6
|
export interface NotificationOptions {
|
|
7
7
|
id?: string;
|
|
8
|
-
title?:
|
|
9
|
-
content?:
|
|
8
|
+
title?: unknown;
|
|
9
|
+
content?: unknown;
|
|
10
10
|
type?: NotificationType;
|
|
11
|
-
/** auto-dismiss seconds; 0 = persist */
|
|
11
|
+
/** auto-dismiss seconds; 0 = persist(对齐 Semi 默认 3) */
|
|
12
12
|
duration?: number;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
showProgress?: boolean;
|
|
18
|
-
/** visual theme of the card */
|
|
13
|
+
position?: NotificationPosition;
|
|
14
|
+
/** 是否展示关闭按钮(对齐 Semi showClose,默认 true) */
|
|
15
|
+
showClose?: boolean;
|
|
16
|
+
/** 填充样式(对齐 Semi theme,默认 normal) */
|
|
19
17
|
theme?: NotificationTheme;
|
|
20
|
-
/**
|
|
18
|
+
/** 自定义左上角图标(渲染层 Snippet;core 用 unknown 透传,无框架依赖) */
|
|
19
|
+
icon?: unknown;
|
|
20
|
+
/** 弹层 z-index(对齐 Semi,默认 1010,首次生效) */
|
|
21
|
+
zIndex?: number;
|
|
22
|
+
/** 书写方向(对齐 Semi direction,默认 ltr) */
|
|
21
23
|
direction?: NotificationDirection;
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
/** 点击通知的回调(对齐 Semi onClick) */
|
|
25
|
+
onClick?: (e: unknown) => void;
|
|
26
|
+
/** 通知关闭回调(主动关闭、延时到达关闭都会触发,对齐 Semi onClose) */
|
|
27
|
+
onClose?: () => void;
|
|
28
|
+
/** 主动点击关闭按钮时的回调(对齐 Semi onCloseClick) */
|
|
29
|
+
onCloseClick?: (id: string) => void;
|
|
28
30
|
}
|
|
29
31
|
export interface NotificationItem {
|
|
30
32
|
id: string;
|
|
31
|
-
title:
|
|
32
|
-
content:
|
|
33
|
+
title: unknown;
|
|
34
|
+
content: unknown;
|
|
33
35
|
type: NotificationType;
|
|
34
36
|
duration: number;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
pauseOnHover: boolean;
|
|
38
|
-
showProgress: boolean;
|
|
37
|
+
position: NotificationPosition;
|
|
38
|
+
showClose: boolean;
|
|
39
39
|
theme: NotificationTheme;
|
|
40
|
+
icon: unknown;
|
|
41
|
+
zIndex: number | undefined;
|
|
40
42
|
direction: NotificationDirection;
|
|
41
|
-
|
|
42
|
-
onClose: ((
|
|
43
|
+
onClick: ((e: unknown) => void) | undefined;
|
|
44
|
+
onClose: (() => void) | undefined;
|
|
45
|
+
onCloseClick: ((id: string) => void) | undefined;
|
|
43
46
|
}
|
|
44
47
|
export interface NotificationStoreOptions {
|
|
45
|
-
|
|
48
|
+
/** 默认自动关闭秒数(对齐 Semi defaultConfig.duration = 3) */
|
|
46
49
|
defaultDuration?: number;
|
|
47
|
-
/**
|
|
50
|
+
/** 默认弹出位置(对齐 Semi defaultConfig.position = 'topRight') */
|
|
51
|
+
defaultPosition?: NotificationPosition;
|
|
52
|
+
/** 默认书写方向 */
|
|
48
53
|
defaultDirection?: NotificationDirection;
|
|
49
54
|
}
|
|
50
55
|
export interface NotificationStore {
|
|
51
56
|
getItems(): NotificationItem[];
|
|
52
57
|
subscribe(listener: (items: NotificationItem[]) => void): () => void;
|
|
58
|
+
/** 新增或按 id 原地更新一条通知,返回 id(对齐 Semi addNotice/update)。 */
|
|
53
59
|
open(options: NotificationOptions): string;
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
has(id: string): boolean;
|
|
61
|
+
close(id: string): void;
|
|
62
|
+
destroyAll(): void;
|
|
63
|
+
/** hover 进入:清定时器(对齐 Semi clearCloseTimer)。 */
|
|
56
64
|
pause(id: string): void;
|
|
65
|
+
/** hover 离开:重新完整计时(对齐 Semi startCloseTimer)。 */
|
|
57
66
|
resume(id: string): void;
|
|
58
67
|
destroy(): void;
|
|
59
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../src/notification.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../src/notification.ts"],"names":[],"mappings":"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"}
|
package/dist/notification.js
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* createNotificationStore — framework-agnostic singleton notification queue.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* 严格对齐 Semi Design(semi-foundation/notification):notificationListFoundation
|
|
4
|
+
* 的 add/has/update/remove/destroyAll + notificationFoundation 的 start/clear/restart
|
|
5
|
+
* close timer 语义。无框架依赖:无 DOM、无 UI 关注点。
|
|
6
|
+
*
|
|
7
|
+
* 对齐要点(对照 Semi):
|
|
8
|
+
* - duration 单位秒,默认 3;仅 duration>0 时自动关闭(duration=0 常驻)。
|
|
9
|
+
* - hover 行为:pause() 清定时器;resume() 重新完整计时(对齐 Semi startCloseTimer,
|
|
10
|
+
* 非恢复剩余时间)。
|
|
11
|
+
* - open():已存在 id → 原地合并更新 + 重启定时器(对齐 has→update→restartCloseTimer);
|
|
12
|
+
* 否则新增,新通知置于队首(对齐 addNotice [opts, ...notices])。
|
|
13
|
+
* - 无 maxCount(Semi 无此能力)。
|
|
14
|
+
* See semi-foundation/notification/notificationListFoundation.ts & notificationFoundation.ts
|
|
7
15
|
*/
|
|
8
16
|
import { useId } from './id.js';
|
|
9
17
|
export function createNotificationStore(storeOptions = {}) {
|
|
10
|
-
const {
|
|
18
|
+
const { defaultDuration = 3, defaultPosition = 'topRight', defaultDirection = 'ltr', } = storeOptions;
|
|
11
19
|
let items = [];
|
|
12
20
|
const timers = new Map();
|
|
13
21
|
const listeners = new Set();
|
|
@@ -16,99 +24,106 @@ export function createNotificationStore(storeOptions = {}) {
|
|
|
16
24
|
for (const l of listeners)
|
|
17
25
|
l(snapshot);
|
|
18
26
|
}
|
|
19
|
-
function now() {
|
|
20
|
-
return Date.now();
|
|
21
|
-
}
|
|
22
27
|
function clearTimer(id) {
|
|
23
|
-
const
|
|
24
|
-
if (
|
|
25
|
-
clearTimeout(
|
|
26
|
-
|
|
28
|
+
const t = timers.get(id);
|
|
29
|
+
if (t != null) {
|
|
30
|
+
clearTimeout(t);
|
|
31
|
+
timers.delete(id);
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
/** 对齐 Semi _startCloseTimer:仅 duration>0 时启动整段计时。 */
|
|
35
|
+
function startTimer(item) {
|
|
36
|
+
if (item.duration && item.duration > 0) {
|
|
37
|
+
const t = setTimeout(() => close(item.id), item.duration * 1000);
|
|
38
|
+
timers.set(item.id, t);
|
|
39
|
+
}
|
|
35
40
|
}
|
|
36
|
-
function
|
|
41
|
+
function normalize(options, id) {
|
|
42
|
+
return {
|
|
43
|
+
id,
|
|
44
|
+
title: options.title ?? '',
|
|
45
|
+
content: options.content ?? '',
|
|
46
|
+
type: options.type ?? 'default',
|
|
47
|
+
duration: options.duration ?? defaultDuration,
|
|
48
|
+
position: options.position ?? defaultPosition,
|
|
49
|
+
showClose: options.showClose ?? true,
|
|
50
|
+
theme: options.theme ?? 'normal',
|
|
51
|
+
icon: options.icon,
|
|
52
|
+
zIndex: options.zIndex,
|
|
53
|
+
direction: options.direction ?? defaultDirection,
|
|
54
|
+
onClick: options.onClick,
|
|
55
|
+
onClose: options.onClose,
|
|
56
|
+
onCloseClick: options.onCloseClick,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function close(id) {
|
|
37
60
|
const item = items.find((t) => t.id === id);
|
|
38
61
|
if (!item)
|
|
39
62
|
return;
|
|
40
63
|
clearTimer(id);
|
|
41
|
-
timers.delete(id);
|
|
42
64
|
items = items.filter((t) => t.id !== id);
|
|
43
65
|
emit();
|
|
44
|
-
item.onClose?.(
|
|
66
|
+
item.onClose?.();
|
|
45
67
|
}
|
|
46
68
|
function open(options) {
|
|
47
69
|
const id = options.id ?? useId('cd-notification');
|
|
48
|
-
const placement = options.placement ?? 'topRight';
|
|
49
|
-
const item = {
|
|
50
|
-
id,
|
|
51
|
-
title: options.title ?? '',
|
|
52
|
-
content: options.content ?? '',
|
|
53
|
-
type: options.type ?? 'default',
|
|
54
|
-
duration: options.duration ?? defaultDuration,
|
|
55
|
-
placement,
|
|
56
|
-
closable: options.closable ?? true,
|
|
57
|
-
pauseOnHover: options.pauseOnHover ?? true,
|
|
58
|
-
showProgress: options.showProgress ?? false,
|
|
59
|
-
theme: options.theme ?? 'light',
|
|
60
|
-
direction: options.direction ?? defaultDirection,
|
|
61
|
-
footer: options.footer,
|
|
62
|
-
onClose: options.onClose,
|
|
63
|
-
};
|
|
64
70
|
const existingIndex = items.findIndex((t) => t.id === id);
|
|
65
71
|
if (existingIndex >= 0) {
|
|
72
|
+
// 对齐 Semi update:原地合并旧 item 属性 + 新 options(仅覆盖显式传入的键),并重启定时器。
|
|
73
|
+
const prev = items[existingIndex];
|
|
74
|
+
const merged = mergeUpdate(prev, options);
|
|
66
75
|
clearTimer(id);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
items = [...items, item];
|
|
72
|
-
// FIFO per placement
|
|
73
|
-
const samePlacement = items.filter((t) => t.placement === placement);
|
|
74
|
-
if (samePlacement.length > maxCount) {
|
|
75
|
-
const oldest = samePlacement[0];
|
|
76
|
-
clearTimer(oldest.id);
|
|
77
|
-
timers.delete(oldest.id);
|
|
78
|
-
items = items.filter((t) => t.id !== oldest.id);
|
|
79
|
-
oldest.onClose?.(oldest.id, 'replace');
|
|
80
|
-
}
|
|
76
|
+
items = items.map((t, i) => (i === existingIndex ? merged : t));
|
|
77
|
+
emit();
|
|
78
|
+
startTimer(merged);
|
|
79
|
+
return id;
|
|
81
80
|
}
|
|
81
|
+
const item = normalize(options, id);
|
|
82
|
+
// 对齐 Semi addNotice:新通知置于队首。
|
|
83
|
+
items = [item, ...items];
|
|
82
84
|
emit();
|
|
83
|
-
startTimer(
|
|
85
|
+
startTimer(item);
|
|
84
86
|
return id;
|
|
85
87
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
/** 对齐 Semi update:以已存在的 item 为基底,仅覆盖 options 中显式传入的键。 */
|
|
89
|
+
function mergeUpdate(prev, options) {
|
|
90
|
+
return {
|
|
91
|
+
id: prev.id,
|
|
92
|
+
title: options.title ?? prev.title,
|
|
93
|
+
content: options.content ?? prev.content,
|
|
94
|
+
type: options.type ?? prev.type,
|
|
95
|
+
duration: options.duration ?? prev.duration,
|
|
96
|
+
position: options.position ?? prev.position,
|
|
97
|
+
showClose: options.showClose ?? prev.showClose,
|
|
98
|
+
theme: options.theme ?? prev.theme,
|
|
99
|
+
icon: options.icon ?? prev.icon,
|
|
100
|
+
zIndex: options.zIndex ?? prev.zIndex,
|
|
101
|
+
direction: options.direction ?? prev.direction,
|
|
102
|
+
onClick: options.onClick ?? prev.onClick,
|
|
103
|
+
onClose: options.onClose ?? prev.onClose,
|
|
104
|
+
onCloseClick: options.onCloseClick ?? prev.onCloseClick,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function destroyAll() {
|
|
108
|
+
const targets = items.slice();
|
|
109
|
+
for (const t of targets)
|
|
89
110
|
clearTimer(t.id);
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
const ids = new Set(targets.map((t) => t.id));
|
|
93
|
-
items = items.filter((t) => !ids.has(t.id));
|
|
111
|
+
items = [];
|
|
94
112
|
emit();
|
|
95
113
|
for (const t of targets)
|
|
96
|
-
t.onClose?.(
|
|
114
|
+
t.onClose?.();
|
|
97
115
|
}
|
|
98
116
|
function pause(id) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return;
|
|
102
|
-
clearTimeout(rec.timer);
|
|
103
|
-
rec.remaining = Math.max(0, rec.remaining - (now() - rec.startedAt));
|
|
104
|
-
rec.timer = null;
|
|
117
|
+
// 对齐 Semi clearCloseTimer:hover 进入清除定时器。
|
|
118
|
+
clearTimer(id);
|
|
105
119
|
}
|
|
106
120
|
function resume(id) {
|
|
107
|
-
|
|
108
|
-
if (
|
|
121
|
+
// 对齐 Semi startCloseTimer:hover 离开重新完整计时。
|
|
122
|
+
if (timers.has(id))
|
|
109
123
|
return;
|
|
110
|
-
|
|
111
|
-
|
|
124
|
+
const item = items.find((t) => t.id === id);
|
|
125
|
+
if (item)
|
|
126
|
+
startTimer(item);
|
|
112
127
|
}
|
|
113
128
|
return {
|
|
114
129
|
getItems: () => items.slice(),
|
|
@@ -117,6 +132,7 @@ export function createNotificationStore(storeOptions = {}) {
|
|
|
117
132
|
return () => listeners.delete(listener);
|
|
118
133
|
},
|
|
119
134
|
open,
|
|
135
|
+
has: (id) => items.some((t) => t.id === id),
|
|
120
136
|
close,
|
|
121
137
|
destroyAll,
|
|
122
138
|
pause,
|
package/dist/notification.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.js","sourceRoot":"","sources":["../src/notification.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"notification.js","sourceRoot":"","sources":["../src/notification.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,10 +10,10 @@ describe('createNotificationStore', () => {
|
|
|
10
10
|
expect(s.getItems()[0]?.title).toBe('Done');
|
|
11
11
|
s.destroy();
|
|
12
12
|
});
|
|
13
|
-
it('auto-dismisses after duration (default
|
|
13
|
+
it('auto-dismisses after duration (default 3s, aligned with Semi)', () => {
|
|
14
14
|
const s = createNotificationStore();
|
|
15
15
|
s.open({ title: 'x' });
|
|
16
|
-
vi.advanceTimersByTime(
|
|
16
|
+
vi.advanceTimersByTime(2999);
|
|
17
17
|
expect(s.getItems().length).toBe(1);
|
|
18
18
|
vi.advanceTimersByTime(1);
|
|
19
19
|
expect(s.getItems().length).toBe(0);
|
|
@@ -26,7 +26,7 @@ describe('createNotificationStore', () => {
|
|
|
26
26
|
expect(s.getItems().length).toBe(1);
|
|
27
27
|
s.destroy();
|
|
28
28
|
});
|
|
29
|
-
it('id dedup updates in place', () => {
|
|
29
|
+
it('id dedup updates in place and restarts the timer', () => {
|
|
30
30
|
const s = createNotificationStore();
|
|
31
31
|
const id = s.open({ title: 'v1', duration: 0 });
|
|
32
32
|
s.open({ id, title: 'v2', duration: 0 });
|
|
@@ -34,33 +34,56 @@ describe('createNotificationStore', () => {
|
|
|
34
34
|
expect(s.getItems()[0]?.title).toBe('v2');
|
|
35
35
|
s.destroy();
|
|
36
36
|
});
|
|
37
|
-
it('
|
|
38
|
-
const s = createNotificationStore(
|
|
39
|
-
s.open({ title: '
|
|
40
|
-
s.open({
|
|
41
|
-
s.
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
expect(
|
|
45
|
-
|
|
46
|
-
s.
|
|
47
|
-
|
|
37
|
+
it('update merges previous props (aligned with Semi update)', () => {
|
|
38
|
+
const s = createNotificationStore();
|
|
39
|
+
const id = s.open({ title: 'v1', content: 'body', type: 'success', duration: 0 });
|
|
40
|
+
s.open({ id, content: 'body2', duration: 0 });
|
|
41
|
+
const item = s.getItems()[0];
|
|
42
|
+
// title/type preserved, content updated
|
|
43
|
+
expect(item.title).toBe('v1');
|
|
44
|
+
expect(item.type).toBe('success');
|
|
45
|
+
expect(item.content).toBe('body2');
|
|
46
|
+
s.destroy();
|
|
47
|
+
});
|
|
48
|
+
it('new notice is placed at the head of the queue (aligned with Semi addNotice)', () => {
|
|
49
|
+
const s = createNotificationStore();
|
|
50
|
+
s.open({ title: 'a', duration: 0 });
|
|
51
|
+
s.open({ title: 'b', duration: 0 });
|
|
52
|
+
expect(s.getItems().map((t) => t.title)).toEqual(['b', 'a']);
|
|
48
53
|
s.destroy();
|
|
49
54
|
});
|
|
50
|
-
it('
|
|
55
|
+
it('has() reflects presence', () => {
|
|
51
56
|
const s = createNotificationStore();
|
|
52
|
-
const
|
|
53
|
-
s.
|
|
57
|
+
const id = s.open({ title: 'a', duration: 0 });
|
|
58
|
+
expect(s.has(id)).toBe(true);
|
|
59
|
+
s.close(id);
|
|
60
|
+
expect(s.has(id)).toBe(false);
|
|
61
|
+
s.destroy();
|
|
62
|
+
});
|
|
63
|
+
it('close and destroyAll', () => {
|
|
64
|
+
const s = createNotificationStore();
|
|
65
|
+
const a = s.open({ title: 'a', duration: 0 });
|
|
66
|
+
s.open({ title: 'b', duration: 0 });
|
|
54
67
|
s.close(a);
|
|
55
68
|
expect(s.getItems().map((t) => t.title)).toEqual(['b']);
|
|
56
|
-
s.open({ title: 'c',
|
|
57
|
-
s.destroyAll(
|
|
58
|
-
expect(s.getItems().map((t) => t.title)).toEqual(['b']);
|
|
59
|
-
s.destroyAll(); // all cleared
|
|
69
|
+
s.open({ title: 'c', duration: 0 });
|
|
70
|
+
s.destroyAll();
|
|
60
71
|
expect(s.getItems().length).toBe(0);
|
|
61
72
|
s.destroy();
|
|
62
73
|
});
|
|
63
|
-
it('
|
|
74
|
+
it('onClose fires on close and destroyAll', () => {
|
|
75
|
+
const s = createNotificationStore();
|
|
76
|
+
const onClose = vi.fn();
|
|
77
|
+
const id = s.open({ title: 'a', duration: 0, onClose });
|
|
78
|
+
s.close(id);
|
|
79
|
+
expect(onClose).toHaveBeenCalledTimes(1);
|
|
80
|
+
const onClose2 = vi.fn();
|
|
81
|
+
s.open({ title: 'b', duration: 0, onClose: onClose2 });
|
|
82
|
+
s.destroyAll();
|
|
83
|
+
expect(onClose2).toHaveBeenCalledTimes(1);
|
|
84
|
+
s.destroy();
|
|
85
|
+
});
|
|
86
|
+
it('pause clears the timer; resume restarts a full countdown (aligned with Semi)', () => {
|
|
64
87
|
const s = createNotificationStore();
|
|
65
88
|
const id = s.open({ title: 'x', duration: 4 });
|
|
66
89
|
vi.advanceTimersByTime(1000);
|
|
@@ -68,35 +91,35 @@ describe('createNotificationStore', () => {
|
|
|
68
91
|
vi.advanceTimersByTime(10000);
|
|
69
92
|
expect(s.getItems().length).toBe(1);
|
|
70
93
|
s.resume(id);
|
|
71
|
-
|
|
94
|
+
// resume 重新完整计时(4s),而非仅剩余 3s
|
|
95
|
+
vi.advanceTimersByTime(3999);
|
|
96
|
+
expect(s.getItems().length).toBe(1);
|
|
97
|
+
vi.advanceTimersByTime(1);
|
|
72
98
|
expect(s.getItems().length).toBe(0);
|
|
73
99
|
s.destroy();
|
|
74
100
|
});
|
|
75
|
-
it('default type
|
|
101
|
+
it('default type / position / theme / showClose', () => {
|
|
76
102
|
const s = createNotificationStore();
|
|
77
103
|
s.open({ title: 'x', duration: 0 });
|
|
78
104
|
const item = s.getItems()[0];
|
|
79
105
|
expect(item.type).toBe('default');
|
|
80
|
-
expect(item.
|
|
106
|
+
expect(item.position).toBe('topRight');
|
|
107
|
+
expect(item.theme).toBe('normal');
|
|
108
|
+
expect(item.showClose).toBe(true);
|
|
81
109
|
s.destroy();
|
|
82
110
|
});
|
|
83
|
-
it('
|
|
111
|
+
it('carries theme / icon / zIndex / onClick / onCloseClick through to the item', () => {
|
|
84
112
|
const s = createNotificationStore();
|
|
85
|
-
|
|
113
|
+
const icon = { __snippet: true };
|
|
114
|
+
const onClick = vi.fn();
|
|
115
|
+
const onCloseClick = vi.fn();
|
|
116
|
+
s.open({ title: 'x', duration: 0, theme: 'light', icon, zIndex: 2000, onClick, onCloseClick });
|
|
86
117
|
const item = s.getItems()[0];
|
|
87
|
-
expect(item.showProgress).toBe(false);
|
|
88
118
|
expect(item.theme).toBe('light');
|
|
89
|
-
expect(item.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const s = createNotificationStore();
|
|
94
|
-
const footer = { __snippet: true };
|
|
95
|
-
s.open({ title: 'x', duration: 0, showProgress: true, theme: 'dark', footer });
|
|
96
|
-
const item = s.getItems()[0];
|
|
97
|
-
expect(item.showProgress).toBe(true);
|
|
98
|
-
expect(item.theme).toBe('dark');
|
|
99
|
-
expect(item.footer).toBe(footer);
|
|
119
|
+
expect(item.icon).toBe(icon);
|
|
120
|
+
expect(item.zIndex).toBe(2000);
|
|
121
|
+
expect(item.onClick).toBe(onClick);
|
|
122
|
+
expect(item.onCloseClick).toBe(onCloseClick);
|
|
100
123
|
s.destroy();
|
|
101
124
|
});
|
|
102
125
|
});
|