@peng_kai/kit 0.2.44 → 0.2.46

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.
@@ -1,15 +1,16 @@
1
1
  import { Modal as AntModal } from 'ant-design-vue';
2
2
  import { tryOnUnmounted } from '@vueuse/core';
3
- import { createVNode, defineComponent, isProxy, reactive, toRef, toRefs } from 'vue';
3
+ import { createVNode, defineComponent, isProxy, onMounted, reactive, toRef, toRefs } from 'vue';
4
4
  import type { Component } from 'vue';
5
5
  import type { ModalProps } from 'ant-design-vue';
6
6
  import type { ComponentEmit, ComponentProps } from 'vue-component-type-helpers';
7
7
  import type { Writable } from 'type-fest';
8
8
  import { useTemplateRefs } from '../../vue';
9
9
 
10
- interface AntdModalProps extends ModalProps {
10
+ interface AntdModalProps<Comp extends Component = any> extends ModalProps {
11
11
  class?: string
12
12
  rejectOnClose?: boolean
13
+ opener?: (open: (newCompProps?: Writable<ComponentProps<Comp>>) => Promise<ExtractConfirmArgs<UnwrapNonNullable<ComponentEmit<Comp>>>>) => void
13
14
  [k: string]: any
14
15
  }
15
16
 
@@ -41,7 +42,7 @@ const defaultModalProps: AntdModalProps = {
41
42
  */
42
43
  export function useAntdModal<Comp extends Component>(
43
44
  comp: IComponentConfig<Comp> | Comp,
44
- modalProps = defaultModalProps,
45
+ modalProps: AntdModalProps<Comp> = defaultModalProps,
45
46
  ) {
46
47
  const _comp = ({ props: {}, type: 'body', ...((comp as any)?.is ? comp : { is: comp }) }) as Required<IComponentConfig<Comp>>;
47
48
  const compProps = reactive(_comp.props);
@@ -62,21 +63,23 @@ export function useAntdModal<Comp extends Component>(
62
63
 
63
64
  const _onClose = (e?: any) => {
64
65
  if (_modalProps.rejectOnClose)
65
- promiseResolvers.reject(e ?? new Error('Modal Cancel'));
66
+ promiseResolvers?.reject(e ?? new Error('Modal Cancel'));
66
67
  else
67
- promiseResolvers.resolve(undefined as any);
68
+ promiseResolvers?.resolve(undefined as any);
68
69
  };
69
70
 
70
71
  const open = (
71
- newCompProps?: Partial<typeof compProps>,
72
+ newCompProps?: typeof compProps,
72
73
  newAntdModalProps?: Omit<Partial<ModalProps>, 'open'>,
73
74
  ) => {
74
- if (_modalProps.open)
75
- return Promise.reject(new Error('Modal is already open'));
76
-
77
75
  Object.assign(_modalProps, newAntdModalProps);
78
76
  Object.assign(compProps, newCompProps);
79
77
 
78
+ if (_modalProps.open) {
79
+ // return Promise.reject(new Error('Modal is already open'));
80
+ return;
81
+ }
82
+
80
83
  promiseResolvers = Promise.withResolvers();
81
84
  _modalProps.open = true;
82
85
 
@@ -86,16 +89,20 @@ export function useAntdModal<Comp extends Component>(
86
89
  _modalProps.open = false;
87
90
  promiseResolvers.resolve(ev);
88
91
  };
89
- const close = (ev: any) => {
92
+ const close = (reason?: any) => {
90
93
  _modalProps.open = false;
91
- _onClose(ev);
94
+ _onClose(reason);
92
95
  };
93
96
 
94
97
  const PresetComponent = defineComponent({
95
- render() {
96
- return createVNode(AntModal, _modalProps, {
97
- [modalSlotName]: () => createVNode(_comp.is, compProps as any),
98
- });
98
+ setup() {
99
+ onMounted(() => _modalProps.opener?.(open as any));
100
+
101
+ return () => {
102
+ return createVNode(AntModal, _modalProps, {
103
+ [modalSlotName]: () => createVNode(_comp.is, compProps as any),
104
+ });
105
+ };
99
106
  },
100
107
  });
101
108
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@peng_kai/kit",
3
3
  "type": "module",
4
- "version": "0.2.44",
4
+ "version": "0.2.46",
5
5
  "description": "",
6
6
  "author": "",
7
7
  "license": "ISC",
@@ -0,0 +1,15 @@
1
+ import { computed, nextTick, onActivated, onDeactivated, onMounted, ref } from 'vue';
2
+
3
+ /**
4
+ * 判断组件是否已经被激活/挂载
5
+ */
6
+ export function useIsActivated() {
7
+ const isMounted = ref(false);
8
+ const isActivated = ref(true);
9
+
10
+ onMounted(() => setTimeout(() => isMounted.value = true));
11
+ onActivated(() => nextTick(() => isActivated.value = true));
12
+ onDeactivated(() => isActivated.value = false);
13
+
14
+ return computed(() => isMounted.value && isActivated.value);
15
+ }
@@ -1,7 +1,7 @@
1
1
  import { onMounted, ref } from 'vue';
2
2
 
3
3
  /**
4
- * 指示组件是否已挂载
4
+ * 【弃用,使用 useIsActivated 代替】指示组件是否已挂载
5
5
  */
6
6
  export function useIsMounted() {
7
7
  const mounted = ref(false);
@@ -0,0 +1,66 @@
1
+ import type { Simplify } from 'type-fest';
2
+ import { onActivated, onBeforeUnmount, onDeactivated, watch } from 'vue';
3
+ import { useRoute, useRouter } from 'vue-router';
4
+ import { useRouteHash } from '../../libs/vueuse';
5
+
6
+ const MODAL_NAME_KEY = 'modal';
7
+
8
+ /**
9
+ * 解析 URL Hash 中的弹窗参数
10
+ * @param modalName 弹窗名称
11
+ * @param hash URL Hash
12
+ */
13
+ export function parseModalParams<T = any>(modalName?: string, hash?: string) {
14
+ const hashStr = (hash || location.hash).replace(/^#/, '');
15
+ const hashParams = new URLSearchParams(hashStr);
16
+ const isTargetModal = (hashParams.get(MODAL_NAME_KEY) && modalName === undefined) || (hashParams.get(MODAL_NAME_KEY) === modalName);
17
+
18
+ if (isTargetModal) {
19
+ type GetParams<T> = 0 extends 1 & T
20
+ ? { modal: string, [key: string]: string } : Simplify<NonNullable<T>
21
+ & { modal: string }>;
22
+ return Object.fromEntries(hashParams.entries()) as GetParams<T>;
23
+ }
24
+ }
25
+
26
+ /**
27
+ * 同步弹窗参数到 URL Hash
28
+ * @param modalName 弹窗名称
29
+ * @param modalParams 弹窗参数
30
+ */
31
+ export function useSyncModalParamsToHash(modalName: string, modalParams: Record<string, any>) {
32
+ const hashStr = useRouteHash(undefined, { route: useRoute(), router: useRouter() });
33
+
34
+ function syncParamsToHash() {
35
+ const _hashStr = hashStr.value ?? '';
36
+ const hashParams = new URLSearchParams(_hashStr.replace(/^#/, ''));
37
+
38
+ if (hashParams.get(MODAL_NAME_KEY) == null)
39
+ hashParams.set(MODAL_NAME_KEY, modalName);
40
+
41
+ if (hashParams.get(MODAL_NAME_KEY) === modalName) {
42
+ Object.keys(modalParams).forEach((k) => {
43
+ const v = modalParams[k];
44
+ v && hashParams.set(k, v);
45
+ });
46
+
47
+ hashStr.value = `#${hashParams.toString()}`;
48
+ }
49
+ }
50
+
51
+ function removeParamsFromHash() {
52
+ const _hashStr = hashStr.value ?? '';
53
+ const hashParams = new URLSearchParams(_hashStr.replace(/^#/, ''));
54
+
55
+ if (!hashParams.get(MODAL_NAME_KEY) || hashParams.get(MODAL_NAME_KEY) === modalName) {
56
+ hashParams.delete(MODAL_NAME_KEY);
57
+ Object.keys(modalParams).forEach(k => hashParams.delete(k));
58
+ hashStr.value = `#${hashParams.toString()}`;
59
+ }
60
+ }
61
+
62
+ watch(modalParams, syncParamsToHash, { immediate: true, deep: true });
63
+ onActivated(syncParamsToHash);
64
+ onBeforeUnmount(removeParamsFromHash);
65
+ onDeactivated(removeParamsFromHash);
66
+ }
package/vue/index.ts CHANGED
@@ -3,4 +3,5 @@ export { useTemplateRefs } from './hooks/useTemplateRefs';
3
3
  export { useTeleportTarget, createTeleportSelectors } from './hooks/useTeleportTarget';
4
4
  export { useIsMounted } from './hooks/useIsMounted';
5
5
  export { useIsDark } from './hooks/useIsDark';
6
+ export { useSyncModalParamsToHash, parseModalParams } from './hooks/useSyncModalParams';
6
7
  export { InfiniteQuery } from './components/infinite-query';