├── .browserslistrc ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── build └── rollup.config.js ├── dev ├── serve.ts └── serve.vue ├── package.json ├── screenshot.png ├── shims-vue.d.ts ├── src ├── components │ └── share-module.vue ├── entry.esm.ts ├── entry.ts ├── share-modal.vue └── utils │ ├── copyToClipboard.ts │ └── index.ts ├── tsconfig.json └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | current node 2 | last 2 versions and > 2% 3 | ie > 10 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2021 Yasin Silavi 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 14 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## vue-share-modal 3 | 4 | A pure, lightweight, and beautiful share modal for Vue 3 5 | ‌ 6 | 7 | ![screenshot](https://github.com/sttatusx/vue-share-modal/raw/master/screenshot.png) 8 | 9 | ‌ 10 | 11 | ## 🪁 Live version 12 | You can see the live version here: 13 | [https://freakingeek.github.io/vue-share-modal/](https://freakingeek.github.io/vue-share-modal/) 14 | 15 | ‌ 16 | 17 | ## 💾 Install 18 | 19 | ```shell 20 | $ yarn add vue-share-modal 21 | # npm install vue-share-modal 22 | ``` 23 | Or you can use any package manager you want 24 | 25 | ‌ 26 | 27 | ## 🚀 Usage 28 | 29 | You should import **share-modal** and **share-module** components from the vue-share-modal 30 | package and use them like this. 31 | ‌ 32 | 33 | ```vue 34 | 47 | 48 | 87 | ``` 88 | ‌ 89 | 90 | > NOTE: vue-share-modal does not contain any icons by default. So we use **@salmon-ui/icons** package for example here 91 | 92 | ‌ 93 | 94 | ## Options Or Props ( share-modal ) 95 | 96 | ```show``` prop is used for showing modal with animation 97 | ```@update:show``` event is used to update ```show``` value 98 | 99 | ```vue 100 | 104 | ``` 105 | 106 | ‌ 107 | 108 | ```link``` prop is used for showing link in the footer 109 | 110 | ```vue 111 | 114 | ``` 115 | 116 | ‌ 117 | 118 | ```mode``` prop is used for changing modal style ( ```normal``` / ```outline``` ) 119 | 120 | ```vue 121 | 124 | ``` 125 | 126 | ‌ 127 | 128 | ```direction``` prop is used for changing modal direction ( ```ltr``` / ```rtl``` ) 129 | 130 | ```vue 131 | 134 | ``` 135 | 136 | ‌ 137 | 138 | ```title``` prop is used for changing modal title 139 | 140 | ```vue 141 | 144 | ``` 145 | 146 | ‌ 147 | 148 | ```footerHint``` prop is used for changing the footer text 149 | 150 | ```vue 151 | 154 | ``` 155 | 156 | ‌ 157 | 158 | ```variables``` prop is used for changing the modal CSS variables ( like font-family and colors ) 159 | 160 | ```vue 161 | 172 | ``` 173 | 174 | ‌ 175 | 176 | 177 | ## Options Or Props ( share-module ) 178 | 179 | ```tag``` generated tag for share-module component ( default: ```span``` ) 180 | 181 | ```vue 182 | 185 | ``` 186 | 187 | ‌ 188 | 189 | ```name``` name of the module 190 | 191 | ```vue 192 | 196 | ``` 197 | 198 | ‌ 199 | 200 | 201 | ```iconClassName``` you can pass this prop to use font icons 202 | 203 | ```vue 204 | 209 | ``` 210 | 211 | ‌ 212 | 213 | ```mode``` you can pass this prop to overwrite share-modal ```mode``` prop 214 | 215 | ```vue 216 | 217 | 221 | 222 | ``` 223 | 224 | ‌ 225 | 226 | ## ✏ Todo 227 | 228 | - [ ] Support for different themes 229 | 230 | ‌ 231 | 232 | ## 📝 License 233 | 234 | This project is under [ISC](https://github.com/sttatusx/vue-share-modal/blob/master/LICENSE) license 235 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | const devPresets = ['@vue/babel-preset-app']; 2 | const buildPresets = [ 3 | [ 4 | '@babel/preset-env', 5 | // Config for @babel/preset-env 6 | { 7 | // Example: Always transpile optional chaining/nullish coalescing 8 | // include: [ 9 | // /(optional-chaining|nullish-coalescing)/ 10 | // ], 11 | }, 12 | ], 13 | '@babel/preset-typescript', 14 | ]; 15 | module.exports = { 16 | presets: (process.env.NODE_ENV === 'development' ? devPresets : buildPresets), 17 | }; 18 | -------------------------------------------------------------------------------- /build/rollup.config.js: -------------------------------------------------------------------------------- 1 | // rollup.config.js 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | import vue from 'rollup-plugin-vue'; 5 | import alias from '@rollup/plugin-alias'; 6 | import commonjs from '@rollup/plugin-commonjs'; 7 | import resolve from '@rollup/plugin-node-resolve'; 8 | import replace from '@rollup/plugin-replace'; 9 | import babel from '@rollup/plugin-babel'; 10 | import PostCSS from 'rollup-plugin-postcss'; 11 | import { terser } from 'rollup-plugin-terser'; 12 | import ttypescript from 'ttypescript'; 13 | import typescript from 'rollup-plugin-typescript2'; 14 | import minimist from 'minimist'; 15 | 16 | // Get browserslist config and remove ie from es build targets 17 | const esbrowserslist = fs.readFileSync('./.browserslistrc') 18 | .toString() 19 | .split('\n') 20 | .filter((entry) => entry && entry.substring(0, 2) !== 'ie'); 21 | 22 | // Extract babel preset-env config, to combine with esbrowserslist 23 | const babelPresetEnvConfig = require('../babel.config') 24 | .presets.filter((entry) => entry[0] === '@babel/preset-env')[0][1]; 25 | 26 | const argv = minimist(process.argv.slice(2)); 27 | 28 | const projectRoot = path.resolve(__dirname, '..'); 29 | 30 | const baseConfig = { 31 | input: 'src/entry.ts', 32 | plugins: { 33 | preVue: [ 34 | alias({ 35 | entries: [ 36 | { 37 | find: '@', 38 | replacement: `${path.resolve(projectRoot, 'src')}`, 39 | }, 40 | ], 41 | }), 42 | ], 43 | replace: { 44 | 'process.env.NODE_ENV': JSON.stringify('production'), 45 | }, 46 | vue: { 47 | }, 48 | postVue: [ 49 | resolve({ 50 | extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'], 51 | }), 52 | // Process only ` 107 | -------------------------------------------------------------------------------- /src/entry.esm.ts: -------------------------------------------------------------------------------- 1 | import { App, Plugin } from 'vue'; 2 | 3 | // Import vue component 4 | import component from '@/share-modal.vue'; 5 | 6 | // Define typescript interfaces for installable component 7 | type InstallableComponent = typeof component & { install: Exclude }; 8 | 9 | // Default export is installable instance of component. 10 | // IIFE injects install function into component, allowing component 11 | // to be registered via Vue.use() as well as Vue.component(), 12 | export default /*#__PURE__*/((): InstallableComponent => { 13 | // Assign InstallableComponent type 14 | const installable = component as unknown as InstallableComponent; 15 | 16 | // Attach install function executed by Vue.use() 17 | installable.install = (app: App) => { 18 | app.component('VueShareModal', installable); 19 | }; 20 | return installable; 21 | })(); 22 | 23 | // It's possible to expose named exports when writing components that can 24 | // also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo'; 25 | // export const RollupDemoDirective = directive; 26 | -------------------------------------------------------------------------------- /src/entry.ts: -------------------------------------------------------------------------------- 1 | // iife/cjs usage extends esm default export - so import it all 2 | import component, * as namedExports from '@/entry.esm'; 3 | 4 | // Attach named exports directly to component. IIFE/CJS will 5 | // only expose one global var, with named exports exposed as properties of 6 | // that global var (eg. plugin.namedExport) 7 | Object.entries(namedExports).forEach(([exportName, exported]) => { 8 | if (exportName !== 'default') component[exportName] = exported; 9 | }); 10 | 11 | export default component as typeof component & Exclude; 12 | -------------------------------------------------------------------------------- /src/share-modal.vue: -------------------------------------------------------------------------------- 1 | 60 | 61 | 178 | 179 | 353 | -------------------------------------------------------------------------------- /src/utils/copyToClipboard.ts: -------------------------------------------------------------------------------- 1 | function copyToClipboard(string?: string) { 2 | if (!string || typeof string !== 'string') return; 3 | 4 | if (!document?.body) return; 5 | 6 | if (!navigator?.clipboard) return; 7 | 8 | const input = document.createElement("input"); 9 | document.body.appendChild(input); 10 | input.value = string; 11 | 12 | input.select(); 13 | input.setSelectionRange(0, 99999); 14 | 15 | navigator.clipboard.writeText(input.value); 16 | 17 | document.body.removeChild(input); 18 | 19 | } 20 | 21 | export default copyToClipboard; 22 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import copyToClipboard from "./copyToClipboard"; 2 | 3 | export { copyToClipboard }; 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "declaration": true, 7 | "declarationDir": "dist/types", 8 | "noUnusedLocals": true, 9 | "noUnusedParameters": true, 10 | "importHelpers": true, 11 | "moduleResolution": "node", 12 | "experimentalDecorators": true, 13 | "esModuleInterop": true, 14 | "allowSyntheticDefaultImports": true, 15 | "sourceMap": true, 16 | "baseUrl": ".", 17 | "newLine": "lf", 18 | "types": [ 19 | "node", 20 | "vue" 21 | ], 22 | "paths": { 23 | "@/*": [ 24 | "src/*" 25 | ] 26 | }, 27 | "plugins": [ 28 | { 29 | "transform":"@zerollup/ts-transform-paths", 30 | "exclude": ["*"] 31 | } 32 | ], 33 | "lib": [ 34 | "esnext", 35 | "dom", 36 | "dom.iterable", 37 | "scripthost" 38 | ] 39 | }, 40 | "exclude": [ 41 | "node_modules", 42 | "dist" 43 | ] 44 | } 45 | --------------------------------------------------------------------------------