@peng_kai/kit 0.2.44 → 0.2.45

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);
@@ -68,7 +69,7 @@ export function useAntdModal<Comp extends Component>(
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
75
  if (_modalProps.open)
@@ -86,16 +87,20 @@ export function useAntdModal<Comp extends Component>(
86
87
  _modalProps.open = false;
87
88
  promiseResolvers.resolve(ev);
88
89
  };
89
- const close = (ev: any) => {
90
+ const close = (reason?: any) => {
90
91
  _modalProps.open = false;
91
- _onClose(ev);
92
+ _onClose(reason);
92
93
  };
93
94
 
94
95
  const PresetComponent = defineComponent({
95
- render() {
96
- return createVNode(AntModal, _modalProps, {
97
- [modalSlotName]: () => createVNode(_comp.is, compProps as any),
98
- });
96
+ setup() {
97
+ onMounted(() => _modalProps.opener?.(open as any));
98
+
99
+ return () => {
100
+ return createVNode(AntModal, _modalProps, {
101
+ [modalSlotName]: () => createVNode(_comp.is, compProps as any),
102
+ });
103
+ };
99
104
  },
100
105
  });
101
106
 
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.45",
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(false);
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';