@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.
Files changed (56) hide show
  1. package/dist/Notification.d.ts +59 -0
  2. package/dist/Notification.js +301 -0
  3. package/dist/NotificationList/Content.d.ts +11 -0
  4. package/dist/NotificationList/Content.js +60 -0
  5. package/dist/NotificationList/index.d.ts +35 -0
  6. package/dist/NotificationList/index.js +224 -0
  7. package/dist/NotificationProvider.js +3 -1
  8. package/dist/Notifications.d.ts +9 -3
  9. package/dist/Notifications.js +45 -21
  10. package/dist/Progress.d.ts +8 -0
  11. package/dist/Progress.js +31 -0
  12. package/dist/hooks/useClosable.d.ts +17 -0
  13. package/dist/hooks/useClosable.js +34 -0
  14. package/dist/hooks/useListPosition/index.d.ts +18 -0
  15. package/dist/hooks/useListPosition/index.js +41 -0
  16. package/dist/hooks/useListPosition/useSizes.d.ts +10 -0
  17. package/dist/hooks/useListPosition/useSizes.js +31 -0
  18. package/dist/hooks/useNoticeTimer.d.ts +7 -0
  19. package/dist/hooks/useNoticeTimer.js +63 -0
  20. package/dist/hooks/useNotification.d.ts +10 -8
  21. package/dist/hooks/useNotification.js +10 -4
  22. package/dist/hooks/useStack.d.ts +5 -0
  23. package/dist/hooks/useStack.js +13 -10
  24. package/dist/index.d.ts +9 -6
  25. package/dist/index.js +5 -3
  26. package/dist/interface.d.ts +18 -43
  27. package/package.json +3 -3
  28. package/src/Notification.tsx +326 -0
  29. package/src/NotificationList/Content.tsx +66 -0
  30. package/src/NotificationList/index.tsx +282 -0
  31. package/src/Notifications.tsx +58 -64
  32. package/src/Progress.tsx +27 -0
  33. package/src/hooks/useClosable.ts +53 -0
  34. package/src/hooks/useListPosition/index.ts +69 -0
  35. package/src/hooks/useListPosition/useSizes.ts +43 -0
  36. package/src/hooks/useNoticeTimer.ts +85 -0
  37. package/src/hooks/useNotification.tsx +30 -28
  38. package/src/hooks/useStack.ts +12 -8
  39. package/src/index.ts +47 -6
  40. package/src/interface.ts +28 -44
  41. package/vite.config.ts +4 -3
  42. package/dist/Notice.cjs +0 -235
  43. package/dist/Notice.d.ts +0 -15
  44. package/dist/Notice.js +0 -227
  45. package/dist/NoticeList.cjs +0 -170
  46. package/dist/NoticeList.d.ts +0 -13
  47. package/dist/NoticeList.js +0 -164
  48. package/dist/NotificationProvider.cjs +0 -14
  49. package/dist/Notifications.cjs +0 -146
  50. package/dist/_virtual/rolldown_runtime.cjs +0 -21
  51. package/dist/hooks/useNotification.cjs +0 -93
  52. package/dist/hooks/useStack.cjs +0 -27
  53. package/dist/index.cjs +0 -7
  54. package/dist/interface.cjs +0 -1
  55. package/src/Notice.tsx +0 -212
  56. package/src/NoticeList.tsx +0 -219
@@ -1,11 +1,17 @@
1
- import { VueNode } from '@v-c/util/dist/type';
2
1
  import { CSSProperties, TransitionGroupProps } from 'vue';
3
- import { Key, OpenConfig, Placement, StackConfig } from './interface.ts';
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: OpenConfig) => void;
25
+ open: (config: NotificationListConfig) => void;
20
26
  close: (key: Key) => void;
21
27
  destroy: () => void;
22
28
  }
@@ -1,26 +1,27 @@
1
- import NoticeList_default from "./NoticeList.js";
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 Notifications_default = /* @__PURE__ */ defineComponent((props, { expose }) => {
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 : {}).onClose?.();
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 = [...configList.value];
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 || 0) + 1;
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 nextPlacements = {};
41
+ const next = {};
41
42
  configList.value.forEach((config) => {
42
- const { placement = "topRight" } = config;
43
- if (placement) {
44
- nextPlacements[placement] = nextPlacements[placement] || [];
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((_placement) => {
49
- const placement = _placement;
50
- nextPlacements[placement] = nextPlacements[placement] || [];
47
+ Object.keys(placements.value).forEach((placement) => {
48
+ next[placement] = next[placement] || [];
51
49
  });
52
- placements.value = nextPlacements;
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((placement) => {
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(NoticeList_default, {
73
+ const list = createVNode(NotificationList, {
75
74
  "key": placement,
76
75
  "configList": placementConfigList,
77
76
  "placement": placement,
78
77
  "prefixCls": prefixCls,
79
- "class": props.className?.(placement),
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
- "onAllNoticeRemoved": () => onAllNoticeRemoved(placement),
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
- export { Notifications_default as default };
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;
@@ -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 { Key, OpenConfig, Placement, StackConfig } from '../interface';
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<OpenConfig>;
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
- closeIcon?: VueNode;
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 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) {
@@ -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(Notifications_default, {
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 = taskQueue.value.filter((task) => !taskQueue.value.includes(task));
88
+ taskQueue.value = [];
84
89
  }
85
90
  });
86
91
  return [api, contextHolder];
87
92
  }
93
+ //#endregion
88
94
  export { useNotification as default };
@@ -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;
@@ -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
- var DEFAULT_GAP = 16;
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 _config = unref(config);
13
- if (_config && typeof _config === "object") {
14
- result.offset = _config.offset ?? DEFAULT_OFFSET;
15
- result.threshold = _config.threshold ?? DEFAULT_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
- var useStack_default = useStack;
22
- export { useStack_default as default };
24
+ //#endregion
25
+ export { useStack as default };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
- import { NotificationAPI, NotificationConfig, default as useNotification } from './hooks/useNotification';
2
- import { default as Notice } from './Notice';
3
- import { useNotificationProvider } from './NotificationProvider';
4
- export { Notice, useNotification, useNotificationProvider };
5
- export type { NotificationAPI, NotificationConfig };
6
- export type { NoticeProps } from './Notice';
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 Notice_default from "./Notice.js";
2
- import { useNotificationProvider } from "./NotificationProvider.js";
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 { Notice_default as Notice, useNotification, useNotificationProvider };
6
+ export { Notification, NotificationList, Progress, useNotification, useNotificationContext, useNotificationProvider };
@@ -1,55 +1,30 @@
1
- import { VueNode } from '@v-c/util/dist/type';
2
- import { CSSProperties } from 'vue';
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 number is greater than threshold, notifications will be stacked together.
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
- * Offset when notifications are stacked together.
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
- export {};
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, };