@v-c/notification 1.0.0 → 2.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Notification.d.ts +59 -0
- package/dist/Notification.js +301 -0
- package/dist/NotificationList/Content.d.ts +11 -0
- package/dist/NotificationList/Content.js +60 -0
- package/dist/NotificationList/index.d.ts +35 -0
- package/dist/NotificationList/index.js +224 -0
- package/dist/NotificationProvider.js +3 -1
- package/dist/Notifications.d.ts +9 -3
- package/dist/Notifications.js +45 -21
- package/dist/Progress.d.ts +8 -0
- package/dist/Progress.js +31 -0
- package/dist/hooks/useClosable.d.ts +17 -0
- package/dist/hooks/useClosable.js +34 -0
- package/dist/hooks/useListPosition/index.d.ts +18 -0
- package/dist/hooks/useListPosition/index.js +41 -0
- package/dist/hooks/useListPosition/useSizes.d.ts +10 -0
- package/dist/hooks/useListPosition/useSizes.js +31 -0
- package/dist/hooks/useNoticeTimer.d.ts +7 -0
- package/dist/hooks/useNoticeTimer.js +63 -0
- package/dist/hooks/useNotification.d.ts +10 -8
- package/dist/hooks/useNotification.js +10 -4
- package/dist/hooks/useStack.d.ts +5 -0
- package/dist/hooks/useStack.js +13 -10
- package/dist/index.d.ts +9 -6
- package/dist/index.js +5 -3
- package/dist/interface.d.ts +18 -43
- package/package.json +3 -3
- package/src/Notification.tsx +326 -0
- package/src/NotificationList/Content.tsx +66 -0
- package/src/NotificationList/index.tsx +282 -0
- package/src/Notifications.tsx +58 -64
- package/src/Progress.tsx +27 -0
- package/src/hooks/useClosable.ts +53 -0
- package/src/hooks/useListPosition/index.ts +69 -0
- package/src/hooks/useListPosition/useSizes.ts +43 -0
- package/src/hooks/useNoticeTimer.ts +85 -0
- package/src/hooks/useNotification.tsx +30 -28
- package/src/hooks/useStack.ts +12 -8
- package/src/index.ts +47 -6
- package/src/interface.ts +28 -44
- package/vite.config.ts +4 -3
- package/dist/Notice.cjs +0 -235
- package/dist/Notice.d.ts +0 -15
- package/dist/Notice.js +0 -227
- package/dist/NoticeList.cjs +0 -170
- package/dist/NoticeList.d.ts +0 -13
- package/dist/NoticeList.js +0 -164
- package/dist/NotificationProvider.cjs +0 -14
- package/dist/Notifications.cjs +0 -146
- package/dist/_virtual/rolldown_runtime.cjs +0 -21
- package/dist/hooks/useNotification.cjs +0 -93
- package/dist/hooks/useStack.cjs +0 -27
- package/dist/index.cjs +0 -7
- package/dist/interface.cjs +0 -1
- package/src/Notice.tsx +0 -212
- package/src/NoticeList.tsx +0 -219
package/dist/Notifications.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import { VueNode } from '@v-c/util/dist/type';
|
|
2
1
|
import { CSSProperties, TransitionGroupProps } from 'vue';
|
|
3
|
-
import {
|
|
2
|
+
import { VueNode } from '@v-c/util/dist/type';
|
|
3
|
+
import { Key, NotificationListConfig, Placement, StackConfig } from './interface';
|
|
4
|
+
import { ComponentsType } from './Notification';
|
|
5
|
+
import { NotificationClassNames, NotificationStyles } from './NotificationList';
|
|
4
6
|
export interface NotificationsProps {
|
|
5
7
|
prefixCls?: string;
|
|
6
8
|
motion?: TransitionGroupProps | ((placement: Placement) => TransitionGroupProps);
|
|
7
9
|
container?: HTMLElement | ShadowRoot;
|
|
8
10
|
maxCount?: number;
|
|
11
|
+
pauseOnHover?: boolean;
|
|
12
|
+
classNames?: NotificationClassNames;
|
|
13
|
+
styles?: NotificationStyles;
|
|
14
|
+
components?: ComponentsType;
|
|
9
15
|
className?: (placement: Placement) => string;
|
|
10
16
|
style?: (placement: Placement) => CSSProperties;
|
|
11
17
|
onAllRemoved?: VoidFunction;
|
|
@@ -16,7 +22,7 @@ export interface NotificationsProps {
|
|
|
16
22
|
}) => VueNode;
|
|
17
23
|
}
|
|
18
24
|
export interface NotificationsRef {
|
|
19
|
-
open: (config:
|
|
25
|
+
open: (config: NotificationListConfig) => void;
|
|
20
26
|
close: (key: Key) => void;
|
|
21
27
|
destroy: () => void;
|
|
22
28
|
}
|
package/dist/Notifications.js
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import
|
|
1
|
+
import NotificationList from "./NotificationList/index.js";
|
|
2
2
|
import { Teleport, createVNode, defineComponent, isVNode, mergeDefaults, shallowRef, watch } from "vue";
|
|
3
|
+
//#region src/Notifications.tsx
|
|
3
4
|
function _isSlot(s) {
|
|
4
5
|
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
|
|
5
6
|
}
|
|
6
7
|
var defaults = { prefixCls: "vc-notification" };
|
|
7
|
-
var
|
|
8
|
+
var Notifications = /* @__PURE__ */ defineComponent((props, { expose }) => {
|
|
8
9
|
const configList = shallowRef([]);
|
|
9
10
|
const onNoticeClose = (key) => {
|
|
10
11
|
const config = configList.value.find((item) => item.key === key);
|
|
11
12
|
const closable = config?.closable;
|
|
12
|
-
(closable && typeof closable === "object" ? closable :
|
|
13
|
+
(closable && typeof closable === "object" ? closable : null)?.onClose?.();
|
|
13
14
|
config?.onClose?.();
|
|
14
15
|
configList.value = configList.value.filter((item) => item.key !== key);
|
|
15
16
|
};
|
|
16
17
|
expose({
|
|
17
18
|
open: (config) => {
|
|
18
19
|
const list = configList.value;
|
|
19
|
-
let clone = [...
|
|
20
|
+
let clone = [...list];
|
|
20
21
|
const index = clone.findIndex((item) => item.key === config.key);
|
|
21
22
|
const innerConfig = { ...config };
|
|
22
23
|
if (index >= 0) {
|
|
23
|
-
innerConfig.times = (list[index]?.times
|
|
24
|
+
innerConfig.times = (list[index]?.times ?? 0) + 1;
|
|
24
25
|
clone[index] = innerConfig;
|
|
25
26
|
} else {
|
|
26
27
|
innerConfig.times = 0;
|
|
@@ -37,19 +38,16 @@ var Notifications_default = /* @__PURE__ */ defineComponent((props, { expose })
|
|
|
37
38
|
});
|
|
38
39
|
const placements = shallowRef({});
|
|
39
40
|
watch(configList, () => {
|
|
40
|
-
const
|
|
41
|
+
const next = {};
|
|
41
42
|
configList.value.forEach((config) => {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
nextPlacements[placement].push(config);
|
|
46
|
-
}
|
|
43
|
+
const placement = config.placement ?? "topRight";
|
|
44
|
+
next[placement] = next[placement] || [];
|
|
45
|
+
next[placement].push(config);
|
|
47
46
|
});
|
|
48
|
-
Object.keys(placements.value).forEach((
|
|
49
|
-
|
|
50
|
-
nextPlacements[placement] = nextPlacements[placement] || [];
|
|
47
|
+
Object.keys(placements.value).forEach((placement) => {
|
|
48
|
+
next[placement] = next[placement] || [];
|
|
51
49
|
});
|
|
52
|
-
placements.value =
|
|
50
|
+
placements.value = next;
|
|
53
51
|
});
|
|
54
52
|
const onAllNoticeRemoved = (placement) => {
|
|
55
53
|
const clone = { ...placements.value };
|
|
@@ -67,20 +65,25 @@ var Notifications_default = /* @__PURE__ */ defineComponent((props, { expose })
|
|
|
67
65
|
return () => {
|
|
68
66
|
let _slot;
|
|
69
67
|
const { container } = props;
|
|
70
|
-
const prefixCls = props.prefixCls ?? defaults.prefixCls
|
|
68
|
+
const prefixCls = props.prefixCls ?? defaults.prefixCls;
|
|
71
69
|
if (!container) return null;
|
|
72
|
-
return createVNode(Teleport, { "to": container }, _isSlot(_slot = Object.keys(placements.value).map((
|
|
70
|
+
return createVNode(Teleport, { "to": container }, _isSlot(_slot = Object.keys(placements.value).map((rawPlacement) => {
|
|
71
|
+
const placement = rawPlacement;
|
|
73
72
|
const placementConfigList = placements.value[placement];
|
|
74
|
-
const list = createVNode(
|
|
73
|
+
const list = createVNode(NotificationList, {
|
|
75
74
|
"key": placement,
|
|
76
75
|
"configList": placementConfigList,
|
|
77
76
|
"placement": placement,
|
|
78
77
|
"prefixCls": prefixCls,
|
|
79
|
-
"
|
|
78
|
+
"pauseOnHover": props.pauseOnHover,
|
|
79
|
+
"classNames": props.classNames,
|
|
80
|
+
"styles": props.styles,
|
|
81
|
+
"components": props.components,
|
|
82
|
+
"className": props.className?.(placement),
|
|
80
83
|
"style": props.style?.(placement),
|
|
81
84
|
"motion": props.motion,
|
|
82
85
|
"stack": props.stack,
|
|
83
|
-
"
|
|
86
|
+
"onAllRemoved": onAllNoticeRemoved,
|
|
84
87
|
"onNoticeClose": onNoticeClose
|
|
85
88
|
}, null);
|
|
86
89
|
return props.renderNotifications ? props.renderNotifications(list, {
|
|
@@ -110,6 +113,26 @@ var Notifications_default = /* @__PURE__ */ defineComponent((props, { expose })
|
|
|
110
113
|
required: false,
|
|
111
114
|
default: void 0
|
|
112
115
|
},
|
|
116
|
+
pauseOnHover: {
|
|
117
|
+
type: Boolean,
|
|
118
|
+
required: false,
|
|
119
|
+
default: void 0
|
|
120
|
+
},
|
|
121
|
+
classNames: {
|
|
122
|
+
type: Object,
|
|
123
|
+
required: false,
|
|
124
|
+
default: void 0
|
|
125
|
+
},
|
|
126
|
+
styles: {
|
|
127
|
+
type: Object,
|
|
128
|
+
required: false,
|
|
129
|
+
default: void 0
|
|
130
|
+
},
|
|
131
|
+
components: {
|
|
132
|
+
type: Object,
|
|
133
|
+
required: false,
|
|
134
|
+
default: void 0
|
|
135
|
+
},
|
|
113
136
|
className: {
|
|
114
137
|
type: Function,
|
|
115
138
|
required: false,
|
|
@@ -137,4 +160,5 @@ var Notifications_default = /* @__PURE__ */ defineComponent((props, { expose })
|
|
|
137
160
|
}, defaults),
|
|
138
161
|
name: "Notifications"
|
|
139
162
|
});
|
|
140
|
-
|
|
163
|
+
//#endregion
|
|
164
|
+
export { Notifications as default };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CSSProperties } from 'vue';
|
|
2
|
+
export interface NotificationProgressProps {
|
|
3
|
+
className?: string;
|
|
4
|
+
style?: CSSProperties;
|
|
5
|
+
percent: number;
|
|
6
|
+
}
|
|
7
|
+
declare const Progress: import('vue').DefineSetupFnComponent<NotificationProgressProps, {}, {}, NotificationProgressProps & {}, import('vue').PublicProps>;
|
|
8
|
+
export default Progress;
|
package/dist/Progress.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createVNode, defineComponent } from "vue";
|
|
2
|
+
//#region src/Progress.tsx
|
|
3
|
+
var Progress = /* @__PURE__ */ defineComponent((props) => {
|
|
4
|
+
return () => createVNode("progress", {
|
|
5
|
+
"class": props.className,
|
|
6
|
+
"max": "100",
|
|
7
|
+
"value": props.percent,
|
|
8
|
+
"style": props.style
|
|
9
|
+
}, null);
|
|
10
|
+
}, {
|
|
11
|
+
props: {
|
|
12
|
+
className: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: false,
|
|
15
|
+
default: void 0
|
|
16
|
+
},
|
|
17
|
+
style: {
|
|
18
|
+
type: Object,
|
|
19
|
+
required: false,
|
|
20
|
+
default: void 0
|
|
21
|
+
},
|
|
22
|
+
percent: {
|
|
23
|
+
type: Number,
|
|
24
|
+
required: true
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
name: "NotificationProgress",
|
|
28
|
+
inheritAttrs: false
|
|
29
|
+
});
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Progress as default };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AriaAttributes, ComputedRef } from 'vue';
|
|
2
|
+
import { VueNode } from '@v-c/util/dist/type';
|
|
3
|
+
export type ClosableConfig = {
|
|
4
|
+
closeIcon?: VueNode;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
onClose?: VoidFunction;
|
|
7
|
+
} & AriaAttributes & Record<`data-${string}`, unknown>;
|
|
8
|
+
export type ClosableType = boolean | ClosableConfig | null | undefined;
|
|
9
|
+
export interface ParsedClosableConfig extends ClosableConfig {
|
|
10
|
+
closeIcon: VueNode;
|
|
11
|
+
disabled: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Normalizes the closable option into a boolean flag, parsed config, and
|
|
15
|
+
* aria props for the close button. Mirrors rc-notification@2.0 useClosable.
|
|
16
|
+
*/
|
|
17
|
+
export default function useClosable(closable: ComputedRef<ClosableType>): [ComputedRef<boolean>, ComputedRef<ParsedClosableConfig>, ComputedRef<Record<string, unknown>>];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import pickAttrs from "@v-c/util/dist/pickAttrs";
|
|
3
|
+
//#region src/hooks/useClosable.ts
|
|
4
|
+
/**
|
|
5
|
+
* Normalizes the closable option into a boolean flag, parsed config, and
|
|
6
|
+
* aria props for the close button. Mirrors rc-notification@2.0 useClosable.
|
|
7
|
+
*/
|
|
8
|
+
function useClosable(closable) {
|
|
9
|
+
const closableObj = computed(() => {
|
|
10
|
+
const value = closable.value;
|
|
11
|
+
if (value === false) return {
|
|
12
|
+
closeIcon: null,
|
|
13
|
+
disabled: true
|
|
14
|
+
};
|
|
15
|
+
if (typeof value === "object" && value !== null) return value;
|
|
16
|
+
return {};
|
|
17
|
+
});
|
|
18
|
+
const closableConfig = computed(() => {
|
|
19
|
+
const obj = closableObj.value;
|
|
20
|
+
return {
|
|
21
|
+
...obj,
|
|
22
|
+
closeIcon: "closeIcon" in obj ? obj.closeIcon : "×",
|
|
23
|
+
disabled: obj.disabled ?? false
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
const closableAriaProps = computed(() => pickAttrs(closableConfig.value, true));
|
|
27
|
+
return [
|
|
28
|
+
computed(() => !!closable.value),
|
|
29
|
+
closableConfig,
|
|
30
|
+
closableAriaProps
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { useClosable as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ComputedRef, Ref } from 'vue';
|
|
2
|
+
import { Key } from '../../interface';
|
|
3
|
+
export interface ListPositionStackConfig {
|
|
4
|
+
threshold?: number;
|
|
5
|
+
offset?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Calculates each notification's position and the full list height.
|
|
9
|
+
* Mirrors rc-notification@2.0 useListPosition.
|
|
10
|
+
*/
|
|
11
|
+
export default function useListPosition(configList: ComputedRef<{
|
|
12
|
+
key: Key;
|
|
13
|
+
}[]>, stack: ComputedRef<ListPositionStackConfig | undefined>, gap: Ref<number>): readonly [ComputedRef<{
|
|
14
|
+
notificationPosition: Map<string, number>;
|
|
15
|
+
totalHeight: number;
|
|
16
|
+
topNoticeHeight: number | undefined;
|
|
17
|
+
topNoticeWidth: number | undefined;
|
|
18
|
+
}>, (key: string, node: HTMLDivElement | null) => void];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import useSizes from "./useSizes.js";
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
//#region src/hooks/useListPosition/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Calculates each notification's position and the full list height.
|
|
6
|
+
* Mirrors rc-notification@2.0 useListPosition.
|
|
7
|
+
*/
|
|
8
|
+
function useListPosition(configList, stack, gap) {
|
|
9
|
+
const [sizeMap, setNodeSize] = useSizes();
|
|
10
|
+
return [computed(() => {
|
|
11
|
+
let offsetY = 0;
|
|
12
|
+
let nextTotalHeight = 0;
|
|
13
|
+
const stackParams = stack.value;
|
|
14
|
+
const stackThreshold = stackParams?.threshold ?? 0;
|
|
15
|
+
const stackOffset = stackParams?.offset ?? 0;
|
|
16
|
+
const notificationPosition = /* @__PURE__ */ new Map();
|
|
17
|
+
let topNoticeHeight;
|
|
18
|
+
let topNoticeWidth;
|
|
19
|
+
configList.value.slice().reverse().forEach((config, index) => {
|
|
20
|
+
const key = String(config.key);
|
|
21
|
+
const height = sizeMap.value[key]?.height ?? 0;
|
|
22
|
+
const y = stackParams && index > 0 ? offsetY + stackOffset - height : offsetY;
|
|
23
|
+
notificationPosition.set(key, y);
|
|
24
|
+
if (index === 0) {
|
|
25
|
+
topNoticeHeight = height;
|
|
26
|
+
topNoticeWidth = sizeMap.value[key]?.width ?? 0;
|
|
27
|
+
}
|
|
28
|
+
if (!stackParams || index < stackThreshold) nextTotalHeight = Math.max(nextTotalHeight, y + height);
|
|
29
|
+
if (stackParams) offsetY = y + height;
|
|
30
|
+
else offsetY += height + gap.value;
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
notificationPosition,
|
|
34
|
+
totalHeight: nextTotalHeight,
|
|
35
|
+
topNoticeHeight,
|
|
36
|
+
topNoticeWidth
|
|
37
|
+
};
|
|
38
|
+
}), setNodeSize];
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { useListPosition as default };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface NodeSize {
|
|
2
|
+
width: number;
|
|
3
|
+
height: number;
|
|
4
|
+
}
|
|
5
|
+
export type NodeSizeMap = Record<string, NodeSize>;
|
|
6
|
+
/**
|
|
7
|
+
* Stores measured node sizes by key and exposes a callback to update them.
|
|
8
|
+
* Mirrors rc-notification@2.0 useSizes.
|
|
9
|
+
*/
|
|
10
|
+
export default function useSizes(): readonly [import('vue').ShallowRef<NodeSizeMap, NodeSizeMap>, (key: string, node: HTMLDivElement | null) => void];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { shallowRef } from "vue";
|
|
2
|
+
//#region src/hooks/useListPosition/useSizes.ts
|
|
3
|
+
/**
|
|
4
|
+
* Stores measured node sizes by key and exposes a callback to update them.
|
|
5
|
+
* Mirrors rc-notification@2.0 useSizes.
|
|
6
|
+
*/
|
|
7
|
+
function useSizes() {
|
|
8
|
+
const sizeMap = shallowRef({});
|
|
9
|
+
const setNodeSize = (key, node) => {
|
|
10
|
+
if (!node) {
|
|
11
|
+
if (!(key in sizeMap.value)) return;
|
|
12
|
+
const next = { ...sizeMap.value };
|
|
13
|
+
delete next[key];
|
|
14
|
+
sizeMap.value = next;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const nextSize = {
|
|
18
|
+
width: node.offsetWidth,
|
|
19
|
+
height: node.offsetHeight
|
|
20
|
+
};
|
|
21
|
+
const prev = sizeMap.value[key];
|
|
22
|
+
if (prev && prev.width === nextSize.width && prev.height === nextSize.height) return;
|
|
23
|
+
sizeMap.value = {
|
|
24
|
+
...sizeMap.value,
|
|
25
|
+
[key]: nextSize
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
return [sizeMap, setNodeSize];
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { useSizes as default };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* Runs the notice auto-close timer and reports progress updates via rAF.
|
|
4
|
+
* Returns controls to pause and resume the timer. Mirrors rc-notification@2.0
|
|
5
|
+
* useNoticeTimer.
|
|
6
|
+
*/
|
|
7
|
+
export default function useNoticeTimer(duration: ComputedRef<number | false | null | undefined>, onClose: () => void, onUpdate: (percent: number) => void): [() => void, () => void];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { onScopeDispose, shallowRef, watch } from "vue";
|
|
2
|
+
//#region src/hooks/useNoticeTimer.ts
|
|
3
|
+
/**
|
|
4
|
+
* Runs the notice auto-close timer and reports progress updates via rAF.
|
|
5
|
+
* Returns controls to pause and resume the timer. Mirrors rc-notification@2.0
|
|
6
|
+
* useNoticeTimer.
|
|
7
|
+
*/
|
|
8
|
+
function useNoticeTimer(duration, onClose, onUpdate) {
|
|
9
|
+
const durationMs = shallowRef(0);
|
|
10
|
+
const walking = shallowRef(false);
|
|
11
|
+
let passTime = 0;
|
|
12
|
+
let lastRafTime = null;
|
|
13
|
+
let rafId = null;
|
|
14
|
+
const syncPassTime = () => {
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
if (lastRafTime !== null) passTime += now - lastRafTime;
|
|
17
|
+
lastRafTime = now;
|
|
18
|
+
};
|
|
19
|
+
const cancelStep = () => {
|
|
20
|
+
if (rafId !== null) {
|
|
21
|
+
cancelAnimationFrame(rafId);
|
|
22
|
+
rafId = null;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const onPause = () => {
|
|
26
|
+
syncPassTime();
|
|
27
|
+
walking.value = false;
|
|
28
|
+
};
|
|
29
|
+
const onResume = () => {
|
|
30
|
+
if (durationMs.value > 0) {
|
|
31
|
+
lastRafTime = Date.now();
|
|
32
|
+
walking.value = true;
|
|
33
|
+
} else onUpdate(0);
|
|
34
|
+
};
|
|
35
|
+
watch(duration, () => {
|
|
36
|
+
const next = typeof duration.value === "number" ? duration.value : 0;
|
|
37
|
+
durationMs.value = Math.max(next, 0) * 1e3;
|
|
38
|
+
passTime = 0;
|
|
39
|
+
walking.value = durationMs.value > 0;
|
|
40
|
+
}, { immediate: true });
|
|
41
|
+
watch(walking, (isWalking) => {
|
|
42
|
+
cancelStep();
|
|
43
|
+
if (!isWalking) return;
|
|
44
|
+
lastRafTime = Date.now();
|
|
45
|
+
const step = () => {
|
|
46
|
+
syncPassTime();
|
|
47
|
+
if (passTime >= durationMs.value) {
|
|
48
|
+
onUpdate(1);
|
|
49
|
+
onClose();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
onUpdate(Math.min(passTime / durationMs.value, 1));
|
|
53
|
+
rafId = requestAnimationFrame(step);
|
|
54
|
+
};
|
|
55
|
+
step();
|
|
56
|
+
}, { immediate: true });
|
|
57
|
+
onScopeDispose(() => {
|
|
58
|
+
cancelStep();
|
|
59
|
+
});
|
|
60
|
+
return [onResume, onPause];
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { useNoticeTimer as default };
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { VueNode } from '@v-c/util/dist/type';
|
|
2
1
|
import { CSSProperties, MaybeRef, TransitionGroupProps } from 'vue';
|
|
3
|
-
import {
|
|
2
|
+
import { VueNode } from '@v-c/util/dist/type';
|
|
3
|
+
import { ClosableType, Key, NotificationListConfig, Placement, StackConfig } from '../interface';
|
|
4
|
+
import { ComponentsType } from '../Notification';
|
|
5
|
+
import { NotificationClassNames, NotificationStyles } from '../NotificationList';
|
|
4
6
|
import { NotificationsProps } from '../Notifications';
|
|
5
|
-
type OptionalConfig = Partial<
|
|
7
|
+
type OptionalConfig = Partial<NotificationListConfig>;
|
|
6
8
|
export interface NotificationConfig {
|
|
7
9
|
prefixCls?: string;
|
|
8
10
|
/** Customize container. It will repeat call which means you should return same container element. */
|
|
9
11
|
getContainer?: () => HTMLElement | ShadowRoot;
|
|
10
12
|
motion?: TransitionGroupProps | ((placement: Placement) => TransitionGroupProps);
|
|
11
|
-
|
|
12
|
-
closable?: boolean | ({
|
|
13
|
-
closeIcon?: VueNode;
|
|
14
|
-
onClose?: VoidFunction;
|
|
15
|
-
} & Record<string, any>);
|
|
13
|
+
closable?: ClosableType;
|
|
16
14
|
maxCount?: number;
|
|
17
15
|
duration?: number | false | null;
|
|
18
16
|
showProgress?: boolean;
|
|
19
17
|
pauseOnHover?: boolean;
|
|
18
|
+
placement?: Placement;
|
|
19
|
+
classNames?: NotificationClassNames;
|
|
20
|
+
styles?: NotificationStyles;
|
|
21
|
+
components?: ComponentsType;
|
|
20
22
|
/** @private. Config for notification holder style. Safe to remove if refactor */
|
|
21
23
|
className?: (placement: Placement) => string;
|
|
22
24
|
/** @private. Config for notification holder style. Safe to remove if refactor */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Notifications from "../Notifications.js";
|
|
2
2
|
import { computed, createVNode, onMounted, shallowRef, unref, watch } from "vue";
|
|
3
|
+
//#region src/hooks/useNotification.tsx
|
|
3
4
|
var defaultGetContainer = () => document.body;
|
|
4
5
|
var uniqueKey = 0;
|
|
5
6
|
function mergeConfig(...objList) {
|
|
@@ -17,18 +18,22 @@ function useNotification(rootConfig = {}) {
|
|
|
17
18
|
const container = shallowRef();
|
|
18
19
|
const notificationRef = shallowRef();
|
|
19
20
|
const shareConfig = computed(() => {
|
|
20
|
-
const { getContainer, motion, prefixCls, maxCount, className, style, onAllRemoved, stack, renderNotifications, ...restConfig } = configRef.value;
|
|
21
|
+
const { getContainer, motion, prefixCls, maxCount, className, style, onAllRemoved, stack, renderNotifications, pauseOnHover, classNames, styles, components, ...restConfig } = configRef.value;
|
|
21
22
|
return restConfig;
|
|
22
23
|
});
|
|
23
24
|
const resolveContainer = () => {
|
|
24
25
|
return (configRef.value.getContainer || defaultGetContainer)();
|
|
25
26
|
};
|
|
26
|
-
const contextHolder = () => createVNode(
|
|
27
|
+
const contextHolder = () => createVNode(Notifications, {
|
|
27
28
|
"container": container.value,
|
|
28
29
|
"ref": notificationRef,
|
|
29
30
|
"prefixCls": configRef.value.prefixCls,
|
|
30
31
|
"motion": configRef.value.motion,
|
|
31
32
|
"maxCount": configRef.value.maxCount,
|
|
33
|
+
"pauseOnHover": configRef.value.pauseOnHover,
|
|
34
|
+
"classNames": configRef.value.classNames,
|
|
35
|
+
"styles": configRef.value.styles,
|
|
36
|
+
"components": configRef.value.components,
|
|
32
37
|
"className": configRef.value.className,
|
|
33
38
|
"style": configRef.value.style,
|
|
34
39
|
"onAllRemoved": configRef.value.onAllRemoved,
|
|
@@ -80,9 +85,10 @@ function useNotification(rootConfig = {}) {
|
|
|
80
85
|
default: break;
|
|
81
86
|
}
|
|
82
87
|
});
|
|
83
|
-
taskQueue.value =
|
|
88
|
+
taskQueue.value = [];
|
|
84
89
|
}
|
|
85
90
|
});
|
|
86
91
|
return [api, contextHolder];
|
|
87
92
|
}
|
|
93
|
+
//#endregion
|
|
88
94
|
export { useNotification as default };
|
package/dist/hooks/useStack.d.ts
CHANGED
|
@@ -2,5 +2,10 @@ import { ComputedRef, MaybeRef, ToRefs } from 'vue';
|
|
|
2
2
|
import { StackConfig } from '../interface';
|
|
3
3
|
type StackParams = Exclude<StackConfig, boolean>;
|
|
4
4
|
type UseStack = (config?: MaybeRef<StackConfig | undefined>) => [ComputedRef<boolean>, ToRefs<StackParams>];
|
|
5
|
+
/**
|
|
6
|
+
* Resolves the stack setting into an enabled flag and normalized stack params.
|
|
7
|
+
* Mirrors rc-notification@2.0 useStack. The `gap` config is no longer surfaced
|
|
8
|
+
* here — gap is now read from the list-content CSS `gap`/`row-gap`.
|
|
9
|
+
*/
|
|
5
10
|
declare const useStack: UseStack;
|
|
6
11
|
export default useStack;
|
package/dist/hooks/useStack.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { computed, reactive, toRefs, unref, watchEffect } from "vue";
|
|
2
|
+
//#region src/hooks/useStack.ts
|
|
2
3
|
var DEFAULT_OFFSET = 8;
|
|
3
4
|
var DEFAULT_THRESHOLD = 3;
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Resolves the stack setting into an enabled flag and normalized stack params.
|
|
7
|
+
* Mirrors rc-notification@2.0 useStack. The `gap` config is no longer surfaced
|
|
8
|
+
* here — gap is now read from the list-content CSS `gap`/`row-gap`.
|
|
9
|
+
*/
|
|
5
10
|
var useStack = (config) => {
|
|
6
11
|
const result = reactive({
|
|
7
12
|
offset: DEFAULT_OFFSET,
|
|
8
|
-
threshold: DEFAULT_THRESHOLD
|
|
9
|
-
gap: DEFAULT_GAP
|
|
13
|
+
threshold: DEFAULT_THRESHOLD
|
|
10
14
|
});
|
|
11
15
|
watchEffect(() => {
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
14
|
-
result.offset =
|
|
15
|
-
result.threshold =
|
|
16
|
-
result.gap = _config.gap ?? DEFAULT_GAP;
|
|
16
|
+
const value = unref(config);
|
|
17
|
+
if (value && typeof value === "object") {
|
|
18
|
+
result.offset = value.offset ?? DEFAULT_OFFSET;
|
|
19
|
+
result.threshold = value.threshold ?? DEFAULT_THRESHOLD;
|
|
17
20
|
}
|
|
18
21
|
});
|
|
19
22
|
return [computed(() => !!unref(config)), toRefs(result)];
|
|
20
23
|
};
|
|
21
|
-
|
|
22
|
-
export {
|
|
24
|
+
//#endregion
|
|
25
|
+
export { useStack as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { default as
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { default as useNotification, NotificationAPI, NotificationConfig } from './hooks/useNotification';
|
|
2
|
+
import { default as Notification, ComponentsType, NotificationClassNames as NoticeClassNames, NotificationProps, NotificationStyles as NoticeStyles } from './Notification';
|
|
3
|
+
import { default as NotificationList, NotificationClassNames, NotificationListProps, NotificationStyles, Placement } from './NotificationList';
|
|
4
|
+
import { useNotificationContext, useNotificationProvider } from './NotificationProvider';
|
|
5
|
+
import { default as Progress, NotificationProgressProps } from './Progress';
|
|
6
|
+
import { Key, NotificationListConfig, StackConfig } from './interface';
|
|
7
|
+
import { ClosableType, ParsedClosableConfig } from './hooks/useClosable';
|
|
8
|
+
export { Notification, NotificationList, Progress, useNotification, useNotificationContext, useNotificationProvider, };
|
|
9
|
+
export type { ClosableType, ComponentsType, Key, NoticeClassNames, NoticeStyles, NotificationAPI, NotificationClassNames, NotificationConfig, NotificationListConfig, NotificationListProps, NotificationProgressProps, NotificationProps, NotificationStyles, ParsedClosableConfig, Placement, StackConfig, };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import Progress from "./Progress.js";
|
|
2
|
+
import Notification from "./Notification.js";
|
|
3
|
+
import { useNotificationContext, useNotificationProvider } from "./NotificationProvider.js";
|
|
4
|
+
import NotificationList from "./NotificationList/index.js";
|
|
3
5
|
import useNotification from "./hooks/useNotification.js";
|
|
4
|
-
export {
|
|
6
|
+
export { Notification, NotificationList, Progress, useNotification, useNotificationContext, useNotificationProvider };
|
package/dist/interface.d.ts
CHANGED
|
@@ -1,55 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ClosableType } from './hooks/useClosable';
|
|
2
|
+
import { ComponentsType, NotificationProps } from './Notification';
|
|
3
3
|
export type Placement = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight';
|
|
4
|
-
type NoticeSemanticProps = 'wrapper';
|
|
5
4
|
export type Key = string | number;
|
|
6
|
-
export interface NoticeConfig {
|
|
7
|
-
content?: VueNode;
|
|
8
|
-
duration?: number | false | null;
|
|
9
|
-
showProgress?: boolean;
|
|
10
|
-
pauseOnHover?: boolean;
|
|
11
|
-
closeIcon?: VueNode;
|
|
12
|
-
closable?: boolean | ({
|
|
13
|
-
closeIcon?: VueNode;
|
|
14
|
-
onClose?: VoidFunction;
|
|
15
|
-
} & Record<string, any>);
|
|
16
|
-
className?: string;
|
|
17
|
-
style?: CSSProperties;
|
|
18
|
-
classNames?: {
|
|
19
|
-
[key in NoticeSemanticProps]?: string;
|
|
20
|
-
};
|
|
21
|
-
styles?: {
|
|
22
|
-
[key in NoticeSemanticProps]?: CSSProperties;
|
|
23
|
-
};
|
|
24
|
-
/** @private Internal usage. Do not override in your code */
|
|
25
|
-
props?: Record<string, any>;
|
|
26
|
-
onClose?: VoidFunction;
|
|
27
|
-
onClick?: (event: Event) => void;
|
|
28
|
-
}
|
|
29
|
-
export interface OpenConfig extends NoticeConfig {
|
|
30
|
-
key: Key;
|
|
31
|
-
placement?: Placement;
|
|
32
|
-
content?: VueNode;
|
|
33
|
-
duration?: number | false | null;
|
|
34
|
-
}
|
|
35
|
-
export type InnerOpenConfig = OpenConfig & {
|
|
36
|
-
times?: number;
|
|
37
|
-
};
|
|
38
|
-
export type Placements = Partial<Record<Placement, OpenConfig[]>>;
|
|
39
5
|
export type StackConfig = boolean | {
|
|
40
6
|
/**
|
|
41
|
-
* When
|
|
7
|
+
* When the notice count exceeds this threshold, notices will be stacked.
|
|
42
8
|
* @default 3
|
|
43
9
|
*/
|
|
44
10
|
threshold?: number;
|
|
45
11
|
/**
|
|
46
|
-
*
|
|
12
|
+
* Vertical offset applied between stacked notices.
|
|
47
13
|
* @default 8
|
|
48
14
|
*/
|
|
49
15
|
offset?: number;
|
|
50
|
-
/**
|
|
51
|
-
* Spacing between each notification when expanded.
|
|
52
|
-
*/
|
|
53
|
-
gap?: number;
|
|
54
16
|
};
|
|
55
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Configuration accepted by the public `api.open` call.
|
|
19
|
+
* Mirrors rc-notification@2.0 NotificationListConfig.
|
|
20
|
+
*/
|
|
21
|
+
export interface NotificationListConfig extends Omit<NotificationProps, 'prefixCls'> {
|
|
22
|
+
key: Key;
|
|
23
|
+
placement?: Placement;
|
|
24
|
+
times?: number;
|
|
25
|
+
}
|
|
26
|
+
export type Placements = Partial<Record<Placement, NotificationListConfig[]>>;
|
|
27
|
+
export type InnerOpenConfig = NotificationListConfig & {
|
|
28
|
+
times?: number;
|
|
29
|
+
};
|
|
30
|
+
export type { ClosableType, ComponentsType, NotificationProps, };
|