@sum-one/hooks 0.0.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.
@@ -0,0 +1,40 @@
1
+ import { DialogProps } from "element-plus";
2
+ import * as _$vue from "vue";
3
+ import { Component, ComponentPublicInstance, Ref } from "vue";
4
+
5
+ //#region ../utils/dist/index.d.mts
6
+ //#region src/typescript.d.ts
7
+ /**
8
+ * 提取组件的 props 类型
9
+ * 支持类组件和函数式组件
10
+ */
11
+ type ExtractComponentProps<T> = T extends (new (...args: any) => {
12
+ $props: infer P;
13
+ }) ? Omit<P, keyof _$vue.VNodeProps> : T extends ((props: infer P, ...args: any) => any) ? P : Record<string, any>; //#endregion
14
+ //#region src/utils.d.ts
15
+ //#endregion
16
+ //#region src/use-modal/types.d.ts
17
+ type ModalSlot = (...args: any[]) => unknown;
18
+ interface ModalOptions<T = any> {
19
+ props?: ExtractComponentProps<T>;
20
+ modalProps?: Partial<DialogProps> & {
21
+ slots?: Record<string, ModalSlot>;
22
+ };
23
+ }
24
+ interface ModalInstance<T = ComponentPublicInstance> {
25
+ /** 卸载模态框的方法 */
26
+ close: () => void;
27
+ /** 组件实例的引用 */
28
+ componentInstance: Ref<T | null>;
29
+ /** 模态框是否打开的状态 */
30
+ isOpen: Ref<boolean>;
31
+ }
32
+ //#endregion
33
+ //#region src/use-modal/index.d.ts
34
+ declare function useModal<T extends Component>(component: T, {
35
+ props,
36
+ modalProps
37
+ }: ModalOptions<T>): ModalInstance;
38
+ //#endregion
39
+ export { useModal };
40
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,78 @@
1
+ import { ElDialog } from "element-plus";
2
+ import { createApp, h, ref } from "vue";
3
+ //#region src/use-modal/index.ts
4
+ /** 动画持续时间(毫秒) */
5
+ const ANIMATION_DURATION = 1e3;
6
+ const DEFAULT_MODAL_PROPS = {
7
+ width: "50%",
8
+ top: "15vh",
9
+ closeOnClickModal: false,
10
+ closeOnPressEscape: true,
11
+ destroyOnClose: true,
12
+ draggable: true,
13
+ lockScroll: true
14
+ };
15
+ function useModal(component, { props, modalProps }) {
16
+ const open = ref(true);
17
+ const componentInstance = ref(null);
18
+ let unmountTimer = null;
19
+ const dialogComponent = () => {
20
+ const { slots: modalSlots, ...restModalProps } = modalProps ?? {};
21
+ return h(ElDialog, {
22
+ ...DEFAULT_MODAL_PROPS,
23
+ ...restModalProps,
24
+ modelValue: open.value,
25
+ beforeClose(done) {
26
+ done();
27
+ unmount();
28
+ }
29
+ }, {
30
+ default: () => h(component, {
31
+ ...props,
32
+ ref: componentInstance
33
+ }),
34
+ ...modalSlots
35
+ });
36
+ };
37
+ let app = null;
38
+ let container = null;
39
+ try {
40
+ app = createApp(dialogComponent);
41
+ container = document.createElement("div");
42
+ document.body.appendChild(container);
43
+ app.mount(container);
44
+ } catch (error) {
45
+ console.error("Failed to create modal:", error);
46
+ throw error;
47
+ }
48
+ function unmount() {
49
+ if (!open.value) return;
50
+ open.value = false;
51
+ if (unmountTimer) clearTimeout(unmountTimer);
52
+ unmountTimer = setTimeout(() => {
53
+ try {
54
+ if (app) {
55
+ app.unmount();
56
+ app = null;
57
+ }
58
+ if (container?.parentNode) {
59
+ container.parentNode.removeChild(container);
60
+ container = null;
61
+ }
62
+ } catch (error) {
63
+ console.error(error);
64
+ } finally {
65
+ unmountTimer = null;
66
+ }
67
+ }, ANIMATION_DURATION);
68
+ }
69
+ return {
70
+ close: unmount,
71
+ componentInstance,
72
+ isOpen: open
73
+ };
74
+ }
75
+ //#endregion
76
+ export { useModal };
77
+
78
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/use-modal/index.ts"],"sourcesContent":["import type { DialogProps } from 'element-plus'\nimport type { Component, ComponentPublicInstance, VNode } from 'vue'\nimport type { ModalInstance, ModalOptions } from './types'\nimport { ElDialog } from 'element-plus'\nimport { createApp, h, ref } from 'vue'\n\n/** 动画持续时间(毫秒) */\nconst ANIMATION_DURATION = 1000\n\nconst DEFAULT_MODAL_PROPS: Partial<DialogProps> = {\n width: '50%',\n top: '15vh',\n closeOnClickModal: false,\n closeOnPressEscape: true,\n destroyOnClose: true,\n draggable: true,\n lockScroll: true\n} as const\n\nexport function useModal<T extends Component>(component: T, { props, modalProps }: ModalOptions<T>): ModalInstance {\n const open = ref(true)\n const componentInstance = ref<ComponentPublicInstance | null>(null)\n let unmountTimer: ReturnType<typeof setTimeout> | null = null\n\n const dialogComponent = (): VNode => {\n const { slots: modalSlots, ...restModalProps } = modalProps ?? {}\n const dialogProps = {\n ...DEFAULT_MODAL_PROPS,\n ...restModalProps,\n modelValue: open.value,\n beforeClose(done: () => void) {\n done()\n unmount()\n }\n }\n const slots = {\n default: () => h(component, {\n ...props,\n ref: componentInstance\n }),\n ...modalSlots\n }\n return h(ElDialog, dialogProps, slots)\n }\n\n let app: ReturnType<typeof createApp> | null = null\n let container: HTMLElement | null = null\n\n try {\n app = createApp(dialogComponent)\n container = document.createElement('div')\n document.body.appendChild(container)\n app.mount(container)\n }\n catch (error) {\n console.error('Failed to create modal:', error)\n throw error\n }\n\n function unmount(): void {\n if (!open.value)\n return\n open.value = false\n if (unmountTimer)\n clearTimeout(unmountTimer)\n\n unmountTimer = setTimeout(() => {\n try {\n if (app) {\n app.unmount()\n app = null\n }\n if (container?.parentNode) {\n container.parentNode.removeChild(container)\n container = null\n }\n }\n catch (error) {\n console.error(error)\n }\n finally {\n unmountTimer = null\n }\n }, ANIMATION_DURATION)\n }\n\n return {\n close: unmount,\n componentInstance,\n isOpen: open\n }\n}\n"],"mappings":";;;;AAOA,MAAM,qBAAqB;AAE3B,MAAM,sBAA4C;CAChD,OAAO;CACP,KAAK;CACL,mBAAmB;CACnB,oBAAoB;CACpB,gBAAgB;CAChB,WAAW;CACX,YAAY;CACb;AAED,SAAgB,SAA8B,WAAc,EAAE,OAAO,cAA8C;CACjH,MAAM,OAAO,IAAI,KAAK;CACtB,MAAM,oBAAoB,IAAoC,KAAK;CACnE,IAAI,eAAqD;CAEzD,MAAM,wBAA+B;EACnC,MAAM,EAAE,OAAO,YAAY,GAAG,mBAAmB,cAAc,EAAE;EAiBjE,OAAO,EAAE,UAAU;GAfjB,GAAG;GACH,GAAG;GACH,YAAY,KAAK;GACjB,YAAY,MAAkB;IAC5B,MAAM;IACN,SAAS;;GAUiB,EAAE;GAN9B,eAAe,EAAE,WAAW;IAC1B,GAAG;IACH,KAAK;IACN,CAAC;GACF,GAAG;GAEgC,CAAC;;CAGxC,IAAI,MAA2C;CAC/C,IAAI,YAAgC;CAEpC,IAAI;EACF,MAAM,UAAU,gBAAgB;EAChC,YAAY,SAAS,cAAc,MAAM;EACzC,SAAS,KAAK,YAAY,UAAU;EACpC,IAAI,MAAM,UAAU;UAEf,OAAO;EACZ,QAAQ,MAAM,2BAA2B,MAAM;EAC/C,MAAM;;CAGR,SAAS,UAAgB;EACvB,IAAI,CAAC,KAAK,OACR;EACF,KAAK,QAAQ;EACb,IAAI,cACF,aAAa,aAAa;EAE5B,eAAe,iBAAiB;GAC9B,IAAI;IACF,IAAI,KAAK;KACP,IAAI,SAAS;KACb,MAAM;;IAER,IAAI,WAAW,YAAY;KACzB,UAAU,WAAW,YAAY,UAAU;KAC3C,YAAY;;YAGT,OAAO;IACZ,QAAQ,MAAM,MAAM;aAEd;IACN,eAAe;;KAEhB,mBAAmB;;CAGxB,OAAO;EACL,OAAO;EACP;EACA,QAAQ;EACT"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@sum-one/hooks",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "packageManager": "pnpm@10.28.2",
6
+ "exports": {
7
+ "./package.json": "./package.json",
8
+ ".": {
9
+ "types": "./dist/index.d.mts",
10
+ "import": "./dist/index.mjs"
11
+ }
12
+ },
13
+ "main": "./dist/index.mjs",
14
+ "types": "./dist/index.d.mts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "dev": "tsdown --watch",
20
+ "build": "tsdown"
21
+ },
22
+ "publishConfig": {
23
+ "access": "public",
24
+ "registry": "https://registry.npmjs.org/"
25
+ },
26
+ "peerDependencies": {
27
+ "element-plus": ">=2.0.0 <3.0.0",
28
+ "vue": ">=3.2.0 <4.0.0"
29
+ },
30
+ "peerDependenciesMeta": {
31
+ "element-plus": {
32
+ "optional": true
33
+ }
34
+ },
35
+ "dependencies": {
36
+ "@vueuse/core": "^14.3.0"
37
+ },
38
+ "devDependencies": {
39
+ "@sum-one/config": "workspace:*",
40
+ "@sum-one/utils": "workspace:*",
41
+ "tsdown": "^0.22.0"
42
+ }
43
+ }