├── .eslintrc.cjs ├── .gitignore ├── LICENSE ├── README.md ├── env.d.ts ├── index.html ├── package.json ├── public └── .gitkeep ├── src ├── App.vue ├── components │ └── otp-widget.vue ├── index.ts └── main.ts ├── tsconfig.config.json ├── tsconfig.json └── vite.config.ts /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require("@rushstack/eslint-patch/modern-module-resolution"); 3 | 4 | module.exports = { 5 | root: true, 6 | extends: [ 7 | "plugin:vue/vue3-essential", 8 | "eslint:recommended", 9 | "@vue/eslint-config-typescript/recommended", 10 | "@vue/eslint-config-prettier", 11 | "@typescript-eslint/no-unused-vars" 12 | ], 13 | rules: { 14 | "@typescript-eslint/no-explicit-any": "off", 15 | }, 16 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | package-*.json 18 | 19 | /cypress/videos/ 20 | /cypress/screenshots/ 21 | 22 | # Editor directories and files 23 | .vscode/* 24 | !.vscode/extensions.json 25 | .idea 26 | *.suo 27 | *.ntvs* 28 | *.njsproj 29 | *.sln 30 | *.sw? -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Balthazar DOSSOU 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # otp-widget-vue 2 | OTP code input widget for Vue 3 3 | 4 | ![image](https://user-images.githubusercontent.com/92580505/212340376-892b9ee4-1cd3-4e38-bd2b-eed867c50221.png) 5 | 6 | ## install 7 | ```sh 8 | npm i @lbgm/otp-widget-vue 9 | ``` 10 | 11 | ## Props 12 | Interface: 13 | ```ts 14 | interface Props { 15 | childs?: number; 16 | type?: "number" | "text"; 17 | placeholder?: string; 18 | gap?: "otp-gap-1" | "otp-gap-2" | "otp-gap-3" | "otp-gap-4" | "otp-gap-5" | "otp-gap-6" | "otp-gap-7" | "otp-gap-8" | "otp-gap-9" | "otp-gap-10" | "otp-gap-11" | "otp-gap-12" | "otp-gap-13" | "otp-gap-14" | "otp-gap-15" | "otp-gap-16" | "otp-gap-17" | "otp-gap-18" | "otp-gap-19" | "otp-gap-20" | "otp-gap-21" | "otp-gap-22" | "otp-gap-23" | "otp-gap-24" | "otp-gap-25" | "otp-gap-26" | "otp-gap-27" | "otp-gap-28" | "otp-gap-29" | "otp-gap-30" | "otp-gap-31" | "otp-gap-32" | "otp-gap-33" | "otp-gap-34" | "otp-gap-35" | "otp-gap-36" | "otp-gap-37" | "otp-gap-38" | "otp-gap-39" | "otp-gap-40" | "otp-gap-41" | "otp-gap-42" | "otp-gap-43" | "otp-gap-44" | "otp-gap-45" | "otp-gap-46" | "otp-gap-47" | "otp-gap-48"; 19 | } 20 | ``` 21 | 22 | Default values: 23 | ```js 24 | { 25 | childs: 4, 26 | type: "number", 27 | placeholder: "", 28 | gap: "otp-gap-16" 29 | } 30 | ``` 31 | 32 | ## Events 33 | `code`: sends value filled as `string`; 34 | 35 | `filled`: when all inputs are filled; 36 | 37 | ## Use 38 | main.ts : 39 | ```js 40 | import { OtpWidget } from '@lbgm/otp-widget-vue'; 41 | 42 | // register as global component 43 | app.component('OtpWidget', OtpWidget); 44 | ``` 45 | App.vue : 46 | ```js 47 | // import component style 48 | import '@lbgm/otp-widget-vue/style'; 49 | 50 | import { ref } from "vue"; 51 | import type { Ref } from "vue"; 52 | 53 | const otp: Ref = ref(""); 54 | ``` 55 | 56 | use component: 57 | ```html 58 | 59 | ``` 60 | 61 | ![image](https://user-images.githubusercontent.com/92580505/212340494-fa18c90b-cb68-4813-817d-e188343719e4.png) 62 | 63 | 64 | ```js 65 | console.log(otp) : 8842 66 | ``` 67 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@lbgm/otp-widget-vue", 3 | "version": "1.0.0-b", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "run-p type-check build-only", 7 | "preview": "vite preview", 8 | "build-only": "vite build", 9 | "type-check": "vue-tsc --noEmit", 10 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", 11 | "build-lib": "vite build && vue-tsc --emitDeclarationOnly --allowJs && mv dist/src dist/types" 12 | }, 13 | "engines": { 14 | "node": ">=14.18.3", 15 | "npm": ">=6.14.15" 16 | }, 17 | "types": "./dist/types/index.d.ts", 18 | "files": [ 19 | "dist" 20 | ], 21 | "main": "./dist/otp-widget-vue.umd.js", 22 | "module": "./dist/otp-widget-vue.es.js", 23 | "exports": { 24 | ".": { 25 | "import": "./dist/otp-widget-vue.es.js", 26 | "require": "./dist/otp-widget-vue.umd.js" 27 | }, 28 | "./style": { 29 | "import": "./dist/style.css", 30 | "require": "./dist/style.css" 31 | } 32 | }, 33 | "dependencies": { 34 | "sass": "^1.57.1", 35 | "vue": "^3.2.45" 36 | }, 37 | "devDependencies": { 38 | "@rushstack/eslint-patch": "^1.1.4", 39 | "@types/node": "^18.11.18", 40 | "@vitejs/plugin-vue": "^4.0.0", 41 | "@vue/eslint-config-prettier": "^7.0.0", 42 | "@vue/eslint-config-typescript": "^11.0.0", 43 | "@vue/tsconfig": "^0.1.3", 44 | "eslint": "^8.22.0", 45 | "eslint-plugin-vue": "^9.3.0", 46 | "npm-run-all": "^4.1.5", 47 | "prettier": "^2.7.1", 48 | "typescript": "~4.7.4", 49 | "vite": "^4.0.0", 50 | "vue-tsc": "^1.0.12" 51 | }, 52 | "description": "OTP code input widget for Vue", 53 | "repository": { 54 | "type": "git", 55 | "url": "git+https://github.com/lbgm/otp-widget-vue.git" 56 | }, 57 | "keywords": [ 58 | "vue", 59 | "otp", 60 | "typescript", 61 | "vite", 62 | "vue component", 63 | "lbgm", 64 | "code", 65 | "auth", 66 | "widget" 67 | ], 68 | "author": "@lbgm", 69 | "license": "MIT", 70 | "bugs": { 71 | "url": "https://github.com/lbgm/otp-widget-vue/issues" 72 | }, 73 | "homepage": "https://github.com/lbgm/otp-widget-vue#readme" 74 | } 75 | -------------------------------------------------------------------------------- /public/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbgm/otp-widget-vue/599d8b614c3997b417c5bec0a3c1f41c45932d40/public/.gitkeep -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | 43 | -------------------------------------------------------------------------------- /src/components/otp-widget.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 138 | 139 | 140 | 212 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as OtpWidget } from "@/components/otp-widget.vue"; -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app') 5 | -------------------------------------------------------------------------------- /tsconfig.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.node.json", 3 | "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "types": ["node"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.web.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "paths": { 7 | "@/*": ["./src/*"] 8 | }, 9 | "outDir": "dist", 10 | "declaration": true, 11 | "composite": true, 12 | "lib": ["es2017", "dom"] 13 | }, 14 | 15 | "references": [ 16 | { 17 | "path": "./tsconfig.config.json" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url'; 2 | import path from "path"; 3 | 4 | import { defineConfig } from 'vite'; 5 | import vue from '@vitejs/plugin-vue'; 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | build: { 10 | lib: { 11 | entry: path.resolve(__dirname, "src/index.ts"), 12 | name: "OtpWidgetVue", 13 | fileName: (format: string) => `otp-widget-vue.${format}.js`, 14 | }, 15 | rollupOptions: { 16 | // make sure to externalize deps that shouldn't be bundled 17 | // into your library 18 | external: ["vue"], 19 | output: { 20 | // Provide global variables to use in the UMD build 21 | // for externalized deps 22 | globals: { 23 | vue: "Vue", 24 | }, 25 | }, 26 | }, 27 | }, 28 | plugins: [vue()], 29 | resolve: { 30 | alias: { 31 | '@': fileURLToPath(new URL('./src', import.meta.url)) 32 | } 33 | } 34 | }) 35 | --------------------------------------------------------------------------------