From 307c89fd5d5d5f1e88aa32c21df64c74f86a4adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E4=BA=AC=E8=BE=89?= <1292077619@qq.com> Date: Wed, 21 Sep 2022 11:00:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20useModal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 24 + .vscode/extensions.json | 3 + README.md | 73 +++ example/.gitignore | 24 + example/.vscode/extensions.json | 3 + example/README.md | 16 + example/index.html | 13 + example/package.json | 20 + example/public/vite.svg | 1 + example/src/App.vue | 31 ++ example/src/assets/vue.svg | 1 + example/src/components/HelloWorld.vue | 38 ++ example/src/main.ts | 5 + example/src/style.css | 81 ++++ example/src/vite-env.d.ts | 7 + example/tsconfig.json | 18 + example/tsconfig.node.json | 9 + example/vite.config.ts | 7 + index.html | 13 + package.json | 72 +++ playgound/App.vue | 0 playgound/Modal.vue | 0 playgound/main.ts | 0 pnpm-lock.yaml | 650 ++++++++++++++++++++++++++ src/CreateModal.vue | 21 + src/Modal.ts | 50 ++ src/ModalProvider.vue | 10 + src/index.ts | 10 + src/useModal.tsx | 140 ++++++ src/vite-env.d.ts | 7 + tsconfig-build.json | 9 + tsconfig.json | 20 + tsconfig.node.json | 9 + vite.config.ts | 28 ++ 34 files changed, 1413 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 README.md create mode 100644 example/.gitignore create mode 100644 example/.vscode/extensions.json create mode 100644 example/README.md create mode 100644 example/index.html create mode 100644 example/package.json create mode 100644 example/public/vite.svg create mode 100644 example/src/App.vue create mode 100644 example/src/assets/vue.svg create mode 100644 example/src/components/HelloWorld.vue create mode 100644 example/src/main.ts create mode 100644 example/src/style.css create mode 100644 example/src/vite-env.d.ts create mode 100644 example/tsconfig.json create mode 100644 example/tsconfig.node.json create mode 100644 example/vite.config.ts create mode 100644 index.html create mode 100644 package.json create mode 100644 playgound/App.vue create mode 100644 playgound/Modal.vue create mode 100644 playgound/main.ts create mode 100644 pnpm-lock.yaml create mode 100644 src/CreateModal.vue create mode 100644 src/Modal.ts create mode 100644 src/ModalProvider.vue create mode 100644 src/index.ts create mode 100644 src/useModal.tsx create mode 100644 src/vite-env.d.ts create mode 100644 tsconfig-build.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a7cea0b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["Vue.volar"] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..b0fe490 --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# vue-modal-provider +[nice-modal-react](https://github.com/eBay/nice-modal-react) vue implementation. Simple to use and manage modal. + +benefit: +- Create modal without losing context +- No need to maintain show variables +- Using promise interact + +## Installation +```bash +$ npm install vue-modal-provider +``` +## Examples +Embed your application with ModalProvider +```vue + + + + +``` +Create modal component +```vue + + + + + +``` +Use in the view +```vue + + + + +``` \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/example/.vscode/extensions.json b/example/.vscode/extensions.json new file mode 100644 index 0000000..a7cea0b --- /dev/null +++ b/example/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["Vue.volar"] +} diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..30b15e2 --- /dev/null +++ b/example/README.md @@ -0,0 +1,16 @@ +# Vue 3 + TypeScript + Vite + +This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` + + diff --git a/example/package.json b/example/package.json new file mode 100644 index 0000000..f030d10 --- /dev/null +++ b/example/package.json @@ -0,0 +1,20 @@ +{ + "name": "example", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview" + }, + "dependencies": { + "vue": "^3.2.37" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^3.1.0", + "typescript": "^4.6.4", + "vite": "^3.1.0", + "vue-tsc": "^0.40.4" + } +} \ No newline at end of file diff --git a/example/public/vite.svg b/example/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/example/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/example/src/App.vue b/example/src/App.vue new file mode 100644 index 0000000..76ebf08 --- /dev/null +++ b/example/src/App.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/example/src/assets/vue.svg b/example/src/assets/vue.svg new file mode 100644 index 0000000..770e9d3 --- /dev/null +++ b/example/src/assets/vue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/example/src/components/HelloWorld.vue b/example/src/components/HelloWorld.vue new file mode 100644 index 0000000..5230910 --- /dev/null +++ b/example/src/components/HelloWorld.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/example/src/main.ts b/example/src/main.ts new file mode 100644 index 0000000..2425c0f --- /dev/null +++ b/example/src/main.ts @@ -0,0 +1,5 @@ +import { createApp } from 'vue' +import './style.css' +import App from './App.vue' + +createApp(App).mount('#app') diff --git a/example/src/style.css b/example/src/style.css new file mode 100644 index 0000000..0192f9a --- /dev/null +++ b/example/src/style.css @@ -0,0 +1,81 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/example/src/vite-env.d.ts b/example/src/vite-env.d.ts new file mode 100644 index 0000000..323c78a --- /dev/null +++ b/example/src/vite-env.d.ts @@ -0,0 +1,7 @@ +/// + +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/example/tsconfig.json b/example/tsconfig.json new file mode 100644 index 0000000..d4aefa2 --- /dev/null +++ b/example/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/example/tsconfig.node.json b/example/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/example/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/example/vite.config.ts b/example/vite.config.ts new file mode 100644 index 0000000..315212d --- /dev/null +++ b/example/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()] +}) diff --git a/index.html b/index.html new file mode 100644 index 0000000..143557b --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Vue + TS + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..eefbc65 --- /dev/null +++ b/package.json @@ -0,0 +1,72 @@ +{ + "author": "Jinghui_S", + "description": "A modal state manager for vue. ", + "name": "vue-modal-provider", + "private": false, + "version": "0.0.0", + "main": "dist/vue-modal-provider.cjs.js", + "module": "dist/vue-modal-provider.es.js", + "types": "dist/types/index.d.ts", + "exports": { + ".": { + "import": "./dist/vue-modal-provider.es.js", + "require": "./dist/vue-modal-provider.cjs.js" + } + }, + "files": [ + "dist", + "package.json" + ], + "scripts": { + "dev": "vite", + "build": "vite build && rimraf types && tsc --build tsconfig-build.json", + "preview": "vite preview", + "release": "pnpm build && npx release-it", + "clean": "rm -rf node_modules **/*/node_modules" + }, + "keywords": [ + "vue", + "vue-modal", + "vue-modal-provider" + ], + "release-it": { + "git": { + "commitMessage": "chore(release): ${version}", + "tagName": "v${version}" + }, + "plugins": { + "@release-it/conventional-changelog": { + "preset": "angular", + "infile": "CHANGELOG.md", + "ignoreRecommendedBump": true + } + }, + "github": { + "release": true, + "web": true + }, + "npm": { + "publish": true + } + }, + "license": "MIT", + "homepage": "https://github.com/JinghuiS/vue-modal-provider", + "repository": { + "type": "git", + "url": "https://github.com/JinghuiS/vue-modal-provider" + }, + "bugs": { + "url": "https://github.com/JinghuiS/vue-modal-provider/issues", + "email": "1292077619@qq.com" + }, + "dependencies": { + "vue": "^3.2.37" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^3.1.0", + "rimraf": "^3.0.2", + "typescript": "^4.6.4", + "vite": "^3.1.0", + "vue-tsc": "^0.40.4" + } +} diff --git a/playgound/App.vue b/playgound/App.vue new file mode 100644 index 0000000..e69de29 diff --git a/playgound/Modal.vue b/playgound/Modal.vue new file mode 100644 index 0000000..e69de29 diff --git a/playgound/main.ts b/playgound/main.ts new file mode 100644 index 0000000..e69de29 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..d37b7f5 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,650 @@ +lockfileVersion: 5.4 + +specifiers: + '@vitejs/plugin-vue': ^3.1.0 + rimraf: ^3.0.2 + typescript: ^4.6.4 + vite: ^3.1.0 + vue: ^3.2.37 + vue-tsc: ^0.40.4 + +dependencies: + vue: 3.2.39 + +devDependencies: + '@vitejs/plugin-vue': 3.1.0_vite@3.1.3+vue@3.2.39 + rimraf: 3.0.2 + typescript: 4.8.3 + vite: 3.1.3 + vue-tsc: 0.40.13_typescript@4.8.3 + +packages: + + /@babel/helper-string-parser/7.18.10: + resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier/7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + + /@babel/parser/7.19.1: + resolution: {integrity: sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.19.0 + + /@babel/types/7.19.0: + resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.18.10 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + + /@esbuild/android-arm/0.15.8: + resolution: {integrity: sha512-CyEWALmn+no/lbgbAJsbuuhT8s2J19EJGHkeyAwjbFJMrj80KJ9zuYsoAvidPTU7BgBf87r/sgae8Tw0dbOc4Q==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dependencies: + esbuild-wasm: 0.15.8 + dev: true + optional: true + + /@esbuild/linux-loong64/0.15.8: + resolution: {integrity: sha512-pE5RQsOTSERCtfZdfCT25wzo7dfhOSlhAXcsZmuvRYhendOv7djcdvtINdnDp2DAjP17WXlBB4nBO6sHLczmsg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@vitejs/plugin-vue/3.1.0_vite@3.1.3+vue@3.2.39: + resolution: {integrity: sha512-fmxtHPjSOEIRg6vHYDaem+97iwCUg/uSIaTzp98lhELt2ISOQuDo2hbkBdXod0g15IhfPMQmAxh4heUks2zvDA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^3.0.0 + vue: ^3.2.25 + dependencies: + vite: 3.1.3 + vue: 3.2.39 + dev: true + + /@volar/code-gen/0.40.13: + resolution: {integrity: sha512-4gShBWuMce868OVvgyA1cU5WxHbjfEme18Tw6uVMfweZCF5fB2KECG0iPrA9D54vHk3FeHarODNwgIaaFfUBlA==} + dependencies: + '@volar/source-map': 0.40.13 + dev: true + + /@volar/source-map/0.40.13: + resolution: {integrity: sha512-dbdkAB2Nxb0wLjAY5O64o3ywVWlAGONnBIoKAkXSf6qkGZM+nJxcizsoiI66K+RHQG0XqlyvjDizfnTxr+6PWg==} + dependencies: + '@vue/reactivity': 3.2.38 + dev: true + + /@volar/typescript-faster/0.40.13: + resolution: {integrity: sha512-uy+TlcFkKoNlKEnxA4x5acxdxLyVDIXGSc8cYDNXpPKjBKXrQaetzCzlO3kVBqu1VLMxKNGJMTKn35mo+ILQmw==} + dependencies: + semver: 7.3.7 + dev: true + + /@volar/vue-language-core/0.40.13: + resolution: {integrity: sha512-QkCb8msi2KUitTdM6Y4kAb7/ZlEvuLcbBFOC2PLBlFuoZwyxvSP7c/dBGmKGtJlEvMX0LdCyrg5V2aBYxD38/Q==} + dependencies: + '@volar/code-gen': 0.40.13 + '@volar/source-map': 0.40.13 + '@vue/compiler-core': 3.2.39 + '@vue/compiler-dom': 3.2.39 + '@vue/compiler-sfc': 3.2.39 + '@vue/reactivity': 3.2.39 + '@vue/shared': 3.2.39 + dev: true + + /@volar/vue-typescript/0.40.13: + resolution: {integrity: sha512-o7bNztwjs8JmbQjVkrnbZUOfm7q4B8ZYssETISN1tRaBdun6cfNqgpkvDYd+VUBh1O4CdksvN+5BUNnwAz4oCQ==} + dependencies: + '@volar/code-gen': 0.40.13 + '@volar/typescript-faster': 0.40.13 + '@volar/vue-language-core': 0.40.13 + dev: true + + /@vue/compiler-core/3.2.39: + resolution: {integrity: sha512-mf/36OWXqWn0wsC40nwRRGheR/qoID+lZXbIuLnr4/AngM0ov8Xvv8GHunC0rKRIkh60bTqydlqTeBo49rlbqw==} + dependencies: + '@babel/parser': 7.19.1 + '@vue/shared': 3.2.39 + estree-walker: 2.0.2 + source-map: 0.6.1 + + /@vue/compiler-dom/3.2.39: + resolution: {integrity: sha512-HMFI25Be1C8vLEEv1hgEO1dWwG9QQ8LTTPmCkblVJY/O3OvWx6r1+zsox5mKPMGvqYEZa6l8j+xgOfUspgo7hw==} + dependencies: + '@vue/compiler-core': 3.2.39 + '@vue/shared': 3.2.39 + + /@vue/compiler-sfc/3.2.39: + resolution: {integrity: sha512-fqAQgFs1/BxTUZkd0Vakn3teKUt//J3c420BgnYgEOoVdTwYpBTSXCMJ88GOBCylmUBbtquGPli9tVs7LzsWIA==} + dependencies: + '@babel/parser': 7.19.1 + '@vue/compiler-core': 3.2.39 + '@vue/compiler-dom': 3.2.39 + '@vue/compiler-ssr': 3.2.39 + '@vue/reactivity-transform': 3.2.39 + '@vue/shared': 3.2.39 + estree-walker: 2.0.2 + magic-string: 0.25.9 + postcss: 8.4.16 + source-map: 0.6.1 + + /@vue/compiler-ssr/3.2.39: + resolution: {integrity: sha512-EoGCJ6lincKOZGW+0Ky4WOKsSmqL7hp1ZYgen8M7u/mlvvEQUaO9tKKOy7K43M9U2aA3tPv0TuYYQFrEbK2eFQ==} + dependencies: + '@vue/compiler-dom': 3.2.39 + '@vue/shared': 3.2.39 + + /@vue/reactivity-transform/3.2.39: + resolution: {integrity: sha512-HGuWu864zStiWs9wBC6JYOP1E00UjMdDWIG5W+FpUx28hV3uz9ODOKVNm/vdOy/Pvzg8+OcANxAVC85WFBbl3A==} + dependencies: + '@babel/parser': 7.19.1 + '@vue/compiler-core': 3.2.39 + '@vue/shared': 3.2.39 + estree-walker: 2.0.2 + magic-string: 0.25.9 + + /@vue/reactivity/3.2.38: + resolution: {integrity: sha512-6L4myYcH9HG2M25co7/BSo0skKFHpAN8PhkNPM4xRVkyGl1K5M3Jx4rp5bsYhvYze2K4+l+pioN4e6ZwFLUVtw==} + dependencies: + '@vue/shared': 3.2.38 + dev: true + + /@vue/reactivity/3.2.39: + resolution: {integrity: sha512-vlaYX2a3qMhIZfrw3Mtfd+BuU+TZmvDrPMa+6lpfzS9k/LnGxkSuf0fhkP0rMGfiOHPtyKoU9OJJJFGm92beVQ==} + dependencies: + '@vue/shared': 3.2.39 + + /@vue/runtime-core/3.2.39: + resolution: {integrity: sha512-xKH5XP57JW5JW+8ZG1khBbuLakINTgPuINKL01hStWLTTGFOrM49UfCFXBcFvWmSbci3gmJyLl2EAzCaZWsx8g==} + dependencies: + '@vue/reactivity': 3.2.39 + '@vue/shared': 3.2.39 + + /@vue/runtime-dom/3.2.39: + resolution: {integrity: sha512-4G9AEJP+sLhsqf5wXcyKVWQKUhI+iWfy0hWQgea+CpaTD7BR0KdQzvoQdZhwCY6B3oleSyNLkLAQwm0ya/wNoA==} + dependencies: + '@vue/runtime-core': 3.2.39 + '@vue/shared': 3.2.39 + csstype: 2.6.21 + + /@vue/server-renderer/3.2.39_vue@3.2.39: + resolution: {integrity: sha512-1yn9u2YBQWIgytFMjz4f/t0j43awKytTGVptfd3FtBk76t1pd8mxbek0G/DrnjJhd2V7mSTb5qgnxMYt8Z5iSQ==} + peerDependencies: + vue: 3.2.39 + dependencies: + '@vue/compiler-ssr': 3.2.39 + '@vue/shared': 3.2.39 + vue: 3.2.39 + + /@vue/shared/3.2.38: + resolution: {integrity: sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==} + dev: true + + /@vue/shared/3.2.39: + resolution: {integrity: sha512-D3dl2ZB9qE6mTuWPk9RlhDeP1dgNRUKC3NJxji74A4yL8M2MwlhLKUC/49WHjrNzSPug58fWx/yFbaTzGAQSBw==} + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /csstype/2.6.21: + resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} + + /esbuild-android-64/0.15.8: + resolution: {integrity: sha512-bVh8FIKOolF7/d4AMzt7xHlL0Ljr+mYKSHI39TJWDkybVWHdn6+4ODL3xZGHOxPpdRpitemXA1WwMKYBsw8dGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dependencies: + esbuild-wasm: 0.15.8 + dev: true + optional: true + + /esbuild-android-arm64/0.15.8: + resolution: {integrity: sha512-ReAMDAHuo0H1h9LxRabI6gwYPn8k6WiUeyxuMvx17yTrJO+SCnIfNc/TSPFvDwtK9MiyiKG/2dBYHouT/M0BXQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-64/0.15.8: + resolution: {integrity: sha512-KaKcGfJ+yto7Fo5gAj3xwxHMd1fBIKatpCHK8znTJLVv+9+NN2/tIPBqA4w5rBwjX0UqXDeIE2v1xJP+nGEXgA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-arm64/0.15.8: + resolution: {integrity: sha512-8tjEaBgAKnXCkP7bhEJmEqdG9HEV6oLkF36BrMzpfW2rgaw0c48Zrxe+9RlfeGvs6gDF4w+agXyTjikzsS3izw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-64/0.15.8: + resolution: {integrity: sha512-jaxcsGHYzn2L0/lffON2WfH4Nc+d/EwozVTP5K2v016zxMb5UQMhLoJzvLgBqHT1SG0B/mO+a+THnJCMVg15zw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-arm64/0.15.8: + resolution: {integrity: sha512-2xp2UlljMvX8HExtcg7VHaeQk8OBU0CSl1j18B5CcZmSDkLF9p3utuMXIopG3a08fr9Hv+Dz6+seSXUow/G51w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-32/0.15.8: + resolution: {integrity: sha512-9u1E54BRz1FQMl86iaHK146+4ID2KYNxL3trLZT4QLLx3M7Q9n4lGG3lrzqUatGR2cKy8c33b0iaCzsItZWkFg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-64/0.15.8: + resolution: {integrity: sha512-4HxrsN9eUzJXdVGMTYA5Xler82FuZUu21bXKN42zcLHHNKCAMPUzD62I+GwDhsdgUBAUj0tRXDdsQHgaP6v0HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm/0.15.8: + resolution: {integrity: sha512-7DVBU9SFjX4+vBwt8tHsUCbE6Vvl6y6FQWHAgyw1lybC5gULqn/WnjHYHN2/LJaZRsDBvxWT4msEgwLGq1Wd3Q==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm64/0.15.8: + resolution: {integrity: sha512-1OCm7Aq0tEJT70PbxmHSGYDLYP8DKH8r4Nk7/XbVzWaduo9beCjGBB+tGZIHK6DdTQ3h00/4Tb/70YMH/bOtKg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-mips64le/0.15.8: + resolution: {integrity: sha512-yeFoNPVFPEzZvFYBfUQNG2TjGRaCyV1E27OcOg4LOtnGrxb2wA+mkW3luckyv1CEyd00mpAg7UdHx8nlx3ghgA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-ppc64le/0.15.8: + resolution: {integrity: sha512-CEyMMUUNabXibw8OSNmBXhOIGhnjNVl5Lpseiuf00iKN0V47oqDrbo4dsHz1wH62m49AR8iG8wpDlTqfYgKbtg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-riscv64/0.15.8: + resolution: {integrity: sha512-OCGSOaspMUjexSCU8ZiA0UnV/NiRU+s2vIfEcAQWQ6u32R+2luyfh/4ZaY6jFbylJE07Esc/yRvb9Q5fXuClXA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-s390x/0.15.8: + resolution: {integrity: sha512-RHdpdfxRTSrZXZJlFSLazFU4YwXLB5Rgf6Zr5rffqSsO4y9JybgtKO38bFwxZNlDXliYISXN/YROKrG9s7mZQA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-netbsd-64/0.15.8: + resolution: {integrity: sha512-VolFFRatBH09T5QMWhiohAWCOien1R1Uz9K0BRVVTBgBaVBt7eArsXTKxVhUgRf2vwu2c2SXkuP0r7HLG0eozw==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-openbsd-64/0.15.8: + resolution: {integrity: sha512-HTAPlg+n4kUeE/isQxlCfsOz0xJGNoT5LJ9oYZWFKABfVf4Ycu7Zlf5ITgOnrdheTkz8JeL/gISIOCFAoOXrSA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-sunos-64/0.15.8: + resolution: {integrity: sha512-qMP/jR/FzcIOwKj+W+Lb+8Cfr8GZHbHUJxAPi7DUhNZMQ/6y7sOgRzlOSpRrbbUntrRZh0MqOyDhJ3Gpo6L1QA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /esbuild-wasm/0.15.8: + resolution: {integrity: sha512-Y7uCl5RNO4URjlemjdx++ukVHEMt5s5AfMWYUnMiK4Sry+pPCvQIctzXq6r6FKCyGKjX6/NGMCqR2OX6aLxj0w==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-32/0.15.8: + resolution: {integrity: sha512-RKR1QHh4iWzjUhkP8Yqi75PPz/KS+b8zw3wUrzw6oAkj+iU5Qtyj61ZDaSG3Qf2vc6hTIUiPqVTqBH0NpXFNwg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-64/0.15.8: + resolution: {integrity: sha512-ag9ptYrsizgsR+PQE8QKeMqnosLvAMonQREpLw4evA4FFgOBMLEat/dY/9txbpozTw9eEOYyD3a4cE9yTu20FA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-arm64/0.15.8: + resolution: {integrity: sha512-dbpAb0VyPaUs9mgw65KRfQ9rqiWCHpNzrJusoPu+LpEoswosjt/tFxN7cd2l68AT4qWdBkzAjDLRon7uqMeWcg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild/0.15.8: + resolution: {integrity: sha512-Remsk2dmr1Ia65sU+QasE6svJbsHe62lzR+CnjpUvbZ+uSYo1SitiOWPRfZQkCu82YWZBBKXiD/j0i//XWMZ+Q==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.15.8 + '@esbuild/linux-loong64': 0.15.8 + esbuild-android-64: 0.15.8 + esbuild-android-arm64: 0.15.8 + esbuild-darwin-64: 0.15.8 + esbuild-darwin-arm64: 0.15.8 + esbuild-freebsd-64: 0.15.8 + esbuild-freebsd-arm64: 0.15.8 + esbuild-linux-32: 0.15.8 + esbuild-linux-64: 0.15.8 + esbuild-linux-arm: 0.15.8 + esbuild-linux-arm64: 0.15.8 + esbuild-linux-mips64le: 0.15.8 + esbuild-linux-ppc64le: 0.15.8 + esbuild-linux-riscv64: 0.15.8 + esbuild-linux-s390x: 0.15.8 + esbuild-netbsd-64: 0.15.8 + esbuild-openbsd-64: 0.15.8 + esbuild-sunos-64: 0.15.8 + esbuild-windows-32: 0.15.8 + esbuild-windows-64: 0.15.8 + esbuild-windows-arm64: 0.15.8 + dev: true + + /estree-walker/2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-core-module/2.10.0: + resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} + dependencies: + has: 1.0.3 + dev: true + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /magic-string/0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /postcss/8.4.16: + resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.10.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup/2.78.1: + resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /semver/7.3.7: + resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + /sourcemap-codec/1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + /typescript/4.8.3: + resolution: {integrity: sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /vite/3.1.3: + resolution: {integrity: sha512-/3XWiktaopByM5bd8dqvHxRt5EEgRikevnnrpND0gRfNkrMrPaGGexhtLCzv15RcCMtV2CLw+BPas8YFeSG0KA==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + less: '*' + sass: '*' + stylus: '*' + terser: ^5.4.0 + peerDependenciesMeta: + less: + optional: true + sass: + optional: true + stylus: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.15.8 + postcss: 8.4.16 + resolve: 1.22.1 + rollup: 2.78.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vue-tsc/0.40.13_typescript@4.8.3: + resolution: {integrity: sha512-xzuN3g5PnKfJcNrLv4+mAjteMd5wLm5fRhW0034OfNJZY4WhB07vhngea/XeGn7wNYt16r7syonzvW/54dcNiA==} + hasBin: true + peerDependencies: + typescript: '*' + dependencies: + '@volar/vue-language-core': 0.40.13 + '@volar/vue-typescript': 0.40.13 + typescript: 4.8.3 + dev: true + + /vue/3.2.39: + resolution: {integrity: sha512-tRkguhRTw9NmIPXhzk21YFBqXHT2t+6C6wPOgQ50fcFVWnPdetmRqbmySRHznrYjX2E47u0cGlKGcxKZJ38R/g==} + dependencies: + '@vue/compiler-dom': 3.2.39 + '@vue/compiler-sfc': 3.2.39 + '@vue/runtime-dom': 3.2.39 + '@vue/server-renderer': 3.2.39_vue@3.2.39 + '@vue/shared': 3.2.39 + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true diff --git a/src/CreateModal.vue b/src/CreateModal.vue new file mode 100644 index 0000000..dd46555 --- /dev/null +++ b/src/CreateModal.vue @@ -0,0 +1,21 @@ + + diff --git a/src/Modal.ts b/src/Modal.ts new file mode 100644 index 0000000..d8c7202 --- /dev/null +++ b/src/Modal.ts @@ -0,0 +1,50 @@ +import { + inject, + type Component, + type ComputedOptions, + type MethodOptions, + type Ref, +} from "vue"; + +export interface ModalState { + action: { + show: (modalId: string, args?: any) => void; + hide: (modalId: string) => void; + remove: (modalId: string) => void; + getModalId: (modal: any) => any; + register: (id: string, comp: any, args: any) => void; + }; + store: { + [id: string]: { + comp: Component; + args?: Record; + visible: boolean; + }; + }; + modalPromise: { + [id: string]: { + promise: Promise; + resolve: (args?: unknown) => void; + reject: (args?: unknown) => void; + }; + }; +} + +export type VueComponent = Component< + any, + any, + any, + ComputedOptions, + MethodOptions +>; + +export type ModalArgs = Record; + +export const ModalStateToken = Symbol("ModalStateToken"); + +export const ModalIdToken = Symbol("ModalIdToken"); + +export const modalContext = () => + inject>(ModalStateToken, {}); + +export const modalIdContext = () => inject(ModalIdToken, ""); diff --git a/src/ModalProvider.vue b/src/ModalProvider.vue new file mode 100644 index 0000000..e54c648 --- /dev/null +++ b/src/ModalProvider.vue @@ -0,0 +1,10 @@ + + diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6bf4393 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,10 @@ +import ModalProvider from "./ModalProvider.vue"; +import { useModal, useModalRef } from "./useModal"; + +const Modal = { + ModalProvider, + useModal, + useModalRef, +}; + +export default Modal; diff --git a/src/useModal.tsx b/src/useModal.tsx new file mode 100644 index 0000000..737bb8b --- /dev/null +++ b/src/useModal.tsx @@ -0,0 +1,140 @@ +import { + computed, + defineComponent, + provide, + reactive, + ref, + toRaw, + toRef, +} from "vue"; +import { + modalContext, + modalIdContext, + ModalStateToken, + type ModalState, + type VueComponent, + type ModalArgs, +} from "./Modal"; +import CreateModal from "./CreateModal.vue"; +const create = (modalId: string, Modal: any) => { + return defineComponent({ + render() { + return ( + + + + ); + }, + }); +}; + +export function useModalProvide() { + let uuid = 0; + const getUid = () => `__modal_${uuid++}`; + const symModalId = Symbol("ModalId"); + const MODAL_REGISTRY_DEFAULT: ModalState["store"] = {}; + const store = reactive(MODAL_REGISTRY_DEFAULT); + const modalPromise: ModalState["modalPromise"] = {}; + const action = { + show: (modalId: string, args?: ModalArgs) => { + if (args) { + store[modalId].args = args; + } + store[modalId].visible = true; + }, + hide: (modalId: string) => { + store[modalId].visible = false; + }, + remove: (modalId: string) => { + delete store[modalId]; + delete modalPromise[modalId]; + }, + getModalId: (modal: any) => { + if (!modal[symModalId]) { + modal[symModalId] = getUid(); + } + return modal[symModalId]; + }, + register: (id: string, comp: any, args: ModalArgs) => { + if (!store[id]) { + store[id] = { comp, visible: false }; + } else { + store[id].args = args; + } + }, + }; + + provide(ModalStateToken, { store, action, modalPromise }); + + const modalList = computed(() => { + const visibleModalIds = Object.keys(store).filter((id) => !!store[id]); + return visibleModalIds + .filter((id) => store[id]) + .map((id) => { + return { + id, + ...store[id], + comp: toRaw(store[id].comp), + }; + }); + }); + return { modalList }; +} + +export function useModal(modal: VueComponent, args?: ModalArgs) { + const { store, action, modalPromise } = modalContext(); + const modalId = action?.getModalId(modal); + + // first + const firstShow = ref(true); + + const modalInfo = store?.[modalId]; + + const show = (showArgs?: ModalArgs) => { + if (firstShow.value || !modalInfo) { + const newModal = create(modalId, modal); + action?.register(modalId, newModal, args); + firstShow.value = false; + } + if (!modalPromise![modalId]) { + let modalResolve!: (args?: unknown) => void; + let modalReject!: (args?: unknown) => void; + const promise = new Promise((resolve, reject) => { + modalResolve = resolve; + modalReject = reject; + }); + modalPromise![modalId] = { + promise, + reject: modalReject, + resolve: modalResolve, + }; + } + + action?.show(modalId, showArgs); + return modalPromise![modalId].promise; + }; + const hide = () => action?.hide(modalId); + + return { show, hide }; +} + +export function useModalRef() { + const { store, action, modalPromise } = modalContext(); + const modalId = modalIdContext(); + const modalInfo = store![modalId]; + + const show = (args?: unknown) => action?.show(modalId, args); + const hide = () => action?.hide(modalId); + const remove = () => action?.remove(modalId); + const resolve = (args?: unknown) => modalPromise![modalId].resolve(args); + const reject = (args?: unknown) => modalPromise![modalId].reject(args); + return { + show, + hide, + visible: toRef(modalInfo, "visible"), + args: toRef(modalInfo, "args"), + remove, + resolve, + reject, + }; +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..323c78a --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1,7 @@ +/// + +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/tsconfig-build.json b/tsconfig-build.json new file mode 100644 index 0000000..cd6ad18 --- /dev/null +++ b/tsconfig-build.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "emitDeclarationOnly": true, + "declaration": true, + "declarationDir": "dist/types" + }, + "include": ["./src"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..44e531f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true, + "outDir": "dist/esm", + "declaration": true + }, + "include": ["./src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..da1022c --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from "vite"; +import vue from "@vitejs/plugin-vue"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()], + build: { + target: "esnext", + lib: { + entry: "src/index.ts", + name: "vue-modal-provider", + formats: ["es", "cjs"], + fileName: (format) => `vue-modal-provider.${format}.js`, + }, + rollupOptions: { + // make sure to externalize deps that shouldn't be bundled + // into your library + external: ["vue"], + output: { + // Provide global variables to use in the UMD build + // for externalized deps + globals: { + vue: "Vue", + }, + }, + }, + }, +});