@v-c/notification 0.0.3 → 2.0.0-beta.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.
Files changed (67) hide show
  1. package/dist/Notification.d.ts +286 -0
  2. package/dist/Notification.js +237 -0
  3. package/dist/NotificationList/Content.d.ts +88 -0
  4. package/dist/NotificationList/Content.js +74 -0
  5. package/dist/NotificationList/index.d.ts +156 -0
  6. package/dist/NotificationList/index.js +204 -0
  7. package/dist/NotificationProvider.d.ts +20 -1
  8. package/dist/NotificationProvider.js +16 -3
  9. package/dist/Notifications.d.ts +136 -8
  10. package/dist/Notifications.js +118 -109
  11. package/dist/Progress.d.ts +8 -0
  12. package/dist/Progress.js +18 -0
  13. package/dist/hooks/useClosable.d.ts +22 -0
  14. package/dist/hooks/useClosable.js +33 -0
  15. package/dist/hooks/useListPosition/index.d.ts +17 -0
  16. package/dist/hooks/useListPosition/index.js +48 -0
  17. package/dist/hooks/useListPosition/useSizes.d.ts +13 -0
  18. package/dist/hooks/useListPosition/useSizes.js +29 -0
  19. package/dist/hooks/useNoticeTimer.d.ts +6 -0
  20. package/dist/hooks/useNoticeTimer.js +71 -0
  21. package/dist/hooks/useNotification.d.ts +8 -24
  22. package/dist/hooks/useNotification.js +33 -22
  23. package/dist/hooks/useStack.d.ts +8 -4
  24. package/dist/hooks/useStack.js +15 -18
  25. package/dist/index.d.ts +7 -5
  26. package/dist/index.js +5 -3
  27. package/docs/context.vue +1 -1
  28. package/docs/hooks.vue +4 -4
  29. package/docs/index.less +62 -143
  30. package/docs/maxCount.vue +1 -1
  31. package/docs/showProgress.vue +2 -2
  32. package/docs/stack.vue +1 -1
  33. package/package.json +5 -4
  34. package/src/Notification.tsx +363 -0
  35. package/src/NotificationList/Content.tsx +84 -0
  36. package/src/NotificationList/index.tsx +298 -0
  37. package/src/NotificationProvider.tsx +23 -3
  38. package/src/Notifications.tsx +103 -87
  39. package/src/Progress.tsx +23 -0
  40. package/src/hooks/useClosable.ts +54 -0
  41. package/src/hooks/useListPosition/index.ts +85 -0
  42. package/src/hooks/useListPosition/useSizes.ts +42 -0
  43. package/src/hooks/useNoticeTimer.ts +96 -0
  44. package/src/hooks/useNotification.tsx +54 -80
  45. package/src/hooks/useStack.ts +26 -18
  46. package/src/index.ts +31 -5
  47. package/tests/index.spec.tsx +200 -0
  48. package/vite.config.ts +4 -3
  49. package/vitest.config.ts +3 -1
  50. package/dist/Notice.cjs +0 -235
  51. package/dist/Notice.d.ts +0 -15
  52. package/dist/Notice.js +0 -227
  53. package/dist/NoticeList.cjs +0 -170
  54. package/dist/NoticeList.d.ts +0 -13
  55. package/dist/NoticeList.js +0 -164
  56. package/dist/NotificationProvider.cjs +0 -14
  57. package/dist/Notifications.cjs +0 -146
  58. package/dist/_virtual/rolldown_runtime.cjs +0 -21
  59. package/dist/hooks/useNotification.cjs +0 -93
  60. package/dist/hooks/useStack.cjs +0 -27
  61. package/dist/index.cjs +0 -7
  62. package/dist/interface.cjs +0 -1
  63. package/dist/interface.d.ts +0 -55
  64. package/dist/interface.js +0 -0
  65. package/src/Notice.tsx +0 -212
  66. package/src/NoticeList.tsx +0 -219
  67. package/src/interface.ts +0 -61
@@ -1,140 +1,149 @@
1
- import NoticeList_default from "./NoticeList.js";
2
- import { Teleport, createVNode, defineComponent, isVNode, mergeDefaults, shallowRef, watch } from "vue";
1
+ import NotificationList from "./NotificationList/index.js";
2
+ import { Teleport, createVNode, defineComponent, isVNode, 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
- var defaults = { prefixCls: "vc-notification" };
7
- var Notifications_default = /* @__PURE__ */ defineComponent((props, { expose }) => {
8
- const configList = shallowRef([]);
9
- const onNoticeClose = (key) => {
10
- const config = configList.value.find((item) => item.key === key);
11
- const closable = config?.closable;
12
- (closable && typeof closable === "object" ? closable : {}).onClose?.();
13
- config?.onClose?.();
14
- configList.value = configList.value.filter((item) => item.key !== key);
15
- };
16
- expose({
17
- open: (config) => {
18
- const list = configList.value;
19
- let clone = [...configList.value];
20
- const index = clone.findIndex((item) => item.key === config.key);
21
- const innerConfig = { ...config };
22
- if (index >= 0) {
23
- innerConfig.times = (list[index]?.times || 0) + 1;
24
- clone[index] = innerConfig;
25
- } else {
26
- innerConfig.times = 0;
27
- clone.push(innerConfig);
28
- }
29
- const maxCount = props.maxCount ?? 0;
30
- if (maxCount > 0 && clone.length > maxCount) clone = clone.slice(-maxCount);
31
- configList.value = clone;
32
- },
33
- close: onNoticeClose,
34
- destroy: () => {
35
- configList.value = [];
36
- }
37
- });
38
- const placements = shallowRef({});
39
- watch(configList, () => {
40
- const nextPlacements = {};
41
- configList.value.forEach((config) => {
42
- const { placement = "topRight" } = config;
43
- if (placement) {
44
- nextPlacements[placement] = nextPlacements[placement] || [];
45
- nextPlacements[placement].push(config);
46
- }
47
- });
48
- Object.keys(placements.value).forEach((_placement) => {
49
- const placement = _placement;
50
- nextPlacements[placement] = nextPlacements[placement] || [];
51
- });
52
- placements.value = nextPlacements;
53
- });
54
- const onAllNoticeRemoved = (placement) => {
55
- const clone = { ...placements.value };
56
- if (!(clone[placement] || []).length) delete clone[placement];
57
- placements.value = clone;
58
- };
59
- const emptyRef = shallowRef(false);
60
- watch(placements, () => {
61
- if (Object.keys(placements.value).length > 0) emptyRef.value = true;
62
- else if (emptyRef.value) {
63
- props?.onAllRemoved?.();
64
- emptyRef.value = false;
65
- }
66
- });
67
- return () => {
68
- let _slot;
69
- const { container } = props;
70
- const prefixCls = props.prefixCls ?? defaults.prefixCls ?? "";
71
- if (!container) return null;
72
- return createVNode(Teleport, { "to": container }, _isSlot(_slot = Object.keys(placements.value).map((placement) => {
73
- const placementConfigList = placements.value[placement];
74
- const list = createVNode(NoticeList_default, {
75
- "key": placement,
76
- "configList": placementConfigList,
77
- "placement": placement,
78
- "prefixCls": prefixCls,
79
- "class": props.className?.(placement),
80
- "style": props.style?.(placement),
81
- "motion": props.motion,
82
- "stack": props.stack,
83
- "onAllNoticeRemoved": () => onAllNoticeRemoved(placement),
84
- "onNoticeClose": onNoticeClose
85
- }, null);
86
- return props.renderNotifications ? props.renderNotifications(list, {
87
- prefixCls,
88
- key: placement
89
- }) : list;
90
- })) ? _slot : { default: () => [_slot] });
91
- };
92
- }, {
93
- props: /* @__PURE__ */ mergeDefaults({
7
+ var Notifications = /* @__PURE__ */ defineComponent({
8
+ name: "Notifications",
9
+ inheritAttrs: false,
10
+ props: {
94
11
  prefixCls: {
95
12
  type: String,
96
- required: false,
97
- default: void 0
13
+ default: "vc-notification"
98
14
  },
99
- motion: {
100
- type: [Object, Function],
101
- required: false,
15
+ classNames: {
16
+ type: Object,
102
17
  default: void 0
103
18
  },
104
- container: {
105
- required: false,
19
+ styles: {
20
+ type: Object,
106
21
  default: void 0
107
22
  },
108
- maxCount: {
109
- type: Number,
110
- required: false,
23
+ components: {
24
+ type: Object,
111
25
  default: void 0
112
26
  },
113
27
  className: {
114
28
  type: Function,
115
- required: false,
116
29
  default: void 0
117
30
  },
118
31
  style: {
119
32
  type: Function,
120
- required: false,
121
33
  default: void 0
122
34
  },
123
- onAllRemoved: {
124
- required: false,
35
+ container: {
36
+ type: Object,
37
+ default: void 0
38
+ },
39
+ motion: {
40
+ type: [Object, Function],
41
+ default: void 0
42
+ },
43
+ maxCount: {
44
+ type: Number,
45
+ default: void 0
46
+ },
47
+ pauseOnHover: {
48
+ type: Boolean,
125
49
  default: void 0
126
50
  },
127
51
  stack: {
128
52
  type: [Boolean, Object],
129
- required: false,
53
+ default: void 0
54
+ },
55
+ onAllRemoved: {
56
+ type: Function,
130
57
  default: void 0
131
58
  },
132
59
  renderNotifications: {
133
60
  type: Function,
134
- required: false,
135
61
  default: void 0
136
62
  }
137
- }, defaults),
138
- name: "Notifications"
63
+ },
64
+ setup(props, { expose }) {
65
+ const configList = shallowRef([]);
66
+ const placements = shallowRef({});
67
+ const emptyRef = shallowRef(false);
68
+ expose({
69
+ open: (config) => {
70
+ const list = configList.value;
71
+ let clone = [...list];
72
+ const index = clone.findIndex((item) => item.key === config.key);
73
+ const innerConfig = { ...config };
74
+ if (index >= 0) {
75
+ innerConfig.times = (list[index]?.times ?? 0) + 1;
76
+ clone[index] = innerConfig;
77
+ } else {
78
+ innerConfig.times = 0;
79
+ clone.push(innerConfig);
80
+ }
81
+ const maxCount = props.maxCount ?? 0;
82
+ if (maxCount > 0 && clone.length > maxCount) clone = clone.slice(-maxCount);
83
+ configList.value = clone;
84
+ },
85
+ close: (key) => {
86
+ configList.value = configList.value.filter((item) => item.key !== key);
87
+ },
88
+ destroy: () => {
89
+ configList.value = [];
90
+ }
91
+ });
92
+ watch(configList, () => {
93
+ const next = {};
94
+ configList.value.forEach((config) => {
95
+ const placement = config.placement ?? "topRight";
96
+ next[placement] = next[placement] || [];
97
+ next[placement].push(config);
98
+ });
99
+ Object.keys(placements.value).forEach((placement) => {
100
+ next[placement] = next[placement] || [];
101
+ });
102
+ placements.value = next;
103
+ }, { immediate: true });
104
+ function onAllNoticeRemoved(placement) {
105
+ const clone = { ...placements.value };
106
+ if (!(clone[placement] || []).length) delete clone[placement];
107
+ placements.value = clone;
108
+ }
109
+ watch(placements, () => {
110
+ if (Object.keys(placements.value).length > 0) emptyRef.value = true;
111
+ else if (emptyRef.value) {
112
+ props.onAllRemoved?.();
113
+ emptyRef.value = false;
114
+ }
115
+ });
116
+ return () => {
117
+ let _slot;
118
+ const { container, prefixCls = "vc-notification" } = props;
119
+ if (!container) return null;
120
+ const placementList = Object.keys(placements.value);
121
+ return createVNode(Teleport, { "to": container }, _isSlot(_slot = placementList.map((placement) => {
122
+ const list = createVNode(NotificationList, {
123
+ "key": placement,
124
+ "configList": placements.value[placement],
125
+ "placement": placement,
126
+ "prefixCls": prefixCls,
127
+ "pauseOnHover": props.pauseOnHover,
128
+ "classNames": props.classNames,
129
+ "styles": props.styles,
130
+ "components": props.components,
131
+ "class": props.className?.(placement),
132
+ "style": props.style?.(placement),
133
+ "motion": props.motion,
134
+ "stack": props.stack,
135
+ "onNoticeClose": (key) => {
136
+ configList.value = configList.value.filter((item) => item.key !== key);
137
+ },
138
+ "onAllRemoved": onAllNoticeRemoved
139
+ }, null);
140
+ return props.renderNotifications ? props.renderNotifications(list, {
141
+ prefixCls,
142
+ key: placement
143
+ }) : list;
144
+ })) ? _slot : { default: () => [_slot] });
145
+ };
146
+ }
139
147
  });
140
- export { Notifications_default as default };
148
+ //#endregion
149
+ export { Notifications as default };
@@ -0,0 +1,8 @@
1
+ import { CSSProperties, FunctionalComponent } from 'vue';
2
+ export interface NotificationProgressProps {
3
+ class?: string;
4
+ style?: CSSProperties;
5
+ percent: number;
6
+ }
7
+ declare const Progress: FunctionalComponent<NotificationProgressProps>;
8
+ export default Progress;
@@ -0,0 +1,18 @@
1
+ import { createVNode } from "vue";
2
+ //#region src/Progress.tsx
3
+ var Progress = (props) => {
4
+ return createVNode("progress", {
5
+ "class": props.class,
6
+ "max": "100",
7
+ "value": props.percent,
8
+ "style": props.style
9
+ }, null);
10
+ };
11
+ Progress.props = [
12
+ "class",
13
+ "style",
14
+ "percent"
15
+ ];
16
+ Progress.inheritAttrs = false;
17
+ //#endregion
18
+ export { Progress as default };
@@ -0,0 +1,22 @@
1
+ import { VueNode } from '@v-c/util/dist/type';
2
+ import { ComputedRef, MaybeRef } from 'vue';
3
+ export type ClosableConfig = {
4
+ closeIcon?: VueNode;
5
+ disabled?: boolean;
6
+ onClose?: VoidFunction;
7
+ } & Record<string, any>;
8
+ export type ClosableType = boolean | ClosableConfig | null | undefined;
9
+ export interface ParsedClosableConfig {
10
+ closeIcon: VueNode;
11
+ disabled: boolean;
12
+ onClose?: VoidFunction;
13
+ [key: string]: any;
14
+ }
15
+ /**
16
+ * Normalize the closable option into an enabled flag, parsed config, and aria props.
17
+ */
18
+ export default function useClosable(closable: MaybeRef<ClosableType>): [
19
+ ComputedRef<boolean>,
20
+ ComputedRef<ParsedClosableConfig>,
21
+ ComputedRef<Record<string, any>>
22
+ ];
@@ -0,0 +1,33 @@
1
+ import { computed, unref } from "vue";
2
+ import pickAttrs from "@v-c/util/dist/pickAttrs";
3
+ //#region src/hooks/useClosable.ts
4
+ /**
5
+ * Normalize the closable option into an enabled flag, parsed config, and aria props.
6
+ */
7
+ function useClosable(closable) {
8
+ const closableObj = computed(() => {
9
+ const value = unref(closable);
10
+ if (value === false) return {
11
+ closeIcon: null,
12
+ disabled: true
13
+ };
14
+ if (typeof value === "object" && value !== null) return value;
15
+ return {};
16
+ });
17
+ const enabled = computed(() => !!unref(closable));
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
+ return [
27
+ enabled,
28
+ closableConfig,
29
+ computed(() => pickAttrs(closableConfig.value, true))
30
+ ];
31
+ }
32
+ //#endregion
33
+ export { useClosable as default };
@@ -0,0 +1,17 @@
1
+ import { ComputedRef, MaybeRef } from 'vue';
2
+ import { StackConfig } from '../useStack';
3
+ type Key = string | number | symbol;
4
+ export interface ConfigItem {
5
+ key: Key;
6
+ }
7
+ /**
8
+ * Calculates each notification's position and the full list height.
9
+ */
10
+ export default function useListPosition(configList: MaybeRef<readonly ConfigItem[]>, stack: MaybeRef<StackConfig | undefined>, gap?: MaybeRef<number>): [
11
+ ComputedRef<Map<string, number>>,
12
+ (key: string, node: HTMLElement | null) => void,
13
+ ComputedRef<number>,
14
+ ComputedRef<number | undefined>,
15
+ ComputedRef<number | undefined>
16
+ ];
17
+ export {};
@@ -0,0 +1,48 @@
1
+ import useSizes from "./useSizes.js";
2
+ import { computed, unref } from "vue";
3
+ //#region src/hooks/useListPosition/index.ts
4
+ /**
5
+ * Calculates each notification's position and the full list height.
6
+ */
7
+ function useListPosition(configList, stack, gap = 0) {
8
+ const [sizeMap, setNodeSize] = useSizes();
9
+ const result = computed(() => {
10
+ const list = unref(configList);
11
+ const stackValue = unref(stack);
12
+ const gapValue = unref(gap) ?? 0;
13
+ let offsetY = 0;
14
+ let nextTotalHeight = 0;
15
+ const stackThreshold = stackValue?.threshold ?? 0;
16
+ const positions = /* @__PURE__ */ new Map();
17
+ let topNoticeHeight;
18
+ let topNoticeWidth;
19
+ list.slice().reverse().forEach((config, index) => {
20
+ const key = String(config.key);
21
+ const height = sizeMap.value[key]?.height ?? 0;
22
+ const y = stackValue && index > 0 ? offsetY + (stackValue.offset ?? 0) - height : offsetY;
23
+ positions.set(key, y);
24
+ if (index === 0) {
25
+ topNoticeHeight = height;
26
+ topNoticeWidth = sizeMap.value[key]?.width ?? 0;
27
+ }
28
+ if (!stackValue || index < stackThreshold) nextTotalHeight = Math.max(nextTotalHeight, y + height);
29
+ if (stackValue) offsetY = y + height;
30
+ else offsetY += height + gapValue;
31
+ });
32
+ return {
33
+ positions,
34
+ totalHeight: nextTotalHeight,
35
+ topNoticeHeight,
36
+ topNoticeWidth
37
+ };
38
+ });
39
+ return [
40
+ computed(() => result.value.positions),
41
+ setNodeSize,
42
+ computed(() => result.value.totalHeight),
43
+ computed(() => result.value.topNoticeHeight),
44
+ computed(() => result.value.topNoticeWidth)
45
+ ];
46
+ }
47
+ //#endregion
48
+ export { useListPosition as default };
@@ -0,0 +1,13 @@
1
+ import { Ref } from 'vue';
2
+ export interface NodeSize {
3
+ width: number;
4
+ height: number;
5
+ }
6
+ export type NodeSizeMap = Record<string, NodeSize>;
7
+ /**
8
+ * Track measured node sizes by key. Returns the size map ref and a setter callback.
9
+ */
10
+ export default function useSizes(): [
11
+ Ref<NodeSizeMap>,
12
+ (key: string, node: HTMLElement | null) => void
13
+ ];
@@ -0,0 +1,29 @@
1
+ import { ref } from "vue";
2
+ //#region src/hooks/useListPosition/useSizes.ts
3
+ /**
4
+ * Track measured node sizes by key. Returns the size map ref and a setter callback.
5
+ */
6
+ function useSizes() {
7
+ const sizeMap = ref({});
8
+ function setNodeSize(key, node) {
9
+ if (!node) {
10
+ if (!(key in sizeMap.value)) return;
11
+ const { [key]: _, ...rest } = sizeMap.value;
12
+ sizeMap.value = rest;
13
+ return;
14
+ }
15
+ const next = {
16
+ width: node.offsetWidth,
17
+ height: node.offsetHeight
18
+ };
19
+ const prev = sizeMap.value[key];
20
+ if (prev && prev.width === next.width && prev.height === next.height) return;
21
+ sizeMap.value = {
22
+ ...sizeMap.value,
23
+ [key]: next
24
+ };
25
+ }
26
+ return [sizeMap, setNodeSize];
27
+ }
28
+ //#endregion
29
+ export { useSizes as default };
@@ -0,0 +1,6 @@
1
+ import { ComputedRef, MaybeRef } from 'vue';
2
+ /**
3
+ * Run the auto-close timer for a notice and report progress updates.
4
+ * Returns controls to pause and resume the timer.
5
+ */
6
+ export default function useNoticeTimer(duration: MaybeRef<number | false | null | undefined>, onClose: () => void, onUpdate: (ptg: number) => void): [() => void, () => void, ComputedRef<number>];
@@ -0,0 +1,71 @@
1
+ import { computed, onBeforeUnmount, shallowRef, unref, watch } from "vue";
2
+ import raf from "@v-c/util/dist/raf";
3
+ //#region src/hooks/useNoticeTimer.ts
4
+ /**
5
+ * Run the auto-close timer for a notice and report progress updates.
6
+ * Returns controls to pause and resume the timer.
7
+ */
8
+ function useNoticeTimer(duration, onClose, onUpdate) {
9
+ const durationMs = computed(() => {
10
+ const value = unref(duration);
11
+ return Math.max(typeof value === "number" ? value : 0, 0) * 1e3;
12
+ });
13
+ const walking = shallowRef(durationMs.value > 0);
14
+ const passTime = shallowRef(0);
15
+ let lastRafTime = null;
16
+ let rafId = null;
17
+ function syncPassTime() {
18
+ const now = Date.now();
19
+ if (lastRafTime !== null) passTime.value += now - lastRafTime;
20
+ lastRafTime = now;
21
+ }
22
+ function cancelRaf() {
23
+ if (rafId !== null) {
24
+ raf.cancel(rafId);
25
+ rafId = null;
26
+ }
27
+ }
28
+ function onPause() {
29
+ syncPassTime();
30
+ walking.value = false;
31
+ }
32
+ function onResume() {
33
+ if (durationMs.value > 0) {
34
+ lastRafTime = Date.now();
35
+ walking.value = true;
36
+ } else onUpdate(0);
37
+ }
38
+ watch(durationMs, () => {
39
+ passTime.value = 0;
40
+ lastRafTime = null;
41
+ walking.value = durationMs.value > 0;
42
+ });
43
+ watch(walking, (isWalking) => {
44
+ cancelRaf();
45
+ if (!isWalking) return;
46
+ function step() {
47
+ syncPassTime();
48
+ if (passTime.value >= durationMs.value) {
49
+ onUpdate(1);
50
+ onClose();
51
+ } else {
52
+ onUpdate(Math.min(passTime.value / durationMs.value, 1));
53
+ rafId = raf(step);
54
+ }
55
+ }
56
+ step();
57
+ }, { immediate: true });
58
+ onBeforeUnmount(() => {
59
+ cancelRaf();
60
+ });
61
+ return [
62
+ onResume,
63
+ onPause,
64
+ computed(() => {
65
+ if (durationMs.value <= 0) return 0;
66
+ return Math.min(passTime.value / durationMs.value, 1);
67
+ })
68
+ ];
69
+ }
70
+ //#endregion
71
+ export { useNoticeTimer as default };
@@ -1,31 +1,15 @@
1
1
  import { VueNode } from '@v-c/util/dist/type';
2
- import { CSSProperties, MaybeRef, TransitionGroupProps } from 'vue';
3
- import { Key, OpenConfig, Placement, StackConfig } from '../interface';
2
+ import { MaybeRef } from 'vue';
3
+ import { NotificationListConfig, Placement } from '../NotificationList';
4
4
  import { NotificationsProps } from '../Notifications';
5
- type OptionalConfig = Partial<OpenConfig>;
6
- export interface NotificationConfig {
7
- prefixCls?: string;
8
- /** Customize container. It will repeat call which means you should return same container element. */
5
+ type Key = string | number | symbol;
6
+ type OptionalConfig = Partial<NotificationListConfig>;
7
+ export interface NotificationConfig extends Omit<NotificationsProps, 'container'> {
8
+ placement?: Placement;
9
9
  getContainer?: () => HTMLElement | ShadowRoot;
10
- motion?: TransitionGroupProps | ((placement: Placement) => TransitionGroupProps);
11
- closeIcon?: VueNode;
12
- closable?: boolean | ({
13
- closeIcon?: VueNode;
14
- onClose?: VoidFunction;
15
- } & Record<string, any>);
16
- maxCount?: number;
10
+ closable?: NotificationListConfig['closable'];
17
11
  duration?: number | false | null;
18
- showProgress?: boolean;
19
- pauseOnHover?: boolean;
20
- /** @private. Config for notification holder style. Safe to remove if refactor */
21
- className?: (placement: Placement) => string;
22
- /** @private. Config for notification holder style. Safe to remove if refactor */
23
- style?: (placement: Placement) => CSSProperties;
24
- /** @private Trigger when all the notification closed. */
25
- onAllRemoved?: VoidFunction;
26
- stack?: StackConfig;
27
- /** @private Slot for style in Notifications */
28
- renderNotifications?: NotificationsProps['renderNotifications'];
12
+ showProgress?: NotificationListConfig['showProgress'];
29
13
  }
30
14
  export interface NotificationAPI {
31
15
  open: (config: OptionalConfig) => void;
@@ -1,13 +1,14 @@
1
- import Notifications_default from "../Notifications.js";
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) {
6
7
  const clone = {};
7
8
  objList.forEach((obj) => {
8
9
  if (obj) Object.keys(obj).forEach((key) => {
9
- const val = obj[key];
10
- if (val !== void 0) clone[key] = val;
10
+ const value = obj[key];
11
+ if (value !== void 0) clone[key] = value;
11
12
  });
12
13
  });
13
14
  return clone;
@@ -15,37 +16,46 @@ function mergeConfig(...objList) {
15
16
  function useNotification(rootConfig = {}) {
16
17
  const configRef = computed(() => unref(rootConfig) || {});
17
18
  const container = shallowRef();
18
- const notificationRef = shallowRef();
19
+ const notificationsRef = shallowRef();
20
+ const taskQueue = shallowRef([]);
19
21
  const shareConfig = computed(() => {
20
- const { getContainer, motion, prefixCls, maxCount, className, style, onAllRemoved, stack, renderNotifications, ...restConfig } = configRef.value;
21
- return restConfig;
22
+ const { placement, closable, duration, showProgress } = configRef.value;
23
+ return {
24
+ placement,
25
+ closable,
26
+ duration,
27
+ showProgress
28
+ };
22
29
  });
23
- const resolveContainer = () => {
30
+ function resolveContainer() {
24
31
  return (configRef.value.getContainer || defaultGetContainer)();
25
- };
26
- const contextHolder = () => createVNode(Notifications_default, {
32
+ }
33
+ const contextHolder = () => createVNode(Notifications, {
27
34
  "container": container.value,
28
- "ref": notificationRef,
35
+ "ref": notificationsRef,
29
36
  "prefixCls": configRef.value.prefixCls,
30
37
  "motion": configRef.value.motion,
31
38
  "maxCount": configRef.value.maxCount,
39
+ "pauseOnHover": configRef.value.pauseOnHover,
40
+ "classNames": configRef.value.classNames,
41
+ "styles": configRef.value.styles,
42
+ "components": configRef.value.components,
32
43
  "className": configRef.value.className,
33
44
  "style": configRef.value.style,
34
45
  "onAllRemoved": configRef.value.onAllRemoved,
35
46
  "stack": configRef.value.stack,
36
47
  "renderNotifications": configRef.value.renderNotifications
37
48
  }, null);
38
- const taskQueue = shallowRef([]);
39
49
  const api = {
40
50
  open(config) {
41
- const mergedConfig = mergeConfig(shareConfig.value, config);
42
- if (mergedConfig.key === null || mergedConfig.key === void 0) {
43
- mergedConfig.key = `vc-notification-${uniqueKey}`;
51
+ const merged = mergeConfig(shareConfig.value, config);
52
+ if (merged.key === null || merged.key === void 0) {
53
+ merged.key = `vc-notification-${uniqueKey}`;
44
54
  uniqueKey += 1;
45
55
  }
46
56
  taskQueue.value = [...taskQueue.value, {
47
57
  type: "open",
48
- config: mergedConfig
58
+ config: merged
49
59
  }];
50
60
  },
51
61
  close(key) {
@@ -65,24 +75,25 @@ function useNotification(rootConfig = {}) {
65
75
  container.value = resolveContainer();
66
76
  });
67
77
  watch(taskQueue, () => {
68
- if (notificationRef.value && taskQueue.value.length) {
69
- taskQueue.value.forEach((task) => {
78
+ if (notificationsRef.value && taskQueue.value.length) {
79
+ const tasks = taskQueue.value;
80
+ tasks.forEach((task) => {
70
81
  switch (task.type) {
71
82
  case "open":
72
- notificationRef.value?.open(task.config);
83
+ notificationsRef.value?.open(task.config);
73
84
  break;
74
85
  case "close":
75
- notificationRef.value?.close(task.key);
86
+ notificationsRef.value?.close(task.key);
76
87
  break;
77
88
  case "destroy":
78
- notificationRef.value?.destroy();
89
+ notificationsRef.value?.destroy();
79
90
  break;
80
- default: break;
81
91
  }
82
92
  });
83
- taskQueue.value = taskQueue.value.filter((task) => !taskQueue.value.includes(task));
93
+ taskQueue.value = taskQueue.value.filter((task) => !tasks.includes(task));
84
94
  }
85
95
  });
86
96
  return [api, contextHolder];
87
97
  }
98
+ //#endregion
88
99
  export { useNotification as default };