├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── featurerequest.md │ └── bugreport.md ├── .stylelintrc.json ├── docs ├── favicon.png ├── github-cover.png ├── kioskboard-keys-turkish.json ├── images │ ├── Keyboard-Types-Icons-Numpad.svg │ ├── Keyboard-Types-Icons-Keyboard.svg │ └── Keyboard-Types-Icons-All.svg ├── index.js ├── index-tooltip.js ├── index.css └── index.html ├── src ├── kioskboard.d.ts └── kioskboard.css ├── .gitignore ├── CONTRIBUTING.md ├── SECURITY.md ├── dist ├── kioskboard-keys-english.json ├── kioskboard-keys-spanish.json ├── kioskboard-keys-german.json ├── kioskboard-keys-french.json ├── kioskboard-keys-persian.json ├── kioskboard-keys-arabic.json ├── kioskboard-keys-russian.json ├── kioskboard-keys-turkish.json ├── kioskboard-keys-hungarian.json ├── kioskboard-2.3.0.min.css └── kioskboard-2.3.0.min.js ├── tsconfig.json ├── .eslintrc.json ├── .dev ├── .eslintrc.json ├── dev-constants.js ├── dev-allinone.js └── dev-minifier.js ├── LICENSE ├── package.json ├── index.d.test.ts ├── CODE_OF_CONDUCT.md ├── CHANGELOG.md ├── index.d.ts └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [furcan] 2 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard" 3 | } 4 | -------------------------------------------------------------------------------- /docs/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furcan/KioskBoard/HEAD/docs/favicon.png -------------------------------------------------------------------------------- /docs/github-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furcan/KioskBoard/HEAD/docs/github-cover.png -------------------------------------------------------------------------------- /src/kioskboard.d.ts: -------------------------------------------------------------------------------- 1 | import KioskBoard from '../index.d'; 2 | export = KioskBoard; 3 | export as namespace KioskBoard; 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Node Modules 3 | node_modules/ 4 | /npm-debug.log 5 | 6 | # Misc 7 | .DS_Store 8 | *.DS_Store 9 | .code-workspace 10 | *.code-workspace 11 | 12 | # IDE/Editor 13 | .vscode/ 14 | .vs/ 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ```js 2 | // TODO: 3 | ``` 4 | Hello, 5 | Thank you for your contribution in advance. 6 | 7 | You can please propose your changes only with: 8 | `https://github.com/furcan/KioskBoard/blob/main/src/kioskboard.js` 9 | 10 | _All the other files will be generated by the build scripts and do not require any actions on your end._ 11 | 12 | Thanks, 13 | Furkan 14 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | KioskBoard is a dependency-free JavaScript library that has no vulnerabilities. Supported versions can be found in the table below. 6 | 7 | | Version | Supported | 8 | | ------- | ------------------ | 9 | | 2.x.x | :white_check_mark: | 10 | | < 2.0.0 | :x: | 11 | 12 | ## Reporting a Vulnerability 13 | 14 | [Report](https://github.com/furcan/KioskBoard/issues) 15 | -------------------------------------------------------------------------------- /dist/kioskboard-keys-english.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "Q", 4 | "1": "W", 5 | "2": "E", 6 | "3": "R", 7 | "4": "T", 8 | "5": "Y", 9 | "6": "U", 10 | "7": "I", 11 | "8": "O", 12 | "9": "P" 13 | }, 14 | { 15 | "0": "A", 16 | "1": "S", 17 | "2": "D", 18 | "3": "F", 19 | "4": "G", 20 | "5": "H", 21 | "6": "J", 22 | "7": "K", 23 | "8": "L" 24 | }, 25 | { 26 | "0": "Z", 27 | "1": "X", 28 | "2": "C", 29 | "3": "V", 30 | "4": "B", 31 | "5": "N", 32 | "6": "M" 33 | } 34 | ] -------------------------------------------------------------------------------- /dist/kioskboard-keys-spanish.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "Q", 4 | "1": "W", 5 | "2": "E", 6 | "3": "R", 7 | "4": "T", 8 | "5": "Y", 9 | "6": "U", 10 | "7": "I", 11 | "8": "O", 12 | "9": "P" 13 | }, 14 | { 15 | "0": "A", 16 | "1": "S", 17 | "2": "D", 18 | "3": "F", 19 | "4": "G", 20 | "5": "H", 21 | "6": "J", 22 | "7": "K", 23 | "8": "L", 24 | "9": "Ñ" 25 | }, 26 | { 27 | "0": "Z", 28 | "1": "X", 29 | "2": "C", 30 | "3": "V", 31 | "4": "B", 32 | "5": "N", 33 | "6": "M" 34 | } 35 | ] -------------------------------------------------------------------------------- /dist/kioskboard-keys-german.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "Q", 4 | "1": "W", 5 | "2": "E", 6 | "3": "R", 7 | "4": "T", 8 | "5": "Z", 9 | "6": "U", 10 | "7": "I", 11 | "8": "O", 12 | "9": "P", 13 | "10": "Ü" 14 | }, 15 | { 16 | "0": "A", 17 | "1": "S", 18 | "2": "D", 19 | "3": "F", 20 | "4": "G", 21 | "5": "H", 22 | "6": "J", 23 | "7": "K", 24 | "8": "L", 25 | "9": "Ö", 26 | "10": "Ä" 27 | }, 28 | { 29 | "0": "Y", 30 | "1": "X", 31 | "2": "C", 32 | "3": "V", 33 | "4": "B", 34 | "5": "N", 35 | "6": "M" 36 | } 37 | ] -------------------------------------------------------------------------------- /dist/kioskboard-keys-french.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "A", 4 | "1": "Z", 5 | "2": "E", 6 | "3": "R", 7 | "4": "T", 8 | "5": "Y", 9 | "6": "U", 10 | "7": "I", 11 | "8": "O", 12 | "9": "P" 13 | }, 14 | { 15 | "0": "Q", 16 | "1": "S", 17 | "2": "D", 18 | "3": "F", 19 | "4": "G", 20 | "5": "H", 21 | "6": "J", 22 | "7": "K", 23 | "8": "L", 24 | "9": "M" 25 | }, 26 | { 27 | "0": "W", 28 | "1": "X", 29 | "2": "C", 30 | "3": "V", 31 | "4": "B", 32 | "5": "N", 33 | "6": "É", 34 | "7": "È", 35 | "8": "Ç", 36 | "9": "À" 37 | } 38 | ] -------------------------------------------------------------------------------- /dist/kioskboard-keys-persian.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "چ", 4 | "1": "ج", 5 | "2": "ح", 6 | "3": "خ", 7 | "4": "ه", 8 | "5": "ع", 9 | "6": "غ", 10 | "7": "ف", 11 | "8": "ق", 12 | "9": "ث", 13 | "10": "ص", 14 | "11": "ض" 15 | }, 16 | { 17 | "0": "گ", 18 | "1": "ک", 19 | "2": "م", 20 | "3": "ن", 21 | "4": "ت", 22 | "5": "ا", 23 | "6": "ل", 24 | "7": "ب", 25 | "8": "ی", 26 | "9": "س", 27 | "10": "ش" 28 | }, 29 | { 30 | "0": "و", 31 | "1": "پ", 32 | "2": "د", 33 | "3": "ذ", 34 | "4": "ر", 35 | "5": "ز", 36 | "6": "ژ", 37 | "7": "ط", 38 | "8": "ظ" 39 | } 40 | ] -------------------------------------------------------------------------------- /dist/kioskboard-keys-arabic.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "د", 4 | "1": "ج", 5 | "2": "ح", 6 | "3": "خ", 7 | "4": "ه", 8 | "5": "ع", 9 | "6": "غ", 10 | "7": "ف", 11 | "8": "ق", 12 | "9": "ث", 13 | "10": "ص", 14 | "11": "ض" 15 | }, 16 | { 17 | "0": "ط", 18 | "1": "ك", 19 | "2": "م", 20 | "3": "ن", 21 | "4": "ت", 22 | "5": "ا", 23 | "6": "ل", 24 | "7": "ب", 25 | "8": "ي", 26 | "9": "س", 27 | "10": "ش" 28 | }, 29 | { 30 | "0": "ظ", 31 | "1": "ز", 32 | "2": "و", 33 | "3": "ة", 34 | "4": "ى", 35 | "5": "لا", 36 | "6": "ر", 37 | "7": "ؤ", 38 | "8": "ء", 39 | "9": "ئ" 40 | } 41 | ] -------------------------------------------------------------------------------- /dist/kioskboard-keys-russian.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "Й", 4 | "1": "Ц", 5 | "2": "У", 6 | "3": "К", 7 | "4": "Е", 8 | "5": "Н", 9 | "6": "Г", 10 | "7": "Ш", 11 | "8": "Щ", 12 | "9": "З", 13 | "10": "Х", 14 | "11": "Ъ" 15 | }, 16 | { 17 | "0": "Ф", 18 | "1": "Ы", 19 | "2": "В", 20 | "3": "А", 21 | "4": "П", 22 | "5": "Р", 23 | "6": "О", 24 | "7": "Л", 25 | "8": "Д", 26 | "9": "Ж", 27 | "10": "Э" 28 | }, 29 | { 30 | "0": "Я", 31 | "1": "Ч", 32 | "2": "С", 33 | "3": "М", 34 | "4": "И", 35 | "5": "Т", 36 | "6": "Ь", 37 | "7": "Б", 38 | "8": "Ю", 39 | "9": "Ё" 40 | } 41 | ] -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/featurerequest.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: FeatureRequest 3 | about: Suggest an idea to help us improve. 4 | title: "[FEAT] - " 5 | labels: enhancement 6 | assignees: furcan 7 | 8 | --- 9 | ### Is your feature request related to a problem? Please describe. 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | ### Describe the solution you'd like 13 | A clear and concise description of what you want to happen. 14 | 15 | ### Describe alternatives you've considered 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | ### Additional context 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /dist/kioskboard-keys-turkish.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "Q", 4 | "1": "W", 5 | "2": "E", 6 | "3": "R", 7 | "4": "T", 8 | "5": "Y", 9 | "6": "U", 10 | "7": "I", 11 | "8": "O", 12 | "9": "P", 13 | "10": "Ğ", 14 | "11": "Ü" 15 | }, 16 | { 17 | "0": "A", 18 | "1": "S", 19 | "2": "D", 20 | "3": "F", 21 | "4": "G", 22 | "5": "H", 23 | "6": "J", 24 | "7": "K", 25 | "8": "L", 26 | "9": "Ş", 27 | "10": "İ" 28 | }, 29 | { 30 | "0": "Z", 31 | "1": "X", 32 | "2": "C", 33 | "3": "V", 34 | "4": "B", 35 | "5": "N", 36 | "6": "M", 37 | "7": "Ö", 38 | "8": "Ç" 39 | } 40 | ] -------------------------------------------------------------------------------- /docs/kioskboard-keys-turkish.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "Q", 4 | "1": "W", 5 | "2": "E", 6 | "3": "R", 7 | "4": "T", 8 | "5": "Y", 9 | "6": "U", 10 | "7": "I", 11 | "8": "O", 12 | "9": "P", 13 | "10": "Ğ", 14 | "11": "Ü" 15 | }, 16 | { 17 | "0": "A", 18 | "1": "S", 19 | "2": "D", 20 | "3": "F", 21 | "4": "G", 22 | "5": "H", 23 | "6": "J", 24 | "7": "K", 25 | "8": "L", 26 | "9": "Ş", 27 | "10": "İ" 28 | }, 29 | { 30 | "0": "Z", 31 | "1": "X", 32 | "2": "C", 33 | "3": "V", 34 | "4": "B", 35 | "5": "N", 36 | "6": "M", 37 | "7": "Ö", 38 | "8": "Ç" 39 | } 40 | ] -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": false, 19 | "jsx": "preserve", 20 | "incremental": false 21 | }, 22 | "include": [ 23 | "index.d.ts", 24 | "index.d.test.ts", 25 | "build/**/*.ts" 26 | ], 27 | "exclude": [ 28 | ".dev", 29 | ".github", 30 | "build/**/*.js", 31 | "dist", 32 | "docs", 33 | "node_modules", 34 | "src" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": false, 6 | "node": false 7 | }, 8 | "extends": "eslint:recommended", 9 | "globals": { 10 | "Atomics": "readonly", 11 | "SharedArrayBuffer": "readonly" 12 | }, 13 | "parserOptions": { 14 | "ecmaVersion": 5 15 | }, 16 | "rules": { 17 | "comma-dangle": [ 18 | "error", 19 | "always-multiline" 20 | ], 21 | "semi": [ 22 | "error", 23 | "always" 24 | ], 25 | "indent": [ 26 | "error", 27 | 2, 28 | { 29 | "ignoredNodes": [ 30 | "TemplateLiteral" 31 | ] 32 | } 33 | ], 34 | "quotes": [ 35 | 2, 36 | "single", 37 | { 38 | "avoidEscape": true, 39 | "allowTemplateLiterals": false 40 | } 41 | ] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /.dev/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | "extends": "eslint:recommended", 9 | "globals": { 10 | "Atomics": "readonly", 11 | "SharedArrayBuffer": "readonly" 12 | }, 13 | "parserOptions": { 14 | "ecmaVersion": 2021 15 | }, 16 | "rules": { 17 | "comma-dangle": [ 18 | "error", 19 | "always-multiline" 20 | ], 21 | "semi": [ 22 | "error", 23 | "always" 24 | ], 25 | "indent": [ 26 | "error", 27 | 2, 28 | { 29 | "ignoredNodes": [ 30 | "TemplateLiteral" 31 | ] 32 | } 33 | ], 34 | "quotes": [ 35 | 2, 36 | "single", 37 | { 38 | "avoidEscape": true, 39 | "allowTemplateLiterals": true 40 | } 41 | ] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dist/kioskboard-keys-hungarian.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "0": "0", 4 | "1": "1", 5 | "2": "2", 6 | "3": "3", 7 | "4": "4", 8 | "5": "5", 9 | "6": "6", 10 | "7": "7", 11 | "8": "8", 12 | "9": "9", 13 | "10": "Ö", 14 | "11": "Ü", 15 | "12": "Ó" 16 | }, 17 | { 18 | "0": "Q", 19 | "1": "W", 20 | "2": "E", 21 | "3": "R", 22 | "4": "T", 23 | "5": "Z", 24 | "6": "U", 25 | "7": "I", 26 | "8": "O", 27 | "9": "P", 28 | "10": "Ő", 29 | "11": "Ú" 30 | }, 31 | { 32 | "0": "A", 33 | "1": "S", 34 | "2": "D", 35 | "3": "F", 36 | "4": "G", 37 | "5": "H", 38 | "6": "J", 39 | "7": "K", 40 | "8": "L", 41 | "9": "É", 42 | "10": "Á", 43 | "11": "Ű" 44 | }, 45 | { 46 | "0": "Í", 47 | "1": "Y", 48 | "2": "X", 49 | "3": "C", 50 | "4": "V", 51 | "5": "B", 52 | "6": "N", 53 | "7": "M" 54 | } 55 | ] 56 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bugreport.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: BugReport 3 | about: Create a report to help us improve. 4 | title: "[BUG] - " 5 | labels: bug 6 | assignees: furcan 7 | 8 | --- 9 | ### Describe the bug 10 | A clear and concise description of what the bug is. 11 | 12 | ### To Reproduce 13 | Steps to reproduce the behavior: 14 | 1. Go to '...' 15 | 2. Click on '....' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | ### Expected behavior 20 | A clear and concise description of what you expected to happen. 21 | 22 | ### Screenshots 23 | If applicable, add screenshots to help explain your problem. 24 | 25 | ### Desktop (please complete the following information): 26 | - OS: [e.g. Windows, macOS...] 27 | - Browser [e.g. Chrome, Edge, Firefox, Safari...] 28 | - Version [e.g. v3.0.0] 29 | 30 | ### Smartphone (please complete the following information): 31 | - Device: [e.g. iPhone6] 32 | - OS: [e.g. iOS8.1] 33 | - Browser [e.g. stock browser, safari] 34 | - Version [e.g. v3.0.0] 35 | 36 | ### Additional context 37 | Add any other context about the problem here. 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 - 2022 KioskBoard: Virtual Keyboard 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. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kioskboard", 3 | "main": "dist/kioskboard-aio-2.3.0.min.js", 4 | "types": "index.d.ts", 5 | "version": "2.3.0", 6 | "description": "A pure JavaScript library for using virtual keyboards.", 7 | "homepage": "https://github.com/furcan/KioskBoard", 8 | "files": [ 9 | "index.d.ts", 10 | "build", 11 | "dist", 12 | "src" 13 | ], 14 | "keywords": [ 15 | "keyboard", 16 | "virtual keyboard", 17 | "kiosk", 18 | "kiosk keyboard", 19 | "numpad", 20 | "virtual numpad" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/furcan/KioskBoard.git" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/furcan/KioskBoard/issues" 28 | }, 29 | "author": "Furkan (https://github.com/furcan)", 30 | "contributors": [ 31 | "Furkan (https://github.com/furcan)" 32 | ], 33 | "license": "MIT", 34 | "devDependencies": { 35 | "babel-minify": "^0.5.1", 36 | "clean-css": "^5.1.5", 37 | "eslint": "^7.32.0", 38 | "stylelint": "^13.13.1", 39 | "stylelint-config-standard": "^22.0.0" 40 | }, 41 | "scripts": { 42 | "src:stylelint": "stylelint src/kioskboard.css", 43 | "src:eslint": "eslint src/kioskboard.js", 44 | "src:lint": "yarn src:stylelint && yarn src:eslint", 45 | "dev:eslint": "eslint -c .dev/.eslintrc.json .dev", 46 | "dev:lint": "yarn dev:eslint", 47 | "dev:allinone": "yarn dev:lint && yarn src:lint && node .dev/dev-allinone.js", 48 | "dev:minifier": "yarn dev:allinone && node .dev/dev-minifier.js", 49 | "build": "yarn dev:minifier" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /index.d.test.ts: -------------------------------------------------------------------------------- 1 | import KioskBoard from 'index.d'; 2 | 3 | KioskBoard.init({ 4 | keysArrayOfObjects: [ 5 | { 6 | "0": "S", 7 | "1": "O", 8 | "2": "L", 9 | }, 10 | { 11 | "0": "L", 12 | "1": "U", 13 | "2": "C", 14 | "3": "E", 15 | "4": "T", 16 | }, 17 | { 18 | "0": "O", 19 | "1": "M", 20 | "2": "N", 21 | "3": "I", 22 | "4": "B", 23 | "5": "U", 24 | "6": "S", 25 | }, 26 | ], 27 | keysJsonUrl: '/Content/Plugins/KioskBoard/dist/kioskboard-keys-english.json', 28 | keysSpecialCharsArrayOfStrings: ["#", "€", "%", "+", "-", "*"], 29 | keysNumpadArrayOfNumbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], 30 | language: 'en', 31 | theme: 'light', 32 | autoScroll: true, 33 | capsLockActive: true, 34 | allowRealKeyboard: false, 35 | allowMobileKeyboard: false, 36 | cssAnimations: true, 37 | cssAnimationsDuration: 360, 38 | cssAnimationsStyle: 'slide', 39 | keysAllowSpacebar: true, 40 | keysSpacebarText: 'Space', 41 | keysFontFamily: 'sans-serif', 42 | keysFontSize: '22px', 43 | keysFontWeight: 'normal', 44 | keysIconSize: '25px', 45 | keysEnterText: 'Enter', 46 | keysEnterCanClose: false, 47 | keysEnterCallback: () => undefined, 48 | }); 49 | 50 | KioskBoard.run('.js-kioskboard', { 51 | keysArrayOfObjects: [ 52 | { 53 | "0": "S", 54 | "1": "O", 55 | "2": "L", 56 | }, 57 | { 58 | "0": "L", 59 | "1": "U", 60 | "2": "C", 61 | "3": "E", 62 | "4": "T", 63 | }, 64 | { 65 | "0": "O", 66 | "1": "M", 67 | "2": "N", 68 | "3": "I", 69 | "4": "B", 70 | "5": "U", 71 | "6": "S", 72 | }, 73 | ], 74 | allowRealKeyboard: false, 75 | allowMobileKeyboard: false, 76 | language: 'en', 77 | theme: 'dark', 78 | }); 79 | 80 | const input = window.document.querySelector('.js-kioskboard') as HTMLInputElement; 81 | KioskBoard.run(input, { 82 | keysArrayOfObjects: [ 83 | { 84 | "0": "F", 85 | "1": "U", 86 | "2": "R", 87 | "3": "C", 88 | "4": "A", 89 | "5": "N", 90 | }, 91 | ], 92 | allowRealKeyboard: false, 93 | allowMobileKeyboard: true, 94 | language: 'en', 95 | theme: 'dark', 96 | }); 97 | -------------------------------------------------------------------------------- /docs/images/Keyboard-Types-Icons-Numpad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.dev/dev-constants.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Constants 3 | * Description: Constants for the development. 4 | * Version: 2.3.0 5 | * Author: Furkan ('https://github.com/furcan') 6 | * Copyright 2022 Constants, MIT Licence ('https://opensource.org/licenses/MIT') 7 | */ 8 | 9 | // Dev Dependencies 10 | const chalk = require('chalk'); 11 | const package = require('../package.json'); 12 | 13 | // Constants: begin 14 | // - CleanCSS Options: begin 15 | const cleanCSSOptions = { 16 | level: { 17 | 1: { 18 | optimizeBackground: false, // controls `background` property optimizations; defaults to `true` 19 | optimizeBorderRadius: false, // controls `border-radius` property optimizations; defaults to `true` 20 | optimizeFilter: false, // controls `filter` property optimizations; defaults to `true` 21 | optimizeFont: false, // controls `font` property optimizations; defaults to `true` 22 | optimizeFontWeight: false, // controls `font-weight` property optimizations; defaults to `true` 23 | optimizeOutline: false, // controls `outline` property optimizations; defaults to `true` 24 | specialComments: false, // remove all comments 25 | removeQuotes: false, // controls removing quotes when unnecessary; defaults to `true` 26 | semicolonAfterLastProperty: true, // controls removing trailing semicolons in rule; defaults to `false` - means remove 27 | }, 28 | }, 29 | }; 30 | // - CleanCSS Options: end 31 | 32 | // - Babel Minify Options: begin 33 | const minifyOptions = { 34 | builtIns: false, // transform-minify-booleans 35 | }; 36 | 37 | const minifyOverrides = { 38 | comments: false, // remove all comments 39 | }; 40 | // - Babel Minify Options: end 41 | 42 | // - Terminal Error Message: begin 43 | const terminalError = (message, fileOrPath) => { 44 | const colorRed = '#ff5549'; 45 | const colorBlue = '#26c0d3'; 46 | if (typeof fileOrPath !== 'string') { fileOrPath = '???'; } 47 | let info = chalk.hex(colorBlue)('\nPlease look at the "' + fileOrPath + '" for more information.\n\n'); 48 | if (typeof message !== 'string') { 49 | message = 'An error has occurred on: "' + chalk.hex(colorBlue)(fileOrPath) + '"'; 50 | info = ''; 51 | } 52 | return console.error(chalk.hex(colorRed).bold('Development Error: ') + chalk.hex(colorRed)(message) + info); 53 | }; 54 | // - Terminal Error Message: end 55 | 56 | // - Exports: begin 57 | module.exports = { 58 | prefix: 'kioskboard', 59 | dirInputDev: 'src', 60 | dirOutputDev: 'build', 61 | dirOutputDist: 'dist', 62 | fileScript: 'kioskboard.js', 63 | fileStyle: 'kioskboard.css', 64 | fileScriptAIO: 'kioskboard-aio.js', 65 | version: (JSON.stringify((package || {}).version) || '').replace(/"/gm, ''), 66 | author: (JSON.stringify((package || {}).author) || '').replace(/"/gm, ''), 67 | title: 'KioskBoard - Virtual Keyboard', 68 | url: '(https://github.com/furcan/KioskBoard)', 69 | license: 'MIT Licence (https://opensource.org/licenses/MIT)', 70 | year: new Date().getFullYear() || '2022', 71 | cleanCSSOptions, 72 | minifyOptions, 73 | minifyOverrides, 74 | terminalError, 75 | }; 76 | // - Exports: end 77 | // Constants: end 78 | -------------------------------------------------------------------------------- /docs/images/Keyboard-Types-Icons-Keyboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at "furcan[at]notiflix.com". All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /docs/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * KioskBoard - Virtual Keyboard ('https://github.com/furcan/KioskBoard') 3 | * Version: 2.3.0 4 | * Author: Furkan ('https://github.com/furcan') 5 | * Copyright 2022 KioskBoard - Virtual Keyboard, MIT Licence ('https://opensource.org/licenses/MIT')* 6 | */ 7 | 8 | // DEMO: Tooltip: begin 9 | function furcanTooltip(tooltip) { 10 | $('body > .tooltip').remove(); 11 | $(tooltip).tooltip({ 12 | trigger: 'hover', 13 | container: 'body', 14 | }); 15 | }; 16 | furcanTooltip('[data-toggle="tooltip"]'); 17 | 18 | $(document).on('click', function () { 19 | if ($('body > .tooltip').length > 0) { 20 | $('body > .tooltip').remove(); 21 | } 22 | }); 23 | // DEMO: Tooltip: end 24 | 25 | // DEMO: Turkish Keys: begin 26 | var turkishKeyboard = [ 27 | { 28 | "0": "Q", 29 | "1": "W", 30 | "2": "E", 31 | "3": "R", 32 | "4": "T", 33 | "5": "Y", 34 | "6": "U", 35 | "7": "I", 36 | "8": "O", 37 | "9": "P", 38 | "10": "Ğ", 39 | "11": "Ü" 40 | }, 41 | { 42 | "0": "A", 43 | "1": "S", 44 | "2": "D", 45 | "3": "F", 46 | "4": "G", 47 | "5": "H", 48 | "6": "J", 49 | "7": "K", 50 | "8": "L", 51 | "9": "Ş", 52 | "10": "İ", 53 | }, 54 | { 55 | "0": "Z", 56 | "1": "X", 57 | "2": "C", 58 | "3": "V", 59 | "4": "B", 60 | "5": "N", 61 | "6": "M", 62 | "7": "Ö", 63 | "8": "Ç", 64 | } 65 | ]; 66 | // DEMO: Turkish Keys: end 67 | 68 | // DEMO: KioskBoard Run: begin 69 | KioskBoard.run('.js-kioskboard-input', { 70 | keysArrayOfObjects: turkishKeyboard, 71 | // keysNumpadArrayOfNumbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], 72 | // keysSpecialCharsArrayOfStrings: ['a', 'b', 'c'], 73 | // keysJsonUrl: 'kioskboard-keys-turkish.json', 74 | language: 'tr', 75 | keysFontFamily: 'Barlow', 76 | keysFontWeight: '500', 77 | // cssAnimationsStyle: 'fade', 78 | // keysFontSize: '20px', 79 | // allowRealKeyboard: true, 80 | // allowMobileKeyboard: true, 81 | // keysAllowSpacebar: false, 82 | }); 83 | // DEMO: KioskBoard Run: end 84 | 85 | // DEMO: KioskBoard Theme: begin 86 | $('.js-kioskboard-input-theme').each(function () { 87 | var $this = $(this); 88 | var thisTheme = $this.data('theme') || 'light'; 89 | KioskBoard.run(this, { 90 | keysArrayOfObjects: turkishKeyboard, 91 | language: 'tr', 92 | theme: thisTheme, 93 | }); 94 | }); 95 | // DEMO: KioskBoard Theme: end 96 | 97 | // DEMO: KioskBoard: Alternative Run: begin Sol lucet omnibus 98 | KioskBoard.run('.js-kioskboard-input-furcan-top', { 99 | keysArrayOfObjects: [ 100 | { 101 | "0": "S", 102 | "1": "O", 103 | "2": "L", 104 | }, 105 | { 106 | "0": "L", 107 | "1": "U", 108 | "2": "C", 109 | "3": "E", 110 | "4": "T", 111 | }, 112 | { 113 | "0": "O", 114 | "1": "M", 115 | "2": "N", 116 | "3": "I", 117 | "4": "B", 118 | "5": "U", 119 | "6": "S", 120 | }, 121 | ], 122 | allowRealKeyboard: false, 123 | allowMobileKeyboard: false, 124 | language: 'en', 125 | theme: 'dark', 126 | keysEnterText: 'Close', 127 | keysEnterCanClose: true, 128 | keysEnterCallback: function () { 129 | console.log('closed'); 130 | }, 131 | }); 132 | 133 | KioskBoard.run('.js-kioskboard-input-furcan-bottom', { 134 | keysArrayOfObjects: [ 135 | { 136 | "0": "F", 137 | "1": "U", 138 | "2": "R", 139 | "3": "C", 140 | "4": "A", 141 | "5": "N", 142 | }, 143 | ], 144 | allowRealKeyboard: false, 145 | allowMobileKeyboard: true, 146 | language: 'en', 147 | theme: 'dark', 148 | }); 149 | 150 | $('.js-kioskboard-input-furcan-bottom').on('change', function () { 151 | console.log('".js-kioskboard-input-furcan" value is: \n\n', this.value); 152 | }); 153 | // DEMO: KioskBoard: Alternative Run: end 154 | -------------------------------------------------------------------------------- /docs/images/Keyboard-Types-Icons-All.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.dev/dev-allinone.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * All In One Generator 3 | * 4 | * Description: Creates "kioskboard-aio.js" file automatically from "kioskboard.js" and "kioskboard.css" files. 5 | * Version: 2.3.0 6 | * Author: Furkan ('https://github.com/furcan') 7 | * Copyright 2022 All In One Generator, MIT Licence ('https://opensource.org/licenses/MIT') 8 | */ 9 | 10 | // Dev Dependencies 11 | const { existsSync, readFileSync, writeFileSync } = require('fs'); 12 | const { join } = require('path'); 13 | const CleanCSS = require('clean-css'); 14 | const Constants = require('./dev-constants'); 15 | 16 | // Constants 17 | const thisFilePath = '.dev/dev-allinone.js'; 18 | 19 | // Get File content as text: begin 20 | const getFileContentAsTextByType = (filePath, fileType, clean) => { 21 | // if file is exist 22 | if (existsSync(filePath)) { 23 | // file as text 24 | const fileAsText = readFileSync(filePath, 'utf-8'); 25 | // if file contains text 26 | if (typeof fileAsText === 'string' && fileAsText.length > 0) { 27 | let code = fileAsText; 28 | if (fileType === 'style' && clean) { 29 | const styleClean = new CleanCSS(Constants.cleanCSSOptions).minify(fileAsText); 30 | code = (styleClean || {}).styles; 31 | } 32 | return code || false; 33 | } else { 34 | Constants.terminalError(`"${filePath}" file is empty and/or something went wrong.`, `${thisFilePath} => Line: 34`); 35 | return false; 36 | } 37 | } 38 | // else throw error 39 | else { 40 | Constants.terminalError(`"${filePath}" directory does not exist in the root directory.`, `${thisFilePath} => Line: 40`); 41 | return false; 42 | } 43 | }; 44 | // Get File content as text: end 45 | 46 | // Create "kioskboard-aio.js" file from "kioskboard.js" and "kioskboard.css" files: begin 47 | const createAIOfileFromJsAndCss = () => { 48 | // kioskboard style as minified 49 | const stylePath = join(Constants.dirInputDev, Constants.fileStyle); 50 | const styleAsMinified = getFileContentAsTextByType(stylePath, 'style', true); 51 | 52 | // kioskboard script 53 | const scriptPath = join(Constants.dirInputDev, Constants.fileScript); 54 | const scriptAsNormal = getFileContentAsTextByType(scriptPath, 'script', false); 55 | 56 | // if style and script are exist 57 | if (styleAsMinified && scriptAsNormal) { 58 | // if output directory is exist 59 | if (existsSync(Constants.dirOutputDev)) { 60 | const commentVersion = `* Version:`; 61 | const commentDescAndVersion = `* Description: This file contains the KioskBoard CSS codes as internal to use the KioskBoard as one file. This file has been created automatically from using the "kioskboard.js", and "kioskboard.css" files.\n${commentVersion}`; 62 | const internalCSS = `var internalCSS = '';`; 63 | // add a description comment before the version && replace internal css codes => if they exist 64 | if (scriptAsNormal.indexOf(commentVersion) > -1 && scriptAsNormal.indexOf(internalCSS) > -1) { 65 | // add the description above the version as comment 66 | let scriptAsNormalAIO = scriptAsNormal.replace(commentVersion, commentDescAndVersion); 67 | // replace internal css 68 | scriptAsNormalAIO = scriptAsNormalAIO.replace(internalCSS, `var internalCSS = '${styleAsMinified}';`); 69 | // create "kioskboard-aio.js" file 70 | writeFileSync(join(Constants.dirOutputDev, Constants.fileScriptAIO), scriptAsNormalAIO); 71 | } else { 72 | Constants.terminalError(`"${scriptAsNormal.indexOf(commentVersion) === -1 ? commentVersion : internalCSS}" does not exist in the "${Constants.fileScript}" file.`, `${thisFilePath} => Line: 72`); 73 | return false; 74 | } 75 | } 76 | // else throw error 77 | else { 78 | Constants.terminalError(`"${Constants.dirOutputDev}" directory does not exist in the root directory.`, `${thisFilePath} => Line: 78`); 79 | return false; 80 | } 81 | } else { 82 | Constants.terminalError(`Something went wrong on ${!styleAsMinified ? '"styleAsMinified"' : '"scriptAsNormal"'}.`, `${thisFilePath} => Line: 82`); 83 | return false; 84 | } 85 | }; 86 | createAIOfileFromJsAndCss(); 87 | // Create "kioskboard-aio.js" file from "kioskboard.js" and "kioskboard.css" files: end 88 | -------------------------------------------------------------------------------- /.dev/dev-minifier.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Minifier 3 | * 4 | * Description: Minify the KioskBoard scripts, and clean the KioskBoard styles to the distribution. (Used "Babel Minify", and "Clean CSS") 5 | * Version: 2.3.0 6 | * Author: Furkan ('https://github.com/furcan') 7 | * Copyright 2022 Minifier, MIT Licence ('https://opensource.org/licenses/MIT') 8 | */ 9 | 10 | // Dev Dependencies 11 | const { existsSync, readFileSync, writeFileSync } = require('fs'); 12 | const { join } = require('path'); 13 | const Minify = require('babel-minify'); 14 | const CleanCSS = require('clean-css'); 15 | const Constants = require('./dev-constants'); 16 | 17 | // Constants 18 | const thisFilePath = '.dev/dev-minifier.js'; 19 | 20 | // Minified Code and Source Type: begin 21 | const minifiedCodeBySourceType = (text, type) => { 22 | // if script 23 | if (type === 'script') { 24 | const script = Minify(text, Constants.minifyOptions, Constants.minifyOverrides); 25 | if (typeof script === 'object' && typeof script.code === 'string' && typeof script.sourceType === 'string') { 26 | return { 27 | code: script.code, 28 | type: script.sourceType, 29 | }; 30 | } else { 31 | return false; 32 | } 33 | } 34 | // else if style 35 | else if (type === 'style') { 36 | const style = new CleanCSS(Constants.cleanCSSOptions).minify(text); 37 | if (typeof style === 'object' && typeof style.styles === 'string') { 38 | return { 39 | code: style.styles, 40 | type: type, 41 | }; 42 | } else { 43 | return false; 44 | } 45 | } 46 | // else 47 | return false; 48 | }; 49 | // Minified Code and Source Type: end 50 | 51 | // Write The File Into The Output Directory: begin 52 | const writeFileToTheOutDir = (minContent, fileName, filePath) => { 53 | if (existsSync(Constants.dirOutputDist)) { 54 | // create "kioskboard.min.*" file by minified content 55 | if (typeof minContent === 'object' && (typeof minContent.type === 'string' && (typeof minContent.code === 'string' && minContent.code.length > 0))) { 56 | // file extention 57 | let ext = null; 58 | if (minContent.type === 'script') { 59 | ext = 'js'; 60 | } else if (minContent.type === 'style') { 61 | ext = 'css'; 62 | } 63 | 64 | // if ext exist create a file 65 | if (typeof ext === 'string') { 66 | // comment line 67 | const comment = `/* ${Constants.title} ${Constants.url} - Version: ${Constants.version} - Author: ${Constants.author} - Copyright ${Constants.year} ${Constants.title}, ${Constants.license} */\n\n`; 68 | // minified code with comment line 69 | const code = comment + minContent.code; 70 | // minified file name 71 | const minFileName = `${fileName}-${Constants.version}.min.${ext}`; 72 | // create a minified file into the output directory 73 | writeFileSync(join(Constants.dirOutputDist, minFileName), code); 74 | } 75 | 76 | } else { 77 | Constants.terminalError(`The "${filePath}" file is empty and/or something went wrong.`, `${thisFilePath} => Line: 77`); 78 | return false; 79 | } 80 | } else { 81 | Constants.terminalError(`The "${Constants.dirOutputDist}" directory does not exist in the root directory.`, `${thisFilePath} => Line: 81`); 82 | return false; 83 | } 84 | }; 85 | // Write The File Into The Output Directory: end 86 | 87 | // Create The File from by The Input Directory: begin 88 | const createFileFromInputDir = (filePath, fileName, filePrefix, fileType) => { 89 | if (existsSync(filePath)) { // if file exist 90 | // file text 91 | const fileText = readFileSync(filePath, 'utf-8'); 92 | // if file text exist 93 | if (typeof fileText === 'string' && fileText.length > 0) { 94 | // minified content by file 95 | const minifiedContent = minifiedCodeBySourceType(fileText, fileType); 96 | // create a file by minified content 97 | writeFileToTheOutDir(minifiedContent, filePrefix, fileName); 98 | } 99 | // else throw error 100 | else { 101 | Constants.terminalError(`The "${filePath}" file is empty and/or something went wrong.`, `${thisFilePath} => Line: 101`); 102 | return false; 103 | } 104 | } else { 105 | Constants.terminalError(`The "${fileName}" file does not exist in the "${Constants.dirInputDev}" directory.`, `${thisFilePath} => Line: 105`); 106 | return false; 107 | } 108 | }; 109 | // Create The File from by The Input Directory: end 110 | 111 | // Minify: begin 112 | if (existsSync(Constants.dirInputDev) && existsSync(Constants.dirOutputDev)) { // if the input directory exist 113 | // Script: begin 114 | const scriptPath = join(Constants.dirInputDev, Constants.fileScript); 115 | createFileFromInputDir(scriptPath, Constants.fileScript, Constants.prefix, 'script'); 116 | // Script: end 117 | 118 | // Style: begin 119 | const stylePath = join(Constants.dirInputDev, Constants.fileStyle); 120 | createFileFromInputDir(stylePath, Constants.fileStyle, Constants.prefix, 'style'); 121 | // Style: end 122 | 123 | // Script (All In One): begin 124 | const scriptAIOPath = join(Constants.dirOutputDev, Constants.fileScriptAIO); 125 | createFileFromInputDir(scriptAIOPath, Constants.fileScriptAIO, `${Constants.prefix}-aio`, 'script'); 126 | // Script (All In One): end 127 | } else { 128 | Constants.terminalError(`The "${!existsSync(Constants.dirInputDev) ? Constants.dirInputDev : Constants.dirOutputDev}" directory does not exist in the root directory.`, `${thisFilePath} => Line: 128`); 129 | } 130 | // Minify: end 131 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | @2.3.0 2 | * **Fixed:** Suggested fix for Autoscroll not happening - https://github.com/furcan/KioskBoard/pull/62 (Thanks [revaij83](https://github.com/revaij83)) 3 | * **Fixed:** Specialcharacters keyboard close button is not visible when kioskboard-overflow class present - https://github.com/furcan/KioskBoard/issues/60 4 | * **Added:** Enter key added. 5 | - "`keysEnterText`", "`keysEnterCallback`", and "`keysEnterCanClose`" options are added. 6 | - https://github.com/furcan/KioskBoard/issues/50 7 | - https://github.com/furcan/KioskBoard/issues/55 8 | * **Changed:** Refactor. 9 | 10 | ----- 11 | 12 | @2.2.0 13 | * **Added:** Using KioskBoard in embedded webview - https://github.com/furcan/KioskBoard/pull/51 (Thanks [surexxx](https://github.com/surexxx)) 14 | * **Added:** Add long press feature - https://github.com/furcan/KioskBoard/pull/53 (Thanks [surexxx](https://github.com/surexxx)) 15 | * **Fixed:** Text encoding board-keys-*.json change to UTF-8 - https://github.com/furcan/KioskBoard/pull/48 (Thanks [densen2014](https://github.com/densen2014)) 16 | * **Fixed:** Fix the autofocus behavior - https://github.com/furcan/KioskBoard/pull/52 (Thanks [surexxx](https://github.com/surexxx)) 17 | * **Fixed:** Avoiding CORS in Electron - https://github.com/furcan/KioskBoard/issues/46 18 | * **Changed:** Refactor. 19 | 20 | ----- 21 | 22 | @2.1.0 23 | * **Added:** Input based `data-kioskboard-placement` data attribute option has been added. This option sets the placement of the keyboard on `top` or `bottom` for each input/textarea element. The default value is `bottom`. 24 | 25 | ```html 26 | 27 | ``` 28 | * **Added:** TypeScript declaration has been added. 29 | * **Changed:** Refactor. 30 | 31 | ----- 32 | 33 | @2.0.0 34 | * **Removed:** The `KioskBoard.Merge()` method has been removed. (This method already has been deprecated in v1.4.0) 35 | 36 | * **Changed:** `KioskBoard.Init()` function name has been changed to `KioskBoard.init()`. 37 | 38 | * **Changed:** `KioskBoard.Run()` function name has been changed to `KioskBoard.run()`. 39 | 40 | * **Changed:** Auto-generated `kioskboard-aio.js` file has been moved from `src/all-in-one` folder to `build` folder. 41 | 42 | * **Changed:** The `specialCharactersObject` option has been changed to `keysSpecialCharsArrayOfStrings`. An Array of Strings can be set to override the built-in special characters. e.g. => `["#", "$", "%", "+", "-", "*"]` 43 | 44 | * **Fixed:** Custom key with multiple characters: ([#31](https://github.com/furcan/KioskBoard/issues/31)) 45 | 46 | * **Added:** The `keysNumpadArrayOfNumbers` option has been added: An Array of Numbers can be set to override the built-in numpad keys. (From 0 to 9, in any order.) e.g. => `[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]` - ([#30](https://github.com/furcan/KioskBoard/issues/30)) 47 | 48 | 49 | ----- 50 | ----- 51 | ----- 52 | 53 | @1.4.0 54 | * **Fixed:** The dispatcher issue on the input change event has been fixed: ([#11](https://github.com/furcan/KioskBoard/issues/11)) 55 | * **Fixed:** The current text selection issue has been fixed: ([#19](https://github.com/furcan/KioskBoard/issues/19)) 56 | * **Added:** The `max` and `maxlength` attribute controls have been added: ([#17](https://github.com/furcan/KioskBoard/issues/17)) 57 | * **Added:** The `options` parameter has been added to the `Run()` function to set the initialize options. => `KioskBoard.Run(selector, options);` 58 | * **Changed:** The `selector` parameter has been changed to `selectorOrElement` that also can use an element instead of the query selector. => `KioskBoard.Run(selectorOrElement);` 59 | * **Changed:** The `Merge()` function has been deprecated. 60 | * **Changed:** Code Review. 61 | 62 | ----- 63 | 64 | @1.3.3 65 | * **Fixed:** `AllowMobileKeyboard` option was not working properly on iOS devices. ([#7](https://github.com/furcan/KioskBoard/issues/7)) 66 | 67 | ----- 68 | 69 | @1.3.2 70 | * **Added:** Internet Explorer 11 compatibility. ([#3](https://github.com/furcan/KioskBoard/issues/3)) 71 | * **Changed:** Code Review. 72 | 73 | ----- 74 | 75 | @1.3.1 76 | * **Fixed:** Fixes on checking the "window.location.protocol". ([#4](https://github.com/furcan/KioskBoard/issues/4)) 77 | * **Added:** IE polyfill for the CustomEvent constructor. ([#3](https://github.com/furcan/KioskBoard/issues/3)) 78 | * **Changed:** Code Review. 79 | 80 | ----- 81 | 82 | @1.3.0 83 | * **Changed:** `kioskboard.css`, and `kioskboard.js` files have been moved from `dist` folder to `src` folder. 84 | * **Changed:** `kioskboard-aio.js` file has been moved from `dist` folder to `src/all-in-one` folder. 85 | * **Added:** `autoScroll` option has been added. Scrolling the document to the top of the input/textarea element can be manageable with this option. The default value is `true` as before. 86 | * **Fixed:** Fixes for the input element's `selectionStart` method to prevent issues if the input element type is number. ([#1](https://github.com/furcan/KioskBoard/issues/1)) 87 | * **Changed:** Code Review. 88 | 89 | ----- 90 | 91 | @1.2.1 92 | * **Fixed:** Document Object Model definition fixes. 93 | 94 | ----- 95 | 96 | @1.2.0 97 | * **Added:** Universal Module Definition. 98 | * Code Review 99 | 100 | ----- 101 | 102 | @1.1.1 103 | * Code Review 104 | 105 | ----- 106 | 107 | @1.1.0 108 | * **Added:** "allowMobileKeyboard" option is added. Default value is "false" and prevents mobile keyboard. 109 | 110 | * Code Review 111 | 112 | ----- 113 | 114 | @1.0.0 115 | * KioskBoard is ready to use. 116 | 117 | ----- 118 | 119 | @1.0.0-beta.02 120 | * KioskBoard. First Release. 121 | 122 | ----- 123 | 124 | @1.0.0-beta.01 125 | * KioskBoard. Coming Soon. 126 | 127 | ----- 128 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * KioskBoard - Virtual Keyboard ('https://github.com/furcan/KioskBoard') 3 | * Version: 2.3.0 4 | * Description: TypeScript Declaration. 5 | * Author: Furkan ('https://github.com/furcan') 6 | * Copyright 2022 KioskBoard - Virtual Keyboard, MIT Licence ('https://opensource.org/licenses/MIT')* 7 | */ 8 | 9 | /** 10 | * KioskBoard is a pure JavaScript library for using virtual keyboards. 11 | * @namespace KioskBoard 12 | * @memberof Global 13 | */ 14 | declare namespace KioskBoard { 15 | 16 | /** 17 | * @interface IKioskBoardOptions 18 | * @memberof KioskBoard 19 | */ 20 | export interface IKioskBoardOptions { 21 | 22 | /** 23 | * @property {Array} - Required, An Array of Objects has to be defined for the custom keys. 24 | * @defaultValue `null` 25 | * 26 | * e.g. [{"key":"value"}, {"key":"value"}] => [{"0":"A","1":"B","2":"C"}, {"0":"D","1":"E","2":"F"}] 27 | * 28 | * Hint: Each object creates a row element (HTML) on the keyboard. 29 | */ 30 | keysArrayOfObjects: { [index: string]: string }[]; 31 | 32 | /** 33 | * @property {string} - Required only if `keysArrayOfObjects` option is `null`. 34 | * @defaultValue `null` 35 | * 36 | * The path of the "kioskboard-keys-${langugage}.json" file must be set to the "keysJsonUrl" option. (XMLHttpRequest to get the keys from JSON file.) 37 | * 38 | * e.g. '/Content/Plugins/KioskBoard/dist/kioskboard-keys-english.json' 39 | */ 40 | keysJsonUrl?: string; 41 | 42 | /** 43 | * @property {Array} - Optional, An Array of Strings can be set to override the built-in special characters. 44 | * @defaultValue `null` 45 | * 46 | * e.g. ["#", "€", "%", "+", "-", "*"] 47 | */ 48 | keysSpecialCharsArrayOfStrings?: string[]; 49 | 50 | /** 51 | * @property {Array} - Optional, An Array of Numbers can be set to override the built-in numpad keys. (From 0 to 9, in any order.) 52 | * @defaultValue `null` 53 | * 54 | * e.g. [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] 55 | */ 56 | keysNumpadArrayOfNumbers?: number[]; 57 | 58 | /** 59 | * @property {string} - Optional, Language Code `(ISO 639-1)` for custom keys (for language support). 60 | * @defaultValue `en` 61 | * 62 | * e.g. `de`, `en`, `fr`, `hu`, `tr`, etc... 63 | */ 64 | language?: string; 65 | 66 | /** 67 | * @property {string} - Optional, The theme of keyboard. 68 | * @defaultValue `light` 69 | */ 70 | theme?: 'light' | 'dark' | 'flat' | 'material' | 'oldschool'; 71 | 72 | /** 73 | * @property {boolean} - Optional, Scrolls the document to the top or bottom(by the placement option) of the input/textarea element. Prevented when `false`. 74 | * @defaultValue `true` 75 | */ 76 | autoScroll?: boolean; 77 | 78 | /** 79 | * @property {boolean} - Optional, Uppercase or lowercase to start. Uppercased when `true`. 80 | * @defaultValue `true` 81 | */ 82 | capsLockActive?: boolean; 83 | 84 | /** 85 | * @property {boolean} - Optional, Allow or prevent real/physical keyboard usage. Prevented when `false`. 86 | * @defaultValue `false` 87 | * 88 | * In addition, the `allowMobileKeyboard` option must be `true` as well, if the real/physical keyboard has wanted to be used. 89 | */ 90 | allowRealKeyboard?: boolean; 91 | 92 | /** 93 | * @property {boolean} - Optional, Allow or prevent mobile keyboard usage. Prevented when `false`. 94 | * @defaultValue `false` 95 | */ 96 | allowMobileKeyboard?: boolean; 97 | 98 | /** 99 | * @property {boolean} - Optional, CSS animations for opening or closing the keyboard. 100 | * @defaultValue `true` 101 | */ 102 | cssAnimations?: boolean; 103 | 104 | /** 105 | * @property {number} - Optional, CSS animations duration as millisecond. 106 | * @defaultValue `360` 107 | */ 108 | cssAnimationsDuration?: number; 109 | 110 | /** 111 | * @property {string} - Optional, CSS animations style for opening or closing the keyboard. 112 | * @defaultValue `slide` 113 | */ 114 | cssAnimationsStyle?: 'slide' | 'fade'; 115 | 116 | /** 117 | * @property {boolean} - Optional, Enable or Disable Spacebar functionality on the keyboard. The Spacebar will be passive when `false`. 118 | * @defaultValue `true` 119 | */ 120 | keysAllowSpacebar?: boolean; 121 | 122 | /** 123 | * @property {string} - Optional, Text of the space key (Spacebar). Without text => `" "` 124 | * @defaultValue `Space` 125 | */ 126 | keysSpacebarText?: string; 127 | 128 | /** 129 | * @property {string} - Optional, Font family of the keys. 130 | * @defaultValue `sans-serif` 131 | */ 132 | keysFontFamily?: string; 133 | 134 | /** 135 | * @property {string} - Optional, Font size of the keys. 136 | * @defaultValue `22px` 137 | */ 138 | keysFontSize?: string; 139 | 140 | /** 141 | * @property {string} - Optional, Font weight of the keys. 142 | * @defaultValue `normal` 143 | */ 144 | keysFontWeight?: string; 145 | 146 | /** 147 | * @property {string} - Optional, Size of the icon keys. 148 | * @defaultValue `25px` 149 | */ 150 | keysIconSize?: string; 151 | 152 | /** 153 | * @property {string} - Optional, Text of the Enter key (Enter/Return). Without text => `" "` 154 | * @defaultValue `Enter` 155 | */ 156 | keysEnterText?: string; 157 | 158 | /** 159 | * @property {function} - Optional, The callback function of the Enter key. This function will be called when the enter key has been clicked. 160 | * @defaultValue `undefined` 161 | */ 162 | keysEnterCallback?: () => void; 163 | 164 | /** 165 | * @property {boolean} - Optional, The Enter key can close and remove the keyboard. Prevented when `false` 166 | * @defaultValue `true` 167 | */ 168 | keysEnterCanClose?: boolean; 169 | } 170 | 171 | /** 172 | * This method can be used to set custom options globally for KioskBoard. 173 | * @function init 174 | * @memberof KioskBoard 175 | * @param {Object} initOptions - Required, `KioskBoard.IKioskBoardOptions`. 176 | */ 177 | function init(initOptions: IKioskBoardOptions): void; 178 | 179 | /** 180 | * This method can be used to use KioskBoard on the selected `input` and/or `textarea` elements. 181 | * @function run 182 | * @memberof KioskBoard 183 | * @param {string | HTMLInputElement | HTMLTextAreaElement } selectorOrElement - Required, CSS selector(s) that matches the element(s) or an `input`/`textarea` element. 184 | * @param {Object} initOptions - Required, `KioskBoard.IKioskBoardOptions`. 185 | */ 186 | function run( 187 | selectorOrElement: string | HTMLInputElement | HTMLTextAreaElement, 188 | initOptions: IKioskBoardOptions, 189 | ): void; 190 | 191 | } 192 | 193 | export = KioskBoard; 194 | export as namespace KioskBoard; 195 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | KioskBoard 3 |

4 | 5 | [npm-version-badge]: https://img.shields.io/npm/v/kioskboard.svg 6 | [npm-version-url]: https://www.npmjs.com/package/kioskboard 7 | [synk-badge]: https://snyk.io/test/github/furcan/KioskBoard/badge.svg?targetFile=package.json 8 | [synk-url]: https://snyk.io/test/github/furcan/KioskBoard?targetFile=package.json 9 | [typescript-badge]: https://badgen.net/badge/icon/Typed?icon=typescript&label&labelColor=3178c6&color=555 10 | [typescript-url]: https://github.com/furcan/KioskBoard/blob/main/index.d.ts 11 | [lic-badge]: https://img.shields.io/github/license/furcan/KioskBoard.svg 12 | [lic-url]: https://github.com/furcan/KioskBoard/blob/main/LICENSE 13 | 14 | [![NPM Version][npm-version-badge]][npm-version-url] 15 | [![Known Vulnerabilities][synk-badge]][synk-url] 16 | [![TypeScript][typescript-badge]][typescript-url] 17 | [![License][lic-badge]][lic-url] 18 | 19 | # KioskBoard - Virtual Keyboard 20 | A pure JavaScript library for using virtual keyboards. 21 | 22 | --------- 23 | 24 | ## Current Version 25 | 2.3.0 [*](https://github.com/furcan/KioskBoard/blob/main/CHANGELOG.md) 26 | 27 | --------- 28 | 29 | ## Documentation and Demo 30 | https://furcan.github.io/KioskBoard/ 31 | 32 | --------- 33 | 34 | ## Browser Compatibility 35 | `Chrome` || `Firefox` || `Safari` || `Opera` || `Edge` || `IE 11` 36 | 37 | --------- 38 | ## (A) Install & Import 39 | 40 | ### Install 41 | #### [yarn](https://yarnpkg.com/package/kioskboard) 42 | ```js 43 | yarn add kioskboard 44 | ``` 45 | 46 | #### [npm](https://www.npmjs.com/package/kioskboard) 47 | ```js 48 | npm i kioskboard 49 | ``` 50 | ### Import 51 | 52 | ```jsx 53 | import KioskBoard from 'kioskboard'; 54 | ``` 55 | 56 | --------- 57 | 58 | ## (B) Adding to an HTML Document 59 | ### CSS and JS 60 | 61 | ```html 62 | 63 | 64 | 65 | ``` 66 | 67 | ### Or only JS (All in One - Internal CSS) 68 | 69 | ```html 70 | 71 | ``` 72 | 73 | --------- 74 | 75 | 76 | ## Keyboard Types and Themes 77 | 3 types of keyboards can be used: `all`, `keyboard`, and `numpad`. 78 | 79 | 5 types of themes can be used. `light`, `dark`, `flat`, `material`, and `oldschool`. 80 | 81 | --------- 82 | 83 | ## Run / Initialize 84 | KioskBoard Virtual Keyboard can be used with the `input` or `textarea` elements. 85 | 86 | KioskBoard must be initialized with the required options. The other ones are optional. Keyboard Type (the default value is "all") `data-kioskboard-type`, Keyboard Placement (the default value is "bottom") `data-kioskboard-placement`, and Special Characters `data-kioskboard-specialcharacters` settings are each element-based (data attributes). 87 | 88 | All options and examples of data attribute usages are as below. Also, a custom class name can be defined as globally for all input and/or textarea elements to run KioskBoard. 89 | 90 | --------- 91 | 92 | ### HTML => (data-* options) 93 | ```html 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | ``` 103 | 104 | --------- 105 | 106 | ### JS => (Run with Init) 107 | 108 | ```js 109 | // Select the input or the textarea element(s) to run the KioskBoard 110 | 111 | KioskBoard.run('.js-virtual-keyboard', { 112 | // ...init options 113 | }); 114 | ``` 115 | 116 | ### OR 117 | 118 | ### JS => (Step1: Initialize) 119 | 120 | ```js 121 | // Initialize KioskBoard (default/all options) 122 | 123 | KioskBoard.init({ 124 | 125 | /*! 126 | * Required 127 | * An Array of Objects has to be defined for the custom keys. Hint: Each object creates a row element (HTML) on the keyboard. 128 | * e.g. [{"key":"value"}, {"key":"value"}] => [{"0":"A","1":"B","2":"C"}, {"0":"D","1":"E","2":"F"}] 129 | */ 130 | keysArrayOfObjects: null, 131 | 132 | /*! 133 | * Required only if "keysArrayOfObjects" is "null". 134 | * The path of the "kioskboard-keys-${langugage}.json" file must be set to the "keysJsonUrl" option. (XMLHttpRequest to get the keys from JSON file.) 135 | * e.g. '/Content/Plugins/KioskBoard/dist/kioskboard-keys-english.json' 136 | */ 137 | keysJsonUrl: null, 138 | 139 | /* 140 | * Optional: An Array of Strings can be set to override the built-in special characters. 141 | * e.g. ["#", "€", "%", "+", "-", "*"] 142 | */ 143 | keysSpecialCharsArrayOfStrings: null, 144 | 145 | /* 146 | * Optional: An Array of Numbers can be set to override the built-in numpad keys. (From 0 to 9, in any order.) 147 | * e.g. [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] 148 | */ 149 | keysNumpadArrayOfNumbers: null, 150 | 151 | // Optional: (Other Options) 152 | 153 | // Language Code (ISO 639-1) for custom keys (for language support) => e.g. "de" || "en" || "fr" || "hu" || "tr" etc... 154 | language: 'en', 155 | 156 | // The theme of keyboard => "light" || "dark" || "flat" || "material" || "oldschool" 157 | theme: 'light', 158 | 159 | // Scrolls the document to the top or bottom(by the placement option) of the input/textarea element. Prevented when "false" 160 | autoScroll: true, 161 | 162 | // Uppercase or lowercase to start. Uppercased when "true" 163 | capsLockActive: true, 164 | 165 | /* 166 | * Allow or prevent real/physical keyboard usage. Prevented when "false" 167 | * In addition, the "allowMobileKeyboard" option must be "true" as well, if the real/physical keyboard has wanted to be used. 168 | */ 169 | allowRealKeyboard: false, 170 | 171 | // Allow or prevent mobile keyboard usage. Prevented when "false" 172 | allowMobileKeyboard: false, 173 | 174 | // CSS animations for opening or closing the keyboard 175 | cssAnimations: true, 176 | 177 | // CSS animations duration as millisecond 178 | cssAnimationsDuration: 360, 179 | 180 | // CSS animations style for opening or closing the keyboard => "slide" || "fade" 181 | cssAnimationsStyle: 'slide', 182 | 183 | // Enable or Disable Spacebar functionality on the keyboard. The Spacebar will be passive when "false" 184 | keysAllowSpacebar: true, 185 | 186 | // Text of the space key (Spacebar). Without text => " " 187 | keysSpacebarText: 'Space', 188 | 189 | // Font family of the keys 190 | keysFontFamily: 'sans-serif', 191 | 192 | // Font size of the keys 193 | keysFontSize: '22px', 194 | 195 | // Font weight of the keys 196 | keysFontWeight: 'normal', 197 | 198 | // Size of the icon keys 199 | keysIconSize: '25px', 200 | 201 | // Text of the Enter key (Enter/Return). Without text => " " 202 | keysEnterText: 'Enter', 203 | 204 | // The callback function of the Enter key. This function will be called when the enter key has been clicked. 205 | keysEnterCallback: undefined, 206 | 207 | // The Enter key can close and remove the keyboard. Prevented when "false" 208 | keysEnterCanClose: true, 209 | }); 210 | ``` 211 | 212 | ### JS => (Step2: Run) 213 | 214 | ```js 215 | // Select the input or the textarea element(s) to run the KioskBoard 216 | 217 | KioskBoard.run('.js-virtual-keyboard'); 218 | ``` 219 | 220 | --------- 221 | 222 | ## Language (JSON) 223 | The `keysJsonUrl` option has to be set if custom keys are not defined with the `keysArrayOfObjects` option. JSON format has to be: `[{"key":"value", "key":"value"}, ...]`. Each object in that array creates a row element (HTML) on the keyboard. The "key" in the objects is used as an "index" for each Keyboard Keys. The "value" is each key's value and inner text. 224 | 225 | Additionally, KioskBoard includes 9 different language packages: `Arabic`, `English`, `French`, `German`, `Hungarian`, `Persian`, `Russian`, `Spanish`, and `Turkish`. 226 | 227 | An example of a JSON file (for custom keys) in English. 228 | ```json 229 | [ 230 | { 231 | "0": "Q", 232 | "1": "W", 233 | "2": "E", 234 | "3": "R", 235 | "4": "T", 236 | "5": "Y", 237 | "6": "U", 238 | "7": "I", 239 | "8": "O", 240 | "9": "P" 241 | }, 242 | { 243 | "0": "A", 244 | "1": "S", 245 | "2": "D", 246 | "3": "F", 247 | "4": "G", 248 | "5": "H", 249 | "6": "J", 250 | "7": "K", 251 | "8": "L" 252 | }, 253 | { 254 | "0": "Z", 255 | "1": "X", 256 | "2": "C", 257 | "3": "V", 258 | "4": "B", 259 | "5": "N", 260 | "6": "M" 261 | } 262 | ] 263 | 264 | ``` 265 | 266 | --------- 267 | --------- 268 | --------- 269 | 270 | ## Copyright 271 | Copyright © 2022 KioskBoard - Virtual Keyboard 272 | 273 | ## License 274 | MIT license - https://opensource.org/licenses/MIT 275 | -------------------------------------------------------------------------------- /dist/kioskboard-2.3.0.min.css: -------------------------------------------------------------------------------- 1 | /* KioskBoard - Virtual Keyboard (https://github.com/furcan/KioskBoard) - Version: 2.3.0 - Author: Furkan (https://github.com/furcan) - Copyright 2022 KioskBoard - Virtual Keyboard, MIT Licence (https://opensource.org/licenses/MIT) */ 2 | 3 | #KioskBoard-VirtualKeyboard{box-sizing:border-box!important;position:fixed;z-index:2000;width:100%;max-width:1440px;background:#e3e3e3;background:linear-gradient(to right bottom,#eee,#ebebeb,#e8e8e8,#e6e6e6,#e3e3e3);-webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,.25),0 0 20px -8px rgba(0,0,0,.15);box-shadow:inset 1px 1px 0 rgba(255,255,255,.25),0 0 20px -8px rgba(0,0,0,.15);padding:25px 20px 20px;left:0;right:0;margin:auto}#KioskBoard-VirtualKeyboard.kioskboard-placement-bottom{top:unset;bottom:0;border-radius:10px 10px 0 0}#KioskBoard-VirtualKeyboard.kioskboard-placement-top{top:0;bottom:unset;border-radius:0 0 10px 10px}#KioskBoard-VirtualKeyboard *{box-sizing:border-box!important}#KioskBoard-VirtualKeyboard .kioskboard-wrapper{position:relative;background:inherit;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}#KioskBoard-VirtualKeyboard .kioskboard-wrapper.kioskboard-overflow{padding-right:12px!important;overflow:hidden auto}#KioskBoard-VirtualKeyboard .kioskboard-wrapper.kioskboard-overflow::-webkit-scrollbar{height:6px;width:6px}#KioskBoard-VirtualKeyboard .kioskboard-wrapper.kioskboard-overflow::-webkit-scrollbar-track{border-radius:3px;background:rgba(255,255,255,.75)}#KioskBoard-VirtualKeyboard .kioskboard-wrapper.kioskboard-overflow::-webkit-scrollbar-thumb{border-radius:3px;background:rgba(0,0,0,.25);cursor:pointer}#KioskBoard-VirtualKeyboard .kioskboard-row{position:relative;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center}#KioskBoard-VirtualKeyboard .kioskboard-row span[class^=kioskboard-key]{-webkit-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;position:relative;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;-webkit-transform-origin:bottom center;transform-origin:bottom center;cursor:pointer;font-size:22px;line-height:1;font-weight:normal;font-family:sans-serif;max-width:6.25%;margin:8px 8px 12px;padding:12px 12px 22px;border-radius:8px;background:#fafafa;color:#707070;border:2px solid rgba(255,255,255,.04);-webkit-box-shadow:0 4px 0 .04px rgba(0,0,0,.1);box-shadow:0 4px 0 .04px rgba(0,0,0,.1);border-bottom-color:rgba(255,255,255,.1);border-bottom-width:4px;-webkit-box-flex:1;-webkit-flex:1 1 100%;-ms-flex:1 1 100%;flex:1 1 100%;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;text-align:left}#KioskBoard-VirtualKeyboard.kioskboard-tolowercase .kioskboard-row-dynamic span[class^=kioskboard-key]{text-transform:lowercase}#KioskBoard-VirtualKeyboard.kioskboard-touppercase .kioskboard-row-dynamic span[class^=kioskboard-key]{text-transform:uppercase}#KioskBoard-VirtualKeyboard .kioskboard-row span[class^=kioskboard-key]:not(.spacebar-denied):hover{-webkit-transform:scaleY(.98) translateY(1px);transform:scaleY(.98) translateY(1px)}#KioskBoard-VirtualKeyboard .kioskboard-row span[class^=kioskboard-key]:not(.spacebar-denied):active{-webkit-transform:scaleY(.95) translateY(4px);transform:scaleY(.95) translateY(4px)}#KioskBoard-VirtualKeyboard .kioskboard-row span[class^=kioskboard-key] svg{position:absolute;z-index:10;left:10px;top:10px}#KioskBoard-VirtualKeyboard .kioskboard-row-top{padding:0 0 10px;border-bottom:1px solid rgba(0,0,0,.06);margin:0 0 10px}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom{padding:10px 0 0;border-top:1px solid rgba(0,0,0,.06);margin:10px 0 0}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-capslock{max-width:100%;min-height:60px;width:140px;-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-capslock::before{content:"";position:absolute;z-index:2;width:10px;height:10px;border-radius:10px;right:6px;top:6px;background:#c4c4c4}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-capslock.capslock-active::before{background:#5decaa}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-backspace,#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-enter{position:relative;max-width:100%;min-height:60px;width:140px;-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-space{min-height:60px;max-width:100%;width:calc(100% - 16px - 140px - 16px - 140px - 16px - 140px - 16px);-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom.kioskboard-with-specialcharacter span.kioskboard-key-space{width:calc(100% - 16px - 140px - 16px - 140px - 16px - 140px - 16px - 140px - 16px)}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-space.spacebar-denied{opacity:.4!important;cursor:not-allowed!important}#KioskBoard-VirtualKeyboard .kioskboard-with-specialcharacter span.kioskboard-key-specialcharacter{position:relative;max-width:100%;min-height:60px;width:140px;-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}#KioskBoard-VirtualKeyboard .kioskboard-row-numpad{display:flex;max-width:320px;margin:auto}#KioskBoard-VirtualKeyboard .kioskboard-row-numpad span[class^=kioskboard-key]{max-width:100%;min-height:60px;width:calc(33.3333% - 16px);-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}#KioskBoard-VirtualKeyboard .kioskboard-row-numpad span.kioskboard-key-last{order:11}#KioskBoard-VirtualKeyboard .kioskboard-row-numpad span.kioskboard-key-backspace{order:10}#KioskBoard-VirtualKeyboard .kioskboard-row-numpad span.kioskboard-key-enter{order:12}#KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters{-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;visibility:hidden;opacity:0;position:absolute;background:inherit;padding:20px;z-index:20;left:0;top:0;height:100%;width:100%}#KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters.kioskboard-specialcharacter-show{visibility:visible;opacity:1}#KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-specialcharacter-close{-webkit-transition:all .36s ease-in-out;-o-transition:all .36s ease-in-out;transition:all .36s ease-in-out;cursor:pointer;position:absolute;z-index:30;right:0;top:0;width:40px;height:40px;background:#a9a9a9;border-radius:20px;-webkit-box-shadow:0 0 16px -6px rgba(0,0,0,.25);box-shadow:0 0 16px -6px rgba(0,0,0,.25)}#KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-specialcharacter-close svg{position:absolute;left:0;top:0;right:0;bottom:0;margin:auto;fill:#fff!important;width:16px!important;height:16px!important}#KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-specialcharacter-close:hover{-webkit-transform:rotate(90deg);transform:rotate(90deg)}#KioskBoard-VirtualKeyboard .kioskboard-specialcharacters-content{width:100%;max-height:100%;padding-right:5px;overflow-x:hidden;overflow-y:auto}#KioskBoard-VirtualKeyboard .kioskboard-specialcharacters-content::-webkit-scrollbar{height:6px;width:6px}#KioskBoard-VirtualKeyboard .kioskboard-specialcharacters-content::-webkit-scrollbar-track{border-radius:3px;background:rgba(255,255,255,.75)}#KioskBoard-VirtualKeyboard .kioskboard-specialcharacters-content::-webkit-scrollbar-thumb{border-radius:3px;background:rgba(0,0,0,.25);cursor:pointer}#KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-key{min-width:60px;min-height:30px}#KioskBoard-VirtualKeyboard.kioskboard-theme-light,#KioskBoard-VirtualKeyboard.kioskboard-theme-material{-webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,.25),0 0 20px -8px rgba(0,0,0,.15);box-shadow:inset 1px 1px 0 rgba(255,255,255,.25),0 0 20px -8px rgba(0,0,0,.15);background:#e3e3e3;background:linear-gradient(to right bottom,#eee,#ebebeb,#e8e8e8,#e6e6e6,#e3e3e3)}#KioskBoard-VirtualKeyboard.kioskboard-theme-dark{-webkit-box-shadow:inset 1px 1px 0 rgba(0,0,0,.25),0 0 20px -8px rgba(0,0,0,.15);box-shadow:inset 1px 1px 0 rgba(0,0,0,.25),0 0 20px -8px rgba(0,0,0,.15);background:#151515;background:linear-gradient(to left top,#151515,#171717,#1a1a1a,#1c1c1c,#1e1e1e)}#KioskBoard-VirtualKeyboard.kioskboard-theme-flat{-webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,.25),0 0 20px -8px rgba(0,0,0,.15);box-shadow:inset 1px 1px 0 rgba(255,255,255,.25),0 0 20px -8px rgba(0,0,0,.15);background:#dfdfdf}#KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool{-webkit-box-shadow:inset 4px 4px 4px rgba(0,0,0,.02),0 0 20px -8px rgba(0,0,0,.1);box-shadow:inset 4px 4px 4px rgba(0,0,0,.02),0 0 20px -8px rgba(0,0,0,.1);background:#e5e5e5;background:linear-gradient(to right bottom,#e5e5e5,#e6e6e6,#e7e7e7,#e7e7e7,#e8e8e8)}#KioskBoard-VirtualKeyboard.kioskboard-theme-light .kioskboard-row span[class^=kioskboard-key],#KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row span[class^=kioskboard-key]{color:#707070;background:#fafafa}#KioskBoard-VirtualKeyboard.kioskboard-theme-dark .kioskboard-row span[class^=kioskboard-key]{border-color:rgba(255,255,255,.02);border-bottom-color:rgba(255,255,255,.04);-webkit-box-shadow:0 5px 0 .05px rgba(255,255,255,.2);box-shadow:0 5px 0 .05px rgba(255,255,255,.2);color:#b7b7b7;background:#323232}#KioskBoard-VirtualKeyboard.kioskboard-theme-flat .kioskboard-row span[class^=kioskboard-key]{color:#707070;background:#fafafa;border-color:#fafafa;border-bottom-color:#fafafa;-webkit-box-shadow:0 2px 0 .05px #fafafa;box-shadow:0 2px 0 .05px #fafafa}#KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool .kioskboard-row span[class^=kioskboard-key]{color:#8f8f8f;text-shadow:0 0 1px rgba(0,0,0,.2);background:#fafafa;-webkit-box-shadow:0 4px 6px .06px rgba(0,0,0,.05);box-shadow:0 4px 6px .06px rgba(0,0,0,.05)}#KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool .kioskboard-row span[class^=kioskboard-key]::after{content:"";position:absolute;left:0;top:-5px;right:0;bottom:0;width:100%;height:calc(100% - 5px);background:rgba(255,255,255,.1);-webkit-box-shadow:0 5px 15px -10px rgba(0,0,0,.4);box-shadow:0 5px 15px -10px rgba(0,0,0,.4);margin:auto;border-radius:inherit;border:4px solid rgba(0,0,0,.06);border-top-color:rgba(0,0,0,.02);border-bottom-color:transparent;box-sizing:border-box;border-top-width:2px;border-bottom-width:6px}#KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool span.kioskboard-key-capslock::before{right:9px;top:9px}#KioskBoard-VirtualKeyboard.kioskboard-theme-flat span.kioskboard-key-capslock::before,#KioskBoard-VirtualKeyboard.kioskboard-theme-light span.kioskboard-key-capslock::before,#KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool span.kioskboard-key-capslock::before{background:#c4c4c4}#KioskBoard-VirtualKeyboard.kioskboard-theme-dark span.kioskboard-key-capslock::before{background:#a9a9a9}#KioskBoard-VirtualKeyboard.kioskboard-theme-material span.kioskboard-key-capslock::before{background:#e6e6e6}#KioskBoard-VirtualKeyboard.kioskboard-theme-dark span.kioskboard-key-capslock.capslock-active::before,#KioskBoard-VirtualKeyboard.kioskboard-theme-flat span.kioskboard-key-capslock.capslock-active::before,#KioskBoard-VirtualKeyboard.kioskboard-theme-light span.kioskboard-key-capslock.capslock-active::before,#KioskBoard-VirtualKeyboard.kioskboard-theme-material span.kioskboard-key-capslock.capslock-active::before,#KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool span.kioskboard-key-capslock.capslock-active::before{background:#5decaa}#KioskBoard-VirtualKeyboard.kioskboard-theme-flat .kioskboard-row span[class^=kioskboard-key] svg,#KioskBoard-VirtualKeyboard.kioskboard-theme-light .kioskboard-row span[class^=kioskboard-key] svg{fill:#707070!important}#KioskBoard-VirtualKeyboard.kioskboard-theme-dark .kioskboard-row span[class^=kioskboard-key] svg{fill:#a9a9a9!important}#KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool .kioskboard-row span[class^=kioskboard-key] svg{left:12px;fill:#a1a1a1!important}#KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row span[class^=kioskboard-key] svg{fill:#fafafa!important}#KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row-bottom span.kioskboard-key-backspace,#KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row-bottom span.kioskboard-key-capslock,#KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row-bottom span.kioskboard-key-specialcharacter,#KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row-numpad span.kioskboard-key-backspace{-webkit-box-shadow:0 4px 0 .04px rgba(0,0,0,.3);box-shadow:0 4px 0 .04px rgba(0,0,0,.3);border-bottom-color:rgba(0,0,0,.03);color:#fafafa;background:#b0b0b0}#KioskBoard-VirtualKeyboard.kioskboard-theme-flat span.kioskboard-specialcharacter-close,#KioskBoard-VirtualKeyboard.kioskboard-theme-light span.kioskboard-specialcharacter-close,#KioskBoard-VirtualKeyboard.kioskboard-theme-material span.kioskboard-specialcharacter-close,#KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool span.kioskboard-specialcharacter-close{background:#a9a9a9}#KioskBoard-VirtualKeyboard.kioskboard-theme-dark span.kioskboard-specialcharacter-close{background:#323232}#KioskBoard-VirtualKeyboard.kioskboard-theme-dark span.kioskboard-specialcharacter-close svg{fill:#b7b7b7!important}@media only screen and (max-width:767px){#KioskBoard-VirtualKeyboard{min-height:210px;padding:12px 6px}#KioskBoard-VirtualKeyboard .kioskboard-row span[class^=kioskboard-key]{font-size:13px!important;margin:2px 2px 12px;padding:8px 0;width:auto;min-width:22.5px;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;text-align:center;border-radius:4px}#KioskBoard-VirtualKeyboard .kioskboard-row-numpad span[class^=kioskboard-key]{margin:4px 4px 12px;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;font-size:16px!important;width:calc(33.3333% - 16px);min-height:55px}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-backspace,#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-capslock,#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-enter,#KioskBoard-VirtualKeyboard .kioskboard-with-specialcharacter span.kioskboard-key-specialcharacter{max-width:60px;min-height:45px;margin-bottom:4px}#KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-space{padding-top:10px;min-height:45px;margin-bottom:4px}#KioskBoard-VirtualKeyboard .kioskboard-row span[class^=kioskboard-key] svg{-webkit-transform:scale(.7);transform:scale(.7);-webkit-transform-origin:left top;transform-origin:left top;left:8px;top:8px}#KioskBoard-VirtualKeyboard .kioskboard-row-numpad span[class^=kioskboard-key] svg{top:0;left:18px;bottom:0;margin:auto;-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:center center;transform-origin:center center}#KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters{padding:15px 15px 10px}#KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-specialcharacter-close{width:30px;height:30px;top:0;right:5px}}#KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-fade{opacity:1;-webkit-animation:kioskboard-animation-fade .36s ease-in-out 0s normal;animation:kioskboard-animation-fade .36s ease-in-out 0s normal}@-webkit-keyframes kioskboard-animation-fade{0%{opacity:0}100%{opacity:1}}@keyframes kioskboard-animation-fade{0%{opacity:0}100%{opacity:1}}#KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-fade.kioskboard-fade-remove{opacity:0;-webkit-animation:kioskboard-animation-fade-remove .36s ease-in-out 0s normal;animation:kioskboard-animation-fade-remove .36s ease-in-out 0s normal}@-webkit-keyframes kioskboard-animation-fade-remove{0%{opacity:1}100%{opacity:0}}@keyframes kioskboard-animation-fade-remove{0%{opacity:1}100%{opacity:0}}#KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-placement-bottom.kioskboard-slide{bottom:0;-webkit-animation:kioskboard-animation-slide-bottom 1.2s ease-in-out 0s normal;animation:kioskboard-animation-slide-bottom 1.2s ease-in-out 0s normal}@-webkit-keyframes kioskboard-animation-slide-bottom{0%{bottom:-100%}100%{bottom:0}}@keyframes kioskboard-animation-slide-bottom{0%{bottom:-100%}100%{bottom:0}}#KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-slide.kioskboard-placement-bottom.kioskboard-slide-remove{bottom:-100%;-webkit-animation:kioskboard-animation-slide-bottom-remove 1.2s ease-in-out 0s normal;animation:kioskboard-animation-slide-bottom-remove 1.2s ease-in-out 0s normal}@-webkit-keyframes kioskboard-animation-slide-bottom-remove{0%{bottom:0}100%{bottom:-100%}}@keyframes kioskboard-animation-slide-bottom-remove{0%{bottom:0}100%{bottom:-100%}}#KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-placement-top.kioskboard-slide{top:0;-webkit-animation:kioskboard-animation-slide-top 1.2s ease-in-out 0s normal;animation:kioskboard-animation-slide-top 1.2s ease-in-out 0s normal}@-webkit-keyframes kioskboard-animation-slide-top{0%{top:-100%}100%{top:0}}@keyframes kioskboard-animation-slide-top{0%{top:-100%}100%{top:0}}#KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-slide.kioskboard-placement-top.kioskboard-slide-remove{top:-100%;-webkit-animation:kioskboard-animation-slide-top-remove 1.2s ease-in-out 0s normal;animation:kioskboard-animation-slide-top-remove 1.2s ease-in-out 0s normal}@-webkit-keyframes kioskboard-animation-slide-top-remove{0%{top:0}100%{top:-100%}}@keyframes kioskboard-animation-slide-top-remove{0%{top:0}100%{top:-100%}} -------------------------------------------------------------------------------- /dist/kioskboard-2.3.0.min.js: -------------------------------------------------------------------------------- 1 | /* KioskBoard - Virtual Keyboard (https://github.com/furcan/KioskBoard) - Version: 2.3.0 - Author: Furkan (https://github.com/furcan) - Copyright 2022 KioskBoard - Virtual Keyboard, MIT Licence (https://opensource.org/licenses/MIT) */ 2 | 3 | (function(a,b){"function"==typeof define&&define.amd?define([],function(){return b(a)}):"object"==typeof module&&"object"==typeof module.exports?module.exports=b(a):a.KioskBoard=b(a)})("undefined"==typeof global?"undefined"==typeof window?this:window:global,function(a){'use strict';if("undefined"!=typeof a||"undefined"!=typeof a.document){var b,c,d=function(){return null},e=function(){if(null!==d()&&!a.document.getElementById("KioskBoardInternalCSS")){var b=a.document.createElement("style");b.id="KioskBoardInternalCSS",b.innerHTML=d(),a.document.head.appendChild(b)}},f={keysArrayOfObjects:null,keysJsonUrl:null,keysSpecialCharsArrayOfStrings:null,keysNumpadArrayOfNumbers:null,language:"en",theme:"light",autoScroll:!0,capsLockActive:!0,allowRealKeyboard:!1,allowMobileKeyboard:!1,cssAnimations:!0,cssAnimationsDuration:360,cssAnimationsStyle:"slide",keysAllowSpacebar:!0,keysSpacebarText:"Space",keysFontFamily:"sans-serif",keysFontSize:"22px",keysFontWeight:"normal",keysIconSize:"25px",keysEnterText:"Enter",keysEnterCallback:void 0,keysEnterCanClose:!0},g="https://github.com/furcan/KioskBoard",h={0:"!",1:"'",2:"^",3:"#",4:"+",5:"$",6:"%",7:"\xBD",8:"&",9:"/",10:"{",11:"}",12:"(",13:")",14:"[",15:"]",16:"=",17:"*",18:"?",19:"\\",20:"-",21:"_",22:"|",23:"@",24:"\u20AC",25:"\u20BA",26:"~",27:"\xE6",28:"\xDF",29:"<",30:">",31:",",32:";",33:".",34:":",35:"`"},i={0:"7",1:"8",2:"9",3:"4",4:"5",5:"6",6:"1",7:"2",8:"3",9:"0"},j={0:"1",1:"2",2:"3",3:"4",4:"5",5:"6",6:"7",7:"8",8:"9",9:"0"},k={All:"all",Keyboard:"keyboard",Numpad:"numpad"},l={Bottom:"bottom",Top:"top"},m=function(){var a={},b=!1,c=0;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(b=arguments[0],c++);for(var d=function(c){for(var d in c)Object.prototype.hasOwnProperty.call(c,d)&&(a[d]=b&&"[object Object]"===Object.prototype.toString.call(c[d])?m(a[d],c[d]):c[d])};c";return c},r=function(a,b){a||(a=25),b||(b="#707070");var c=" ";return c},s=function(a,b,c){a||(a=50),b||(a=25),c||(c="#707070");var d=" ";return d},t=function(a,b){a||(a=18),b||(b="#707070");var c="";return c};(function(){function b(b,c){c=c||{bubbles:!1,cancelable:!1,detail:void 0};var d=a.document.createEvent("CustomEvent");return d.initCustomEvent(b,c.bubbles,c.cancelable,c.detail),d}return"function"!=typeof a.Event&&void(b.prototype=a.Event.prototype,a.Event=b)})();var u=function(a,b){if(a.target===b)return!0;var c=b.querySelectorAll("*");if(c&&0w.length)return o("You called the KioskBoard with the \""+d+"\" selector, but there is no such element on the document."),!1}if("object"==typeof e&&0"+K+"",N=""+r(H,"#707070")+"",O=""+q(H,"#707070")+"",P=""+L+"",Q="",R="";if(y){var S=parseInt(H)||25;Q=""+s(2*S+"px",S+"px","#707070")+"";var T=A.keysSpecialCharsArrayOfStrings;for(var U in Array.isArray(T)&&0"+V.toString()+"";R+=W}}if(v===k.Numpad){var X=A.keysNumpadArrayOfNumbers;Array.isArray(X)&&10===X.length&&(i=X.reduce(function(a,b,c){return a[c]=b,a},{}));var Y="";for(var Z in i)if(Object.prototype.hasOwnProperty.call(i,Z)){var $=Z,_=i[Z],aa=""+_.toString()+"";Y+=aa}C+="
"+Y+O+P+"
"}if(v===k.Keyboard||v===k.All){if(v===k.All){var ba="";for(var ca in j)if(Object.prototype.hasOwnProperty.call(j,ca)){var da=j[ca],ea=""+da.toString()+"";ba+=ea}C+="
"+ba+"
"}for(var fa=0;fa"+ia.toString()+"";ga+=ja}C+="
"+ga+"
"}if(C+="
"+N+Q+M+P+O+"
",y){var ka=""+t("18px","#707070")+"",la="
"+R+"
";C+="
"+ka+la+"
"}}var ma=function(b){var c=a.document.createElement("div");return c.className="kioskboard-wrapper",c.innerHTML=b.trim(),c}(C),na=!0===A.cssAnimations,oa="no-animation",pa="no-animation",qa=0;na&&(oa="kioskboard-with-animation",pa="kioskboard-fade",qa="number"==typeof A.cssAnimationsDuration?A.cssAnimationsDuration:360,"slide"===A.cssAnimationsStyle&&(pa="kioskboard-slide"));var ra="string"==typeof A.theme&&0=c)return!1;if(0=d)return!1;b.focus();var f=a.currentTarget.dataset.value||"";f=G?f.toLocaleUpperCase(z):f.toLocaleLowerCase(z);for(var g=f.split(""),h=0;hMath.round(2*(ya/3))){var Ba=a.document.querySelector(".kioskboard-wrapper");Ba.style.maxHeight=Math.round(4*(ya/5))+"px",Ba.style.overflowX="hidden",Ba.style.overflowY="auto",Ba.classList.add("kioskboard-overflow")}var Ca=x===l.Top,Da=(Ca?f.getBoundingClientRect().top:f.getBoundingClientRect().bottom)||0,Ea=a.document.documentElement.scrollTop||0,Fa=Math.round(Da+Ea),Ga=Fa.kioskboard-body-padding {padding-"+(Ga?"top":"bottom")+":"+Aa+"px !important;}",Ja=a.document.createRange();Ja.selectNode(a.document.head);var Ka=Ja.createContextualFragment(Ia);a.document.head.appendChild(Ka),a.document.body.classList.add("kioskboard-body-padding")}var La=!0===A.autoScroll;if(La){var Ma=Ca?20:50,Na=f.getBoundingClientRect().top||0,Oa=Math.round(Na+Ea),Pa=!0===A.cssAnimations?"smooth":"auto",Qa=!0===A.cssAnimations&&"number"==typeof A.cssAnimationsDuration?A.cssAnimationsDuration:0,Ra=Oa-Ma-(Ca?Aa:0),Sa=a.navigator.userAgent.toLocaleLowerCase("en"),Ta=-1
', 38 | trigger: 'hover focus', 39 | title: '', 40 | delay: 0, 41 | html: false, 42 | container: false, 43 | viewport: { 44 | selector: 'body', 45 | padding: 0 46 | } 47 | } 48 | 49 | Tooltip.prototype.init = function (type, element, options) { 50 | this.enabled = true 51 | this.type = type 52 | this.$element = $(element) 53 | this.options = this.getOptions(options) 54 | this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) 55 | this.inState = { click: false, hover: false, focus: false } 56 | 57 | if (this.$element[0] instanceof document.constructor && !this.options.selector) { 58 | throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') 59 | } 60 | 61 | var triggers = this.options.trigger.split(' ') 62 | 63 | for (var i = triggers.length; i--;) { 64 | var trigger = triggers[i] 65 | 66 | if (trigger == 'click') { 67 | this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 68 | } else if (trigger != 'manual') { 69 | var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 70 | var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 71 | 72 | this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 73 | this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 74 | } 75 | } 76 | 77 | this.options.selector ? 78 | (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 79 | this.fixTitle() 80 | } 81 | 82 | Tooltip.prototype.getDefaults = function () { 83 | return Tooltip.DEFAULTS 84 | } 85 | 86 | Tooltip.prototype.getOptions = function (options) { 87 | options = $.extend({}, this.getDefaults(), this.$element.data(), options) 88 | 89 | if (options.delay && typeof options.delay == 'number') { 90 | options.delay = { 91 | show: options.delay, 92 | hide: options.delay 93 | } 94 | } 95 | 96 | return options 97 | } 98 | 99 | Tooltip.prototype.getDelegateOptions = function () { 100 | var options = {} 101 | var defaults = this.getDefaults() 102 | 103 | this._options && $.each(this._options, function (key, value) { 104 | if (defaults[key] != value) options[key] = value 105 | }) 106 | 107 | return options 108 | } 109 | 110 | Tooltip.prototype.enter = function (obj) { 111 | var self = obj instanceof this.constructor ? 112 | obj : $(obj.currentTarget).data('bs.' + this.type) 113 | 114 | if (!self) { 115 | self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 116 | $(obj.currentTarget).data('bs.' + this.type, self) 117 | } 118 | 119 | if (obj instanceof $.Event) { 120 | self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true 121 | } 122 | 123 | if (self.tip().hasClass('in') || self.hoverState == 'in') { 124 | self.hoverState = 'in' 125 | return 126 | } 127 | 128 | clearTimeout(self.timeout) 129 | 130 | self.hoverState = 'in' 131 | 132 | if (!self.options.delay || !self.options.delay.show) return self.show() 133 | 134 | self.timeout = setTimeout(function () { 135 | if (self.hoverState == 'in') self.show() 136 | }, self.options.delay.show) 137 | } 138 | 139 | Tooltip.prototype.isInStateTrue = function () { 140 | for (var key in this.inState) { 141 | if (this.inState[key]) return true 142 | } 143 | 144 | return false 145 | } 146 | 147 | Tooltip.prototype.leave = function (obj) { 148 | var self = obj instanceof this.constructor ? 149 | obj : $(obj.currentTarget).data('bs.' + this.type) 150 | 151 | if (!self) { 152 | self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 153 | $(obj.currentTarget).data('bs.' + this.type, self) 154 | } 155 | 156 | if (obj instanceof $.Event) { 157 | self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false 158 | } 159 | 160 | if (self.isInStateTrue()) return 161 | 162 | clearTimeout(self.timeout) 163 | 164 | self.hoverState = 'out' 165 | 166 | if (!self.options.delay || !self.options.delay.hide) return self.hide() 167 | 168 | self.timeout = setTimeout(function () { 169 | if (self.hoverState == 'out') self.hide() 170 | }, self.options.delay.hide) 171 | } 172 | 173 | Tooltip.prototype.show = function () { 174 | var e = $.Event('show.bs.' + this.type) 175 | 176 | if (this.hasContent() && this.enabled) { 177 | this.$element.trigger(e) 178 | 179 | var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) 180 | if (e.isDefaultPrevented() || !inDom) return 181 | var that = this 182 | 183 | var $tip = this.tip() 184 | 185 | var tipId = this.getUID(this.type) 186 | 187 | this.setContent() 188 | $tip.attr('id', tipId) 189 | this.$element.attr('aria-describedby', tipId) 190 | 191 | if (this.options.animation) $tip.addClass('fade') 192 | 193 | var placement = typeof this.options.placement == 'function' ? 194 | this.options.placement.call(this, $tip[0], this.$element[0]) : 195 | this.options.placement 196 | 197 | var autoToken = /\s?auto?\s?/i 198 | var autoPlace = autoToken.test(placement) 199 | if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 200 | 201 | $tip 202 | .detach() 203 | .css({ top: 0, left: 0, display: 'block' }) 204 | .addClass(placement) 205 | .data('bs.' + this.type, this) 206 | 207 | this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) 208 | this.$element.trigger('inserted.bs.' + this.type) 209 | 210 | var pos = this.getPosition() 211 | var actualWidth = $tip[0].offsetWidth 212 | var actualHeight = $tip[0].offsetHeight 213 | 214 | if (autoPlace) { 215 | var orgPlacement = placement 216 | var viewportDim = this.getPosition(this.$viewport) 217 | 218 | placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : 219 | placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : 220 | placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : 221 | placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : 222 | placement 223 | 224 | $tip 225 | .removeClass(orgPlacement) 226 | .addClass(placement) 227 | } 228 | 229 | var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 230 | 231 | this.applyPlacement(calculatedOffset, placement) 232 | 233 | var complete = function () { 234 | var prevHoverState = that.hoverState 235 | that.$element.trigger('shown.bs.' + that.type) 236 | that.hoverState = null 237 | 238 | if (prevHoverState == 'out') that.leave(that) 239 | } 240 | 241 | $.support.transition && this.$tip.hasClass('fade') ? 242 | $tip 243 | .one('bsTransitionEnd', complete) 244 | .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 245 | complete() 246 | } 247 | } 248 | 249 | Tooltip.prototype.applyPlacement = function (offset, placement) { 250 | var $tip = this.tip() 251 | var width = $tip[0].offsetWidth 252 | var height = $tip[0].offsetHeight 253 | 254 | // manually read margins because getBoundingClientRect includes difference 255 | var marginTop = parseInt($tip.css('margin-top'), 10) 256 | var marginLeft = parseInt($tip.css('margin-left'), 10) 257 | 258 | // we must check for NaN for ie 8/9 259 | if (isNaN(marginTop)) marginTop = 0 260 | if (isNaN(marginLeft)) marginLeft = 0 261 | 262 | offset.top += marginTop 263 | offset.left += marginLeft 264 | 265 | // $.fn.offset doesn't round pixel values 266 | // so we use setOffset directly with our own function B-0 267 | $.offset.setOffset($tip[0], $.extend({ 268 | using: function (props) { 269 | $tip.css({ 270 | top: Math.round(props.top), 271 | left: Math.round(props.left) 272 | }) 273 | } 274 | }, offset), 0) 275 | 276 | $tip.addClass('in') 277 | 278 | // check to see if placing tip in new offset caused the tip to resize itself 279 | var actualWidth = $tip[0].offsetWidth 280 | var actualHeight = $tip[0].offsetHeight 281 | 282 | if (placement == 'top' && actualHeight != height) { 283 | offset.top = offset.top + height - actualHeight 284 | } 285 | 286 | var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 287 | 288 | if (delta.left) offset.left += delta.left 289 | else offset.top += delta.top 290 | 291 | var isVertical = /top|bottom/.test(placement) 292 | var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 293 | var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' 294 | 295 | $tip.offset(offset) 296 | this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) 297 | } 298 | 299 | Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { 300 | this.arrow() 301 | .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') 302 | .css(isVertical ? 'top' : 'left', '') 303 | } 304 | 305 | Tooltip.prototype.setContent = function () { 306 | var $tip = this.tip() 307 | var title = this.getTitle() 308 | 309 | $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 310 | $tip.removeClass('fade in top bottom left right') 311 | } 312 | 313 | Tooltip.prototype.hide = function (callback) { 314 | var that = this 315 | var $tip = $(this.$tip) 316 | var e = $.Event('hide.bs.' + this.type) 317 | 318 | function complete() { 319 | if (that.hoverState != 'in') $tip.detach() 320 | if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. 321 | that.$element 322 | .removeAttr('aria-describedby') 323 | .trigger('hidden.bs.' + that.type) 324 | } 325 | callback && callback() 326 | } 327 | 328 | this.$element.trigger(e) 329 | 330 | if (e.isDefaultPrevented()) return 331 | 332 | $tip.removeClass('in') 333 | 334 | $.support.transition && $tip.hasClass('fade') ? 335 | $tip 336 | .one('bsTransitionEnd', complete) 337 | .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 338 | complete() 339 | 340 | this.hoverState = null 341 | 342 | return this 343 | } 344 | 345 | Tooltip.prototype.fixTitle = function () { 346 | var $e = this.$element 347 | if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { 348 | $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 349 | } 350 | } 351 | 352 | Tooltip.prototype.hasContent = function () { 353 | return this.getTitle() 354 | } 355 | 356 | Tooltip.prototype.getPosition = function ($element) { 357 | $element = $element || this.$element 358 | 359 | var el = $element[0] 360 | var isBody = el.tagName == 'BODY' 361 | 362 | var elRect = el.getBoundingClientRect() 363 | if (elRect.width == null) { 364 | // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 365 | elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) 366 | } 367 | var isSvg = window.SVGElement && el instanceof window.SVGElement 368 | // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. 369 | // See https://github.com/twbs/bootstrap/issues/20280 370 | var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) 371 | var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } 372 | var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null 373 | 374 | return $.extend({}, elRect, scroll, outerDims, elOffset) 375 | } 376 | 377 | Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 378 | return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 379 | placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 380 | placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 381 | /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 382 | 383 | } 384 | 385 | Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 386 | var delta = { top: 0, left: 0 } 387 | if (!this.$viewport) return delta 388 | 389 | var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 390 | var viewportDimensions = this.getPosition(this.$viewport) 391 | 392 | if (/right|left/.test(placement)) { 393 | var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 394 | var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 395 | if (topEdgeOffset < viewportDimensions.top) { // top overflow 396 | delta.top = viewportDimensions.top - topEdgeOffset 397 | } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 398 | delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset 399 | } 400 | } else { 401 | var leftEdgeOffset = pos.left - viewportPadding 402 | var rightEdgeOffset = pos.left + viewportPadding + actualWidth 403 | if (leftEdgeOffset < viewportDimensions.left) { // left overflow 404 | delta.left = viewportDimensions.left - leftEdgeOffset 405 | } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow 406 | delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 407 | } 408 | } 409 | 410 | return delta 411 | } 412 | 413 | Tooltip.prototype.getTitle = function () { 414 | var title 415 | var $e = this.$element 416 | var o = this.options 417 | 418 | title = $e.attr('data-original-title') 419 | || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 420 | 421 | return title 422 | } 423 | 424 | Tooltip.prototype.getUID = function (prefix) { 425 | do prefix += ~~(Math.random() * 1000000) 426 | while (document.getElementById(prefix)) 427 | return prefix 428 | } 429 | 430 | Tooltip.prototype.tip = function () { 431 | if (!this.$tip) { 432 | this.$tip = $(this.options.template) 433 | if (this.$tip.length != 1) { 434 | throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') 435 | } 436 | } 437 | return this.$tip 438 | } 439 | 440 | Tooltip.prototype.arrow = function () { 441 | return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) 442 | } 443 | 444 | Tooltip.prototype.enable = function () { 445 | this.enabled = true 446 | } 447 | 448 | Tooltip.prototype.disable = function () { 449 | this.enabled = false 450 | } 451 | 452 | Tooltip.prototype.toggleEnabled = function () { 453 | this.enabled = !this.enabled 454 | } 455 | 456 | Tooltip.prototype.toggle = function (e) { 457 | var self = this 458 | if (e) { 459 | self = $(e.currentTarget).data('bs.' + this.type) 460 | if (!self) { 461 | self = new this.constructor(e.currentTarget, this.getDelegateOptions()) 462 | $(e.currentTarget).data('bs.' + this.type, self) 463 | } 464 | } 465 | 466 | if (e) { 467 | self.inState.click = !self.inState.click 468 | if (self.isInStateTrue()) self.enter(self) 469 | else self.leave(self) 470 | } else { 471 | self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 472 | } 473 | } 474 | 475 | Tooltip.prototype.destroy = function () { 476 | var that = this 477 | clearTimeout(this.timeout) 478 | this.hide(function () { 479 | that.$element.off('.' + that.type).removeData('bs.' + that.type) 480 | if (that.$tip) { 481 | that.$tip.detach() 482 | } 483 | that.$tip = null 484 | that.$arrow = null 485 | that.$viewport = null 486 | that.$element = null 487 | }) 488 | } 489 | 490 | 491 | // TOOLTIP PLUGIN DEFINITION 492 | // ========================= 493 | 494 | function Plugin(option) { 495 | return this.each(function () { 496 | var $this = $(this) 497 | var data = $this.data('bs.tooltip') 498 | var options = typeof option == 'object' && option 499 | 500 | if (!data && /destroy|hide/.test(option)) return 501 | if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 502 | if (typeof option == 'string') data[option]() 503 | }) 504 | } 505 | 506 | var old = $.fn.tooltip 507 | 508 | $.fn.tooltip = Plugin 509 | $.fn.tooltip.Constructor = Tooltip 510 | 511 | 512 | // TOOLTIP NO CONFLICT 513 | // =================== 514 | 515 | $.fn.tooltip.noConflict = function () { 516 | $.fn.tooltip = old 517 | return this 518 | } 519 | 520 | }(jQuery); -------------------------------------------------------------------------------- /docs/index.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * KioskBoard - Virtual Keyboard ('https://github.com/furcan/KioskBoard') 3 | * Version: 2.3.0 4 | * Author: Furkan ('https://github.com/furcan') 5 | * Copyright 2022 KioskBoard - Virtual Keyboard, MIT Licence ('https://opensource.org/licenses/MIT')* 6 | */ 7 | 8 | /* Reset on */ 9 | *, 10 | *:focus { 11 | outline: none !important; 12 | } 13 | 14 | *, 15 | *::before, 16 | *::after { 17 | box-sizing: border-box; 18 | } 19 | 20 | body { 21 | float: left; 22 | width: 100%; 23 | min-height: 100vh; 24 | overflow-x: hidden !important; 25 | font-size: 15px; 26 | line-height: 18px; 27 | font-weight: 400; 28 | color: #2f2f2f; 29 | background: #f8f8f8; 30 | background: linear-gradient(to left top, #fff, #fbfbfb, #f7f7f7, #f4f4f4, #f0f0f0); 31 | } 32 | 33 | body, 34 | iframe, 35 | h1, 36 | h2, 37 | h3, 38 | h4, 39 | h5, 40 | h6, 41 | p, 42 | pre, 43 | a, 44 | strong, 45 | u, 46 | center, 47 | ol, 48 | ul, 49 | li, 50 | fieldset, 51 | form, 52 | label, 53 | table, 54 | tbody, 55 | tfoot, 56 | thead, 57 | tr, 58 | th, 59 | td, 60 | footer, 61 | header, 62 | menu, 63 | nav, 64 | button { 65 | text-decoration: none !important; 66 | margin: 0; 67 | padding: 0; 68 | border: 0; 69 | font-family: "Barlow", sans-serif; 70 | } 71 | 72 | input, 73 | textarea, 74 | select, 75 | option { 76 | font-family: "Barlow", sans-serif; 77 | } 78 | 79 | li { 80 | list-style: none !important; 81 | } 82 | 83 | a { 84 | color: inherit; 85 | transition: all 0.2s ease-in-out; 86 | cursor: pointer; 87 | } 88 | 89 | h1 { 90 | font-family: "Bungee", sans-serif; 91 | font-weight: 400; 92 | font-size: 24px; 93 | line-height: 28px; 94 | } 95 | 96 | h2 { 97 | font-family: "Bungee", sans-serif; 98 | font-weight: 400; 99 | font-size: 20px; 100 | line-height: 24px; 101 | } 102 | 103 | h3 { 104 | font-family: "Bungee", sans-serif; 105 | font-weight: 400; 106 | font-size: 18px; 107 | line-height: 22px; 108 | } 109 | 110 | h4, 111 | h5 { 112 | font-size: 16px; 113 | line-height: 20px; 114 | } 115 | 116 | img { 117 | font-size: 10px; 118 | vertical-align: middle; 119 | max-width: 100%; 120 | height: auto; 121 | } 122 | 123 | *::selection { 124 | background-color: #000000; 125 | color: #fff; 126 | } 127 | 128 | *::-moz-selection { 129 | background-color: #000000; 130 | color: #fff; 131 | } 132 | 133 | ::-webkit-scrollbar { 134 | height: 4px; 135 | width: 4px; 136 | } 137 | ::-webkit-scrollbar-track { 138 | background: #1e1e1e; 139 | } 140 | ::-webkit-scrollbar-thumb { 141 | background: #5decaa; 142 | cursor: pointer; 143 | } 144 | 145 | input[type="number"]::-webkit-inner-spin-button, 146 | input[type="number"]::-webkit-outer-spin-button { 147 | -webkit-appearance: none; 148 | margin: 0; 149 | } 150 | 151 | .cantselect { 152 | -webkit-user-select: none; 153 | -moz-user-select: none; 154 | -ms-user-select: none; 155 | user-select: none; 156 | } 157 | 158 | .max-width { 159 | display: block; 160 | margin: auto; 161 | max-width: 1240px; 162 | } 163 | /* Reset off */ 164 | 165 | /* Header on */ 166 | header#Header { 167 | box-shadow: 0 0 40px -10px rgba(0, 0, 0, 0.5); 168 | float: left; 169 | width: 100%; 170 | position: relative; 171 | z-index: 10; 172 | background: #3a3a3a; 173 | background: linear-gradient(to left top, #3a3a3a, #333333, #2c2c2c, #252525, #1e1e1e); 174 | padding: 20px 0; 175 | } 176 | 177 | header#Header a#Logo { 178 | float: left; 179 | margin: 8px 0 0 20px; 180 | width: 260px; 181 | height: 60px; 182 | } 183 | 184 | header#Header a#Logo span.title { 185 | color: #5decaa; 186 | font-family: "Bungee", sans-serif; 187 | font-size: 31px; 188 | line-height: 32px; 189 | font-weight: normal; 190 | text-align: center; 191 | float: left; 192 | width: 100%; 193 | } 194 | header#Header a#Logo span.title i { 195 | transform: scale(0.85); 196 | min-width: 25px; 197 | margin-left: 3px; 198 | color: #fff; 199 | } 200 | 201 | header#Header a#Logo span.desc { 202 | color: #f8f8f8; 203 | font-family: "Barlow", sans-serif; 204 | font-size: 20px; 205 | line-height: 25px; 206 | font-weight: 300; 207 | text-align: center; 208 | float: left; 209 | width: 100%; 210 | } 211 | 212 | header#Header .get-kioskboard { 213 | float: right; 214 | width: 200px; 215 | height: 70px; 216 | text-align: center; 217 | padding: 20px 10px 20px 15px; 218 | background: #5decaa; 219 | border-radius: 100px 0 0 100px; 220 | } 221 | 222 | header#Header .get-kioskboard a { 223 | font-size: 30px; 224 | line-height: 30px; 225 | display: inline-table; 226 | margin: 0 12px; 227 | color: #3a3a3a; 228 | } 229 | 230 | header#Header .get-kioskboard a.npm { 231 | transform: scale(1.5); 232 | } 233 | /* Header off */ 234 | 235 | /* Slider on */ 236 | section#Slider { 237 | float: left; 238 | position: relative; 239 | z-index: 9; 240 | background: #fff; 241 | overflow: hidden; 242 | width: 100%; 243 | } 244 | 245 | section#Slider .slider-content { 246 | position: relative; 247 | float: left; 248 | width: 100%; 249 | } 250 | 251 | section#Slider .slider-content.slider-image { 252 | padding: 70px 100px 0 40px; 253 | text-align: center; 254 | width: 55%; 255 | } 256 | 257 | section#Slider .slider-content.slider-image img.image { 258 | max-width: 460px; 259 | filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.05)); 260 | } 261 | 262 | section#Slider .slider-content.slider-info { 263 | text-align: center; 264 | padding: 75px 20px; 265 | background: #2f2f2f; 266 | color: #fff; 267 | float: left; 268 | width: 45%; 269 | } 270 | 271 | section#Slider .slider-content.slider-info:before { 272 | content: ""; 273 | z-index: -1; 274 | position: absolute; 275 | background: #2f2f2f; 276 | left: -40px; 277 | top: 0; 278 | width: 80px; 279 | height: 100%; 280 | transform: skewX(-8deg); 281 | } 282 | 283 | section#Slider .slider-content.slider-info .title { 284 | font-size: 50px; 285 | line-height: 50px; 286 | color: #5decaa; 287 | margin: 0 0 5px; 288 | } 289 | 290 | section#Slider .slider-content.slider-info .title i { 291 | transform: scale(0.85); 292 | margin-left: 5px; 293 | color: #fff; 294 | } 295 | 296 | section#Slider .slider-content.slider-info .sub-title { 297 | color: #f8f8f8; 298 | font-size: 34px; 299 | line-height: 34px; 300 | font-weight: 300; 301 | padding: 0 0 30px; 302 | border-bottom: 1px dashed rgba(255, 255, 255, 0.15); 303 | margin: 0 0 30px; 304 | } 305 | 306 | section#Slider .slider-content.slider-info .desc { 307 | font-size: 15px; 308 | line-height: 20px; 309 | margin: 0 0 30px; 310 | color: #d3d3d3; 311 | } 312 | 313 | section#Slider .slider-content.slider-info .version { 314 | font-size: 15px; 315 | line-height: 15px; 316 | display: table; 317 | margin: 0 auto 45px; 318 | background: #5decaa; 319 | color: #2f2f2f; 320 | padding: 10px 16px; 321 | border-radius: 20px; 322 | font-weight: 600; 323 | } 324 | 325 | section#Slider .slider-content.slider-info .version { 326 | animation: version-highlighter-animation 1.5s infinite cubic-bezier(0.25, 0.5, 0.1, 1); 327 | -webkit-animation: version-highlighter-animation 1.5s infinite cubic-bezier(0.25, 0.5, 0.1, 1); 328 | box-shadow: 0 0 0 0 rgba(93, 236, 170, 0.4); 329 | } 330 | 331 | @keyframes version-highlighter-animation { 332 | to { 333 | box-shadow: 0 0 0 10px rgba(93, 236, 170, 0); 334 | } 335 | } 336 | @-webkit-keyframes version-highlighter-animation { 337 | to { 338 | box-shadow: 0 0 0 10px rgba(93, 236, 170, 0); 339 | } 340 | } 341 | 342 | section#Slider .browser-compatibility { 343 | position: relative; 344 | display: table; 345 | margin: auto; 346 | } 347 | 348 | section#Slider .browser-compatibility h5.bc-title { 349 | font-family: "Barlow", sans-serif; 350 | position: absolute; 351 | width: 140px; 352 | height: 24px; 353 | font-size: 12px; 354 | line-height: 24px; 355 | font-weight: 300; 356 | border-radius: 100px; 357 | background: #4a4a4a; 358 | text-align: center; 359 | left: 0; 360 | right: 0; 361 | top: -12px; 362 | margin: auto; 363 | } 364 | 365 | section#Slider .browser-compatibility ul.bc-ul { 366 | border-radius: 100px; 367 | padding: 20px 20px 12px; 368 | display: table; 369 | margin: auto; 370 | background: #a6a6a6; 371 | } 372 | 373 | section#Slider .browser-compatibility ul.bc-ul li { 374 | float: left; 375 | width: 45px; 376 | } 377 | 378 | section#Slider .browser-compatibility ul.bc-ul li i { 379 | font-size: 18px; 380 | line-height: 18px; 381 | display: block; 382 | color: #4a4a4a; 383 | margin: 0 0 6px; 384 | width: 100%; 385 | text-align: center; 386 | } 387 | 388 | section#Slider .browser-compatibility ul.bc-ul li span { 389 | float: left; 390 | width: 100%; 391 | font-weight: 500; 392 | color: #4a4a4a; 393 | font-size: 10.5px; 394 | line-height: 11px; 395 | text-align: center; 396 | } 397 | /* Slider off */ 398 | 399 | /* Sections on */ 400 | section.sections { 401 | float: left; 402 | position: relative; 403 | background: #f0f0f0; 404 | background: linear-gradient(to bottom, #f0f0f0, #f4f4f4, #f7f7f7, #fbfbfb, #ffffff); 405 | z-index: 8; 406 | padding: 80px 60px; 407 | width: 100%; 408 | } 409 | 410 | section.sections .head { 411 | margin: 0 0 40px; 412 | float: left; 413 | width: 100%; 414 | } 415 | 416 | section.sections .head .sec-title { 417 | float: left; 418 | width: 100%; 419 | position: relative; 420 | font-size: 26px; 421 | line-height: 26px; 422 | padding: 0 0 0 12px; 423 | margin: 0 0 15px; 424 | } 425 | 426 | section.sections .head .sec-title.no-margin { 427 | margin: 0; 428 | } 429 | 430 | section.sections .head .sec-title::before { 431 | content: ""; 432 | position: absolute; 433 | height: 100%; 434 | left: 0; 435 | top: 0; 436 | border-left: 4px solid #5decaa; 437 | } 438 | 439 | section.sections .head .sec-desc { 440 | font-size: 15px; 441 | line-height: 25px; 442 | margin: 0 0 10px; 443 | float: left; 444 | width: 100%; 445 | } 446 | 447 | section.sections .head .sec-desc:nth-last-of-type(1) { 448 | margin: 0; 449 | } 450 | 451 | section.sections .head .sec-desc span.option { 452 | font-family: "Inconsolata", monospace; 453 | padding: 0 8px; 454 | display: inline-block; 455 | font-weight: 600; 456 | margin: 0 2px; 457 | line-height: 20px; 458 | border-radius: 20px; 459 | background: #5decaa; 460 | } 461 | section.sections .head .sec-desc span.option.num { 462 | background: #525252; 463 | color: #fff; 464 | } 465 | 466 | section.sections .section-content { 467 | float: left; 468 | width: 100%; 469 | } 470 | /* Sections off */ 471 | 472 | /* Sections: Keyboard Types and Themes on */ 473 | section#KeyboardTypes .keyboard-types .types { 474 | float: left; 475 | width: 29.3333%; 476 | margin: 0 2%; 477 | padding: 30px; 478 | text-align: center; 479 | background: #fff; 480 | box-shadow: 0 0 20px -8px rgba(0, 0, 0, 0.15); 481 | border-radius: 20px; 482 | } 483 | 484 | section#KeyboardThemes .keyboard-themes .themes { 485 | float: left; 486 | width: 17%; 487 | margin: 0 1.5%; 488 | padding: 30px; 489 | text-align: center; 490 | background: #e8e8e8; 491 | background: linear-gradient(to right bottom, #e8e8e8, #e5e5e5, #e2e2e2, #e0e0e0, #dddddd); 492 | box-shadow: 0 0 20px -8px rgba(0, 0, 0, 0.15); 493 | border-radius: 20px; 494 | } 495 | 496 | section#KeyboardThemes .keyboard-themes .themes .info, 497 | section#KeyboardTypes .keyboard-types .types .info { 498 | margin: 0 0 20px; 499 | float: left; 500 | width: 100%; 501 | } 502 | 503 | section#KeyboardThemes .keyboard-themes .themes .info span.key-preview { 504 | -webkit-user-select: none; 505 | -ms-user-select: none; 506 | -moz-user-select: none; 507 | user-select: none; 508 | position: relative; 509 | transition: all 0.2s ease-in-out; 510 | transform-origin: bottom center; 511 | cursor: pointer; 512 | line-height: 1; 513 | text-align: left; 514 | display: table; 515 | max-width: 120px; 516 | width: 70px; 517 | min-height: 62px; 518 | margin: 0 auto 20px; 519 | padding: 12px 12px 22px; 520 | border-radius: 8px; 521 | background: #fafafa; 522 | color: #707070; 523 | border: 2px solid rgba(255, 255, 255, 0.04); 524 | box-shadow: 0 4px 0 0.04px rgba(0, 0, 0, 0.12); 525 | border-bottom-color: rgba(255, 255, 255, 0.1); 526 | border-bottom-width: 4px; 527 | text-transform: uppercase; 528 | font-family: Barlow, sans-serif; 529 | font-weight: 600; 530 | font-size: 22px; 531 | } 532 | 533 | section#KeyboardThemes .keyboard-themes .themes .info span.key-preview:hover { 534 | transform: scaleY(0.98) translateY(1px); 535 | } 536 | 537 | section#KeyboardThemes .keyboard-themes .themes.theme-material .info span.key-preview, 538 | section#KeyboardThemes .keyboard-themes .themes.theme-light .info span.key-preview { 539 | color: #707070; 540 | background: #fafafa; 541 | } 542 | 543 | section#KeyboardThemes .keyboard-themes .themes.theme-dark .info span.key-preview { 544 | border-color: rgba(255, 255, 255, 0.02); 545 | border-bottom-color: rgba(255, 255, 255, 0.04); 546 | box-shadow: 0 5px 0 0.05px rgba(0, 0, 0, 0.6); 547 | color: #b7b7b7; 548 | background: #323232; 549 | } 550 | 551 | section#KeyboardThemes .keyboard-themes .themes.theme-flat .info span.key-preview { 552 | color: #707070; 553 | background: #fafafa; 554 | box-shadow: unset; 555 | border: 1px solid rgba(0, 0, 0, 0.05); 556 | } 557 | 558 | section#KeyboardThemes .keyboard-themes .themes.theme-oldschool .info span.key-preview { 559 | color: #8f8f8f; 560 | text-shadow: 0 0 1px rgba(0, 0, 0, 0.2); 561 | background: #fafafa; 562 | box-shadow: 0 4px 6px 0.06px rgba(0, 0, 0, 0.05); 563 | } 564 | section#KeyboardThemes .keyboard-themes .themes.theme-oldschool .info span.key-preview:after { 565 | content: ""; 566 | position: absolute; 567 | left: 0px; 568 | top: -5px; 569 | right: 0; 570 | bottom: 0; 571 | width: 100%; 572 | height: calc(100% - 5px); 573 | background: rgba(255, 255, 255, 0.1); 574 | box-shadow: 0 5px 15px -10px rgba(0, 0, 0, 0.4); 575 | margin: auto; 576 | border-radius: inherit; 577 | border: 4px solid rgba(0, 0, 0, 0.06); 578 | border-top-color: rgba(0, 0, 0, 0.02); 579 | border-bottom-color: transparent; 580 | box-sizing: border-box; 581 | border-top-width: 2px; 582 | border-bottom-width: 6px; 583 | } 584 | 585 | section#KeyboardTypes .keyboard-types .types .info img { 586 | display: table; 587 | width: 150px; 588 | height: 150px; 589 | box-shadow: 0 0 30px -12px rgba(0, 0, 0, 0.2); 590 | margin: 0 auto 25px; 591 | border-radius: 150px; 592 | } 593 | 594 | section#KeyboardTypes .keyboard-types .types .info h4 { 595 | font-size: 20px; 596 | line-height: 22px; 597 | margin: 0 0 10px; 598 | } 599 | 600 | section#KeyboardThemes .keyboard-themes .themes .info h4 { 601 | font-size: 20px; 602 | line-height: 22px; 603 | } 604 | 605 | section#KeyboardTypes .keyboard-types .types .info p { 606 | color: #868686; 607 | margin: 0 0 6px; 608 | font-size: 14px; 609 | line-height: 18px; 610 | } 611 | 612 | section#KeyboardTypes .keyboard-types .types .info p i { 613 | transform: scale(0.3); 614 | margin-right: 2px; 615 | } 616 | 617 | section#KeyboardThemes .keyboard-themes .themes .demo, 618 | section#KeyboardTypes .keyboard-types .types .demo { 619 | float: left; 620 | width: 100%; 621 | } 622 | 623 | section#KeyboardThemes .keyboard-themes .themes .demo input, 624 | section#KeyboardThemes .keyboard-themes .themes .demo textarea, 625 | section#KeyboardTypes .keyboard-types .types .demo input, 626 | section#KeyboardTypes .keyboard-types .types .demo textarea { 627 | transition: all 0.2s ease-in-out; 628 | float: left; 629 | width: 100%; 630 | resize: none; 631 | border: 1px dashed rgba(0, 0, 0, 0.15); 632 | padding: 10px; 633 | font-size: 13px; 634 | line-height: 16px; 635 | border-radius: 20px; 636 | box-shadow: 0 0 20px -8px rgba(0, 0, 0, 0.2); 637 | color: #2f2f2f; 638 | background: rgba(255, 255, 255, 0.5); 639 | } 640 | 641 | section#KeyboardThemes .keyboard-themes .themes .demo input:focus, 642 | section#KeyboardThemes .keyboard-themes .themes .demo textarea:focus { 643 | background: #fff; 644 | } 645 | 646 | section#KeyboardThemes .keyboard-themes .themes .demo input::-webkit-input-placeholder, 647 | section#KeyboardThemes .keyboard-themes .themes .demo textarea::-webkit-input-placeholder, 648 | section#KeyboardTypes .keyboard-types .types .demo input::-webkit-input-placeholder, 649 | section#KeyboardTypes .keyboard-types .types .demo textarea::-webkit-input-placeholder { 650 | transition: all 0.2s ease-in-out; 651 | color: #b8b8b8; 652 | } 653 | 654 | section#KeyboardThemes .keyboard-themes .themes .demo input::-moz-placeholder, 655 | section#KeyboardThemes .keyboard-themes .themes .demo textarea::-moz-placeholder, 656 | section#KeyboardTypes .keyboard-types .types .demo input::-moz-placeholder, 657 | section#KeyboardTypes .keyboard-types .types .demo textarea::-moz-placeholder { 658 | transition: all 0.2s ease-in-out; 659 | color: #b8b8b8; 660 | } 661 | /* Sections: Keyboard Types and Themes off */ 662 | 663 | /* Footer on */ 664 | footer#Footer { 665 | padding: 40px 20px; 666 | color: #5decaa; 667 | background: #2f2f2f; 668 | float: left; 669 | width: 100%; 670 | } 671 | 672 | footer#Footer p.copyright { 673 | float: left; 674 | font-size: 12px; 675 | line-height: 15px; 676 | font-weight: 400; 677 | } 678 | 679 | footer#Footer a.github { 680 | float: right; 681 | font-size: 15px; 682 | line-height: 18px; 683 | font-weight: 400; 684 | } 685 | 686 | footer#Footer a.github:hover { 687 | color: #fff; 688 | } 689 | 690 | footer#Footer a.github i { 691 | margin-right: 2px; 692 | } 693 | /* Footer off */ 694 | 695 | /* Code on */ 696 | .code-or { 697 | font-size: 20px; 698 | line-height: 25px; 699 | font-weight: 900; 700 | margin: 10px 0 35px; 701 | float: left; 702 | width: 100%; 703 | } 704 | 705 | .code-deprecated { 706 | opacity: 0.3; 707 | cursor: not-allowed; 708 | } 709 | 710 | code { 711 | text-align: left; 712 | font-family: "Inconsolata", monospace; 713 | position: relative; 714 | width: 100%; 715 | font-size: 13px; 716 | line-height: 16px; 717 | letter-spacing: 0.2px; 718 | word-break: break-all; 719 | word-break: break-word; 720 | display: inline-block; 721 | color: #7d7d7d; 722 | background: #1e1e1e; 723 | border-radius: 0 20px 20px 20px; 724 | margin: 25px 0; 725 | padding: 14px 18px; 726 | } 727 | 728 | code:nth-last-of-type(1) { 729 | margin-bottom: 0; 730 | } 731 | 732 | code.json, 733 | code.js { 734 | color: #f8f8f8; 735 | } 736 | 737 | code > span.label { 738 | position: absolute; 739 | text-align: center; 740 | background: #5decaa; 741 | color: #1e1e1e; 742 | left: 0; 743 | top: -25px; 744 | height: 25px; 745 | line-height: 25px; 746 | padding: 0 0 0 18px; 747 | font-size: 17px; 748 | font-weight: 600; 749 | border-radius: 10px 10px 0 0; 750 | } 751 | 752 | code > span.label > span.desc { 753 | float: right; 754 | height: 100%; 755 | font-weight: normal; 756 | margin-left: 15px; 757 | font-size: 12px; 758 | padding: 0 15px; 759 | color: #fff; 760 | background: #525252; 761 | border-radius: 0 10px 0 0; 762 | } 763 | 764 | code > span.l1 { 765 | margin: 4px 0 6px; 766 | float: left; 767 | width: 100%; 768 | } 769 | 770 | code > span.l2 { 771 | padding-left: 20px; 772 | } 773 | 774 | code > span.l3 { 775 | padding-left: 40px; 776 | } 777 | 778 | code.json > span.l1 { 779 | margin: 2px 0 2px; 780 | } 781 | 782 | code > span.break { 783 | min-height: 10px; 784 | } 785 | 786 | code span.data { 787 | color: #90d1ef !important; 788 | } 789 | 790 | code span.cmmnt { 791 | font-size: 12px; 792 | line-height: 14px; 793 | margin-top: 6px; 794 | margin-bottom: -1px; 795 | color: #55a64a; 796 | } 797 | 798 | code span.key, 799 | code span.fnc1 { 800 | color: #90d1ef; 801 | } 802 | 803 | code span.fnc2 { 804 | color: #e3e3b0; 805 | } 806 | 807 | code span.value, 808 | code span.str { 809 | color: #d69d85; 810 | } 811 | 812 | code span.cllbck, 813 | code span.link, 814 | code span.bool { 815 | color: #569cd6; 816 | } 817 | 818 | code span.int { 819 | color: #b5cea4; 820 | } 821 | 822 | code span.imp { 823 | color: #b77baf; 824 | } 825 | 826 | code span.the-button { 827 | cursor: pointer; 828 | } 829 | /* Code off */ 830 | 831 | /* Tooltip on */ 832 | .tooltip { 833 | font-family: "Inconsolata" !important; 834 | transition: opacity 0.3s ease-in-out; 835 | position: absolute; 836 | z-index: 800; 837 | border: none !important; 838 | display: block; 839 | font-size: 15px; 840 | line-height: 1.4; 841 | opacity: 0; 842 | filter: alpha(opacity=0); 843 | visibility: visible; 844 | } 845 | 846 | .tooltip.in { 847 | opacity: 1; 848 | filter: alpha(opacity=100); 849 | } 850 | 851 | .tooltip.top { 852 | padding: 5px 0; 853 | margin-top: -3px; 854 | } 855 | 856 | .tooltip.right { 857 | padding: 0 5px; 858 | margin-left: 3px; 859 | } 860 | 861 | .tooltip.bottom { 862 | padding: 5px 0; 863 | margin-top: 3px; 864 | } 865 | 866 | .tooltip.left { 867 | padding: 0 5px; 868 | margin-left: -3px; 869 | } 870 | 871 | .tooltip-inner { 872 | line-height: 1.3; 873 | max-width: 360px; 874 | min-width: 80px; 875 | padding: 12px 16px; 876 | color: #fff; 877 | text-align: center; 878 | text-decoration: none; 879 | background-color: #000000; 880 | -webkit-border-radius: 20px; 881 | -moz-border-radius: 20px; 882 | border-radius: 20px; 883 | } 884 | 885 | .tooltip-arrow { 886 | position: absolute; 887 | width: 0; 888 | height: 0; 889 | border-color: transparent; 890 | border-style: solid; 891 | } 892 | 893 | .tooltip.top .tooltip-arrow { 894 | bottom: 0; 895 | left: 50%; 896 | margin-left: -5px; 897 | border-top-color: #000000; 898 | border-width: 5px 5px 0; 899 | } 900 | 901 | .tooltip.right .tooltip-arrow { 902 | top: 50%; 903 | left: 0; 904 | margin-top: -5px; 905 | border-right-color: #000000; 906 | border-width: 5px 5px 5px 0; 907 | } 908 | 909 | .tooltip.left .tooltip-arrow { 910 | top: 50%; 911 | right: 0; 912 | margin-top: -5px; 913 | border-left-color: #000000; 914 | border-width: 5px 0 5px 5px; 915 | } 916 | 917 | .tooltip.bottom .tooltip-arrow { 918 | top: 0; 919 | left: 50%; 920 | margin-left: -5px; 921 | border-bottom-color: #000000; 922 | border-width: 0 5px 5px; 923 | } 924 | /* Tooltip off */ 925 | 926 | /* Responsive on */ 927 | @media only screen and (max-width: 1023px) { 928 | body { 929 | background: #fff; 930 | } 931 | 932 | header#Header { 933 | border-radius: 0 0 40px 40px; 934 | } 935 | 936 | header#Header a#Logo { 937 | display: table; 938 | float: unset; 939 | margin: 20px auto 40px; 940 | } 941 | 942 | header#Header .get-kioskboard { 943 | border-radius: 100px; 944 | display: table; 945 | float: unset; 946 | margin: 0 auto 10px; 947 | } 948 | 949 | section#Slider { 950 | background: transparent; 951 | } 952 | 953 | section#Slider .slider-content.slider-image { 954 | float: left; 955 | width: 100%; 956 | padding: 40px 20px; 957 | } 958 | 959 | section#Slider .slider-content.slider-image img.image { 960 | max-width: 100%; 961 | } 962 | 963 | section#Slider .slider-content.slider-info { 964 | float: left; 965 | width: 100%; 966 | border-radius: 40px 40px 0 0; 967 | padding: 30px 20px 40px; 968 | } 969 | 970 | section#Slider .slider-content.slider-info:before { 971 | display: none; 972 | } 973 | 974 | section#Slider .slider-content.slider-info .title, 975 | section#Slider .slider-content.slider-info .sub-title { 976 | display: none; 977 | } 978 | 979 | section.sections { 980 | padding: 50px 30px; 981 | } 982 | 983 | section.sections .head .sec-desc { 984 | font-size: 14px; 985 | } 986 | 987 | section#KeyboardThemes .keyboard-themes .themes, 988 | section#KeyboardTypes .keyboard-types .types { 989 | width: 96%; 990 | margin: 0 2% 40px; 991 | } 992 | section#KeyboardThemes .keyboard-themes .themes:nth-last-of-type(1), 993 | section#KeyboardTypes .keyboard-types .types:nth-last-of-type(1) { 994 | margin-bottom: 0; 995 | } 996 | 997 | footer#Footer p.copyright { 998 | text-align: center; 999 | width: 100%; 1000 | margin: 0 0 30px; 1001 | } 1002 | 1003 | footer#Footer a.github { 1004 | float: unset; 1005 | display: table; 1006 | margin: auto; 1007 | } 1008 | } 1009 | 1010 | @media only screen and (max-width: 359px) { 1011 | body { 1012 | min-width: 360px !important; 1013 | } 1014 | } 1015 | 1016 | @media only screen and (min-width: 2048px) { 1017 | html { 1018 | background: #000; 1019 | } 1020 | 1021 | body { 1022 | max-width: 2048px; 1023 | margin: auto; 1024 | display: flex; 1025 | flex-direction: column; 1026 | float: unset; 1027 | } 1028 | } 1029 | /* Responsive off */ 1030 | 1031 | /* Furcan on */ 1032 | section#FurcanTop, 1033 | section#FurcanBottom { 1034 | width: 100%; 1035 | } 1036 | 1037 | input.furcan { 1038 | width: 100%; 1039 | font-weight: 600; 1040 | border: none; 1041 | padding: 0 20px; 1042 | border-radius: 0; 1043 | background: #5decaa; 1044 | color: #1e1e1e; 1045 | } 1046 | 1047 | input.furcan-top { 1048 | height: 60px; 1049 | font-size: 1rem; 1050 | text-align: center; 1051 | } 1052 | 1053 | input.furcan-bottom { 1054 | height: 90px; 1055 | font-size: 1.25rem; 1056 | } 1057 | 1058 | input.furcan::placeholder { 1059 | font-weight: 500; 1060 | color: rgba(0, 0, 0, 0.25); 1061 | } 1062 | 1063 | input.furcan:-ms-input-placeholder { 1064 | font-weight: 500; 1065 | color: rgba(0, 0, 0, 0.25); 1066 | } 1067 | 1068 | input.furcan::-ms-input-placeholder { 1069 | font-weight: 500; 1070 | color: rgba(0, 0, 0, 0.25); 1071 | } 1072 | /* Furcan off */ 1073 | -------------------------------------------------------------------------------- /src/kioskboard.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * KioskBoard - Virtual Keyboard ('https://github.com/furcan/KioskBoard') 3 | * Version: 2.3.0 4 | * Author: Furkan ('https://github.com/furcan') 5 | * Copyright 2022 KioskBoard - Virtual Keyboard, MIT Licence ('https://opensource.org/licenses/MIT')* 6 | */ 7 | 8 | /* KioskBoard: Main: begin */ 9 | #KioskBoard-VirtualKeyboard { 10 | box-sizing: border-box !important; 11 | position: fixed; 12 | z-index: 2000; 13 | width: 100%; 14 | max-width: 1440px; 15 | background: #e3e3e3; 16 | background: linear-gradient(to right bottom, #eee, #ebebeb, #e8e8e8, #e6e6e6, #e3e3e3); 17 | -webkit-box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.25), 0 0 20px -8px rgba(0, 0, 0, 0.15); 18 | box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.25), 0 0 20px -8px rgba(0, 0, 0, 0.15); 19 | padding: 25px 20px 20px; 20 | left: 0; 21 | right: 0; 22 | margin: auto; 23 | } 24 | 25 | #KioskBoard-VirtualKeyboard.kioskboard-placement-bottom { 26 | top: unset; 27 | bottom: 0; 28 | border-radius: 10px 10px 0 0; 29 | } 30 | 31 | #KioskBoard-VirtualKeyboard.kioskboard-placement-top { 32 | top: 0; 33 | bottom: unset; 34 | border-radius: 0 0 10px 10px; 35 | } 36 | 37 | #KioskBoard-VirtualKeyboard * { 38 | box-sizing: border-box !important; 39 | } 40 | 41 | /* KioskBoard: Main: end */ 42 | 43 | /* KioskBoard: Wrapper: begin */ 44 | #KioskBoard-VirtualKeyboard .kioskboard-wrapper { 45 | position: relative; 46 | background: inherit; 47 | width: 100%; 48 | display: -webkit-box; 49 | display: -webkit-flex; 50 | display: -ms-flexbox; 51 | display: flex; 52 | -webkit-flex-wrap: wrap; 53 | -ms-flex-wrap: wrap; 54 | flex-wrap: wrap; 55 | -webkit-box-orient: horizontal; 56 | -webkit-box-direction: normal; 57 | -webkit-flex-direction: row; 58 | -ms-flex-direction: row; 59 | flex-direction: row; 60 | } 61 | 62 | #KioskBoard-VirtualKeyboard .kioskboard-wrapper.kioskboard-overflow { 63 | padding-right: 12px !important; 64 | overflow: hidden auto; 65 | } 66 | 67 | #KioskBoard-VirtualKeyboard .kioskboard-wrapper.kioskboard-overflow::-webkit-scrollbar { 68 | height: 6px; 69 | width: 6px; 70 | } 71 | 72 | #KioskBoard-VirtualKeyboard .kioskboard-wrapper.kioskboard-overflow::-webkit-scrollbar-track { 73 | border-radius: 3px; 74 | background: rgba(255, 255, 255, 0.75); 75 | } 76 | 77 | #KioskBoard-VirtualKeyboard .kioskboard-wrapper.kioskboard-overflow::-webkit-scrollbar-thumb { 78 | border-radius: 3px; 79 | background: rgba(0, 0, 0, 0.25); 80 | cursor: pointer; 81 | } 82 | 83 | /* KioskBoard: Wrapper: end */ 84 | 85 | /* KioskBoard: Row: begin */ 86 | #KioskBoard-VirtualKeyboard .kioskboard-row { 87 | position: relative; 88 | width: 100%; 89 | display: -webkit-box; 90 | display: -webkit-flex; 91 | display: -ms-flexbox; 92 | display: flex; 93 | -webkit-flex-wrap: wrap; 94 | -ms-flex-wrap: wrap; 95 | flex-wrap: wrap; 96 | -webkit-box-orient: horizontal; 97 | -webkit-box-direction: normal; 98 | -webkit-flex-direction: row; 99 | -ms-flex-direction: row; 100 | flex-direction: row; 101 | -webkit-box-align: center; 102 | -webkit-align-items: center; 103 | -ms-flex-align: center; 104 | align-items: center; 105 | -webkit-box-pack: center; 106 | -webkit-justify-content: center; 107 | -ms-flex-pack: center; 108 | justify-content: center; 109 | text-align: center; 110 | } 111 | 112 | /* KioskBoard: Row: end */ 113 | 114 | /* KioskBoard: Keys: begin */ 115 | #KioskBoard-VirtualKeyboard .kioskboard-row span[class^="kioskboard-key"] { 116 | -webkit-user-select: none; 117 | -ms-user-select: none; 118 | -moz-user-select: none; 119 | user-select: none; 120 | position: relative; 121 | -webkit-transition: all 0.2s ease-in-out; 122 | -o-transition: all 0.2s ease-in-out; 123 | transition: all 0.2s ease-in-out; 124 | -webkit-transform-origin: bottom center; 125 | transform-origin: bottom center; 126 | cursor: pointer; 127 | font-size: 22px; 128 | line-height: 1; 129 | font-weight: normal; 130 | font-family: sans-serif; 131 | max-width: 6.25%; 132 | margin: 8px 8px 12px; 133 | padding: 12px 12px 22px; 134 | border-radius: 8px; 135 | background: #fafafa; 136 | color: #707070; 137 | border: 2px solid rgba(255, 255, 255, 0.04); 138 | -webkit-box-shadow: 0 4px 0 0.04px rgba(0, 0, 0, 0.1); 139 | box-shadow: 0 4px 0 0.04px rgba(0, 0, 0, 0.1); 140 | border-bottom-color: rgba(255, 255, 255, 0.1); 141 | border-bottom-width: 4px; 142 | -webkit-box-flex: 1; 143 | -webkit-flex: 1 1 100%; 144 | -ms-flex: 1 1 100%; 145 | flex: 1 1 100%; 146 | display: -webkit-inline-box; 147 | display: -webkit-inline-flex; 148 | display: -ms-inline-flexbox; 149 | display: inline-flex; 150 | -webkit-flex-wrap: wrap; 151 | -ms-flex-wrap: wrap; 152 | flex-wrap: wrap; 153 | -webkit-box-orient: vertical; 154 | -webkit-box-direction: normal; 155 | -webkit-flex-direction: column; 156 | -ms-flex-direction: column; 157 | flex-direction: column; 158 | -webkit-box-align: start; 159 | -webkit-align-items: flex-start; 160 | -ms-flex-align: start; 161 | align-items: flex-start; 162 | -webkit-box-pack: start; 163 | -webkit-justify-content: flex-start; 164 | -ms-flex-pack: start; 165 | justify-content: flex-start; 166 | text-align: left; 167 | } 168 | 169 | #KioskBoard-VirtualKeyboard.kioskboard-tolowercase .kioskboard-row-dynamic span[class^="kioskboard-key"] { 170 | text-transform: lowercase; 171 | } 172 | 173 | #KioskBoard-VirtualKeyboard.kioskboard-touppercase .kioskboard-row-dynamic span[class^="kioskboard-key"] { 174 | text-transform: uppercase; 175 | } 176 | 177 | #KioskBoard-VirtualKeyboard .kioskboard-row span[class^="kioskboard-key"]:not(.spacebar-denied):hover { 178 | -webkit-transform: scaleY(0.98) translateY(1px); 179 | transform: scaleY(0.98) translateY(1px); 180 | } 181 | 182 | #KioskBoard-VirtualKeyboard .kioskboard-row span[class^="kioskboard-key"]:not(.spacebar-denied):active { 183 | -webkit-transform: scaleY(0.95) translateY(4px); 184 | transform: scaleY(0.95) translateY(4px); 185 | } 186 | 187 | #KioskBoard-VirtualKeyboard .kioskboard-row span[class^="kioskboard-key"] svg { 188 | position: absolute; 189 | z-index: 10; 190 | left: 10px; 191 | top: 10px; 192 | } 193 | 194 | /* KioskBoard: Keys: end */ 195 | 196 | /* KioskBoard: Row & Keys Top Group: begin */ 197 | #KioskBoard-VirtualKeyboard .kioskboard-row-top { 198 | padding: 0 0 10px; 199 | border-bottom: 1px solid rgba(0, 0, 0, 0.06); 200 | margin: 0 0 10px; 201 | } 202 | 203 | /* KioskBoard: Row & Keys Top Group: end */ 204 | 205 | /* KioskBoard: Row & Keys Bottom Group: begin */ 206 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom { 207 | padding: 10px 0 0; 208 | border-top: 1px solid rgba(0, 0, 0, 0.06); 209 | margin: 10px 0 0; 210 | } 211 | 212 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-capslock { 213 | max-width: 100%; 214 | min-height: 60px; 215 | width: 140px; 216 | -webkit-box-flex: 1; 217 | -webkit-flex: 1 1 auto; 218 | -ms-flex: 1 1 auto; 219 | flex: 1 1 auto; 220 | } 221 | 222 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-capslock::before { 223 | content: ""; 224 | position: absolute; 225 | z-index: 2; 226 | width: 10px; 227 | height: 10px; 228 | border-radius: 10px; 229 | right: 6px; 230 | top: 6px; 231 | background: #c4c4c4; 232 | } 233 | 234 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-capslock.capslock-active::before { 235 | background: #5decaa; 236 | } 237 | 238 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-enter, 239 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-backspace { 240 | position: relative; 241 | max-width: 100%; 242 | min-height: 60px; 243 | width: 140px; 244 | -webkit-box-flex: 1; 245 | -webkit-flex: 1 1 auto; 246 | -ms-flex: 1 1 auto; 247 | flex: 1 1 auto; 248 | } 249 | 250 | /* 140+16=>CapsLock && 140+16=>BackSpace && 140+16=>Enter */ 251 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-space { 252 | min-height: 60px; 253 | max-width: 100%; 254 | width: calc(100% - 16px - 140px - 16px - 140px - 16px - 140px - 16px); 255 | -webkit-box-flex: 1; 256 | -webkit-flex: 1 1 auto; 257 | -ms-flex: 1 1 auto; 258 | flex: 1 1 auto; 259 | } 260 | 261 | /* 140+16=>CapsLock && 140+16=>BackSpace && 140+16=>SpecialChar && 140+16=>Enter */ 262 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom.kioskboard-with-specialcharacter span.kioskboard-key-space { 263 | width: calc(100% - 16px - 140px - 16px - 140px - 16px - 140px - 16px - 140px - 16px); 264 | } 265 | 266 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-space.spacebar-denied { 267 | opacity: 0.4 !important; 268 | cursor: not-allowed !important; 269 | } 270 | 271 | #KioskBoard-VirtualKeyboard .kioskboard-with-specialcharacter span.kioskboard-key-specialcharacter { 272 | position: relative; 273 | max-width: 100%; 274 | min-height: 60px; 275 | width: 140px; 276 | -webkit-box-flex: 1; 277 | -webkit-flex: 1 1 auto; 278 | -ms-flex: 1 1 auto; 279 | flex: 1 1 auto; 280 | } 281 | 282 | /* KioskBoard: Row & Keys Bottom Group: end */ 283 | 284 | /* KioskBoard: Row & Keys Numpad Group: begin */ 285 | #KioskBoard-VirtualKeyboard .kioskboard-row-numpad { 286 | display: flex; 287 | max-width: 320px; 288 | margin: auto; 289 | } 290 | 291 | /* stylelint-disable no-descending-specificity */ 292 | #KioskBoard-VirtualKeyboard .kioskboard-row-numpad span[class^="kioskboard-key"] { 293 | max-width: 100%; 294 | min-height: 60px; 295 | width: calc(33.3333% - 16px); 296 | -webkit-box-flex: 1; 297 | -webkit-flex: 1 1 auto; 298 | -ms-flex: 1 1 auto; 299 | flex: 1 1 auto; 300 | } 301 | /* stylelint-enable no-descending-specificity */ 302 | 303 | #KioskBoard-VirtualKeyboard .kioskboard-row-numpad span.kioskboard-key-last { 304 | order: 11; 305 | } 306 | 307 | #KioskBoard-VirtualKeyboard .kioskboard-row-numpad span.kioskboard-key-backspace { 308 | order: 10; 309 | } 310 | 311 | #KioskBoard-VirtualKeyboard .kioskboard-row-numpad span.kioskboard-key-enter { 312 | order: 12; 313 | } 314 | 315 | /* KioskBoard: Row & Keys Numpad Group: end */ 316 | 317 | /* KioskBoard: Row & Keys SpecialChar Group: begin */ 318 | #KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters { 319 | -webkit-transition: all 0.2s ease-in-out; 320 | -o-transition: all 0.2s ease-in-out; 321 | transition: all 0.2s ease-in-out; 322 | visibility: hidden; 323 | opacity: 0; 324 | position: absolute; 325 | background: inherit; 326 | padding: 20px; 327 | z-index: 20; 328 | left: 0; 329 | top: 0; 330 | height: 100%; 331 | width: 100%; 332 | } 333 | 334 | #KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters.kioskboard-specialcharacter-show { 335 | visibility: visible; 336 | opacity: 1; 337 | } 338 | 339 | #KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-specialcharacter-close { 340 | -webkit-transition: all 0.36s ease-in-out; 341 | -o-transition: all 0.36s ease-in-out; 342 | transition: all 0.36s ease-in-out; 343 | cursor: pointer; 344 | position: absolute; 345 | z-index: 30; 346 | right: 0; 347 | top: 0; 348 | width: 40px; 349 | height: 40px; 350 | background: #a9a9a9; 351 | border-radius: 20px; 352 | -webkit-box-shadow: 0 0 16px -6px rgba(0, 0, 0, 0.25); 353 | box-shadow: 0 0 16px -6px rgba(0, 0, 0, 0.25); 354 | } 355 | 356 | #KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-specialcharacter-close svg { 357 | position: absolute; 358 | left: 0; 359 | top: 0; 360 | right: 0; 361 | bottom: 0; 362 | margin: auto; 363 | fill: #fff !important; 364 | width: 16px !important; 365 | height: 16px !important; 366 | } 367 | 368 | #KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-specialcharacter-close:hover { 369 | -webkit-transform: rotate(90deg); 370 | transform: rotate(90deg); 371 | } 372 | 373 | #KioskBoard-VirtualKeyboard .kioskboard-specialcharacters-content { 374 | width: 100%; 375 | max-height: 100%; 376 | padding-right: 5px; 377 | overflow-x: hidden; 378 | overflow-y: auto; 379 | } 380 | 381 | #KioskBoard-VirtualKeyboard .kioskboard-specialcharacters-content::-webkit-scrollbar { 382 | height: 6px; 383 | width: 6px; 384 | } 385 | 386 | #KioskBoard-VirtualKeyboard .kioskboard-specialcharacters-content::-webkit-scrollbar-track { 387 | border-radius: 3px; 388 | background: rgba(255, 255, 255, 0.75); 389 | } 390 | 391 | #KioskBoard-VirtualKeyboard .kioskboard-specialcharacters-content::-webkit-scrollbar-thumb { 392 | border-radius: 3px; 393 | background: rgba(0, 0, 0, 0.25); 394 | cursor: pointer; 395 | } 396 | 397 | #KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-key { 398 | min-width: 60px; 399 | min-height: 30px; 400 | } 401 | 402 | /* KioskBoard: Row & Keys SpecialChar Group: end */ 403 | 404 | /* KioskBoard: Theme: begin */ 405 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material, 406 | #KioskBoard-VirtualKeyboard.kioskboard-theme-light { 407 | -webkit-box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.25), 0 0 20px -8px rgba(0, 0, 0, 0.15); 408 | box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.25), 0 0 20px -8px rgba(0, 0, 0, 0.15); 409 | background: #e3e3e3; 410 | background: linear-gradient(to right bottom, #eee, #ebebeb, #e8e8e8, #e6e6e6, #e3e3e3); 411 | } 412 | 413 | #KioskBoard-VirtualKeyboard.kioskboard-theme-dark { 414 | -webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.25), 0 0 20px -8px rgba(0, 0, 0, 0.15); 415 | box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.25), 0 0 20px -8px rgba(0, 0, 0, 0.15); 416 | background: #151515; 417 | background: linear-gradient(to left top, #151515, #171717, #1a1a1a, #1c1c1c, #1e1e1e); 418 | } 419 | 420 | #KioskBoard-VirtualKeyboard.kioskboard-theme-flat { 421 | -webkit-box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.25), 0 0 20px -8px rgba(0, 0, 0, 0.15); 422 | box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.25), 0 0 20px -8px rgba(0, 0, 0, 0.15); 423 | background: #dfdfdf; 424 | } 425 | 426 | #KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool { 427 | -webkit-box-shadow: inset 4px 4px 4px rgba(0, 0, 0, 0.02), 0 0 20px -8px rgba(0, 0, 0, 0.1); 428 | box-shadow: inset 4px 4px 4px rgba(0, 0, 0, 0.02), 0 0 20px -8px rgba(0, 0, 0, 0.1); 429 | background: #e5e5e5; 430 | background: linear-gradient(to right bottom, #e5e5e5, #e6e6e6, #e7e7e7, #e7e7e7, #e8e8e8); 431 | } 432 | 433 | /* stylelint-disable no-descending-specificity */ 434 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row span[class^="kioskboard-key"], 435 | #KioskBoard-VirtualKeyboard.kioskboard-theme-light .kioskboard-row span[class^="kioskboard-key"] { 436 | color: #707070; 437 | background: #fafafa; 438 | } 439 | 440 | #KioskBoard-VirtualKeyboard.kioskboard-theme-dark .kioskboard-row span[class^="kioskboard-key"] { 441 | border-color: rgba(255, 255, 255, 0.02); 442 | border-bottom-color: rgba(255, 255, 255, 0.04); 443 | -webkit-box-shadow: 0 5px 0 0.05px rgba(255, 255, 255, 0.2); 444 | box-shadow: 0 5px 0 0.05px rgba(255, 255, 255, 0.2); 445 | color: #b7b7b7; 446 | background: #323232; 447 | } 448 | 449 | #KioskBoard-VirtualKeyboard.kioskboard-theme-flat .kioskboard-row span[class^="kioskboard-key"] { 450 | color: #707070; 451 | background: #fafafa; 452 | border-color: #fafafa; 453 | border-bottom-color: #fafafa; 454 | -webkit-box-shadow: 0 2px 0 0.05px #fafafa; 455 | box-shadow: 0 2px 0 0.05px #fafafa; 456 | } 457 | 458 | #KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool .kioskboard-row span[class^="kioskboard-key"] { 459 | color: #8f8f8f; 460 | text-shadow: 0 0 1px rgba(0, 0, 0, 0.2); 461 | background: #fafafa; 462 | -webkit-box-shadow: 0 4px 6px 0.06px rgba(0, 0, 0, 0.05); 463 | box-shadow: 0 4px 6px 0.06px rgba(0, 0, 0, 0.05); 464 | } 465 | /* stylelint-enable no-descending-specificity */ 466 | 467 | #KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool .kioskboard-row span[class^="kioskboard-key"]::after { 468 | content: ""; 469 | position: absolute; 470 | left: 0; 471 | top: -5px; 472 | right: 0; 473 | bottom: 0; 474 | width: 100%; 475 | height: calc(100% - 5px); 476 | background: rgba(255, 255, 255, 0.1); 477 | -webkit-box-shadow: 0 5px 15px -10px rgba(0, 0, 0, 0.4); 478 | box-shadow: 0 5px 15px -10px rgba(0, 0, 0, 0.4); 479 | margin: auto; 480 | border-radius: inherit; 481 | border: 4px solid rgba(0, 0, 0, 0.06); 482 | border-top-color: rgba(0, 0, 0, 0.02); 483 | border-bottom-color: transparent; 484 | box-sizing: border-box; 485 | border-top-width: 2px; 486 | border-bottom-width: 6px; 487 | } 488 | 489 | #KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool span.kioskboard-key-capslock::before { 490 | right: 9px; 491 | top: 9px; 492 | } 493 | 494 | #KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool span.kioskboard-key-capslock::before, 495 | #KioskBoard-VirtualKeyboard.kioskboard-theme-flat span.kioskboard-key-capslock::before, 496 | #KioskBoard-VirtualKeyboard.kioskboard-theme-light span.kioskboard-key-capslock::before { 497 | background: #c4c4c4; 498 | } 499 | 500 | #KioskBoard-VirtualKeyboard.kioskboard-theme-dark span.kioskboard-key-capslock::before { 501 | background: #a9a9a9; 502 | } 503 | 504 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material span.kioskboard-key-capslock::before { 505 | background: #e6e6e6; 506 | } 507 | 508 | #KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool span.kioskboard-key-capslock.capslock-active::before, 509 | #KioskBoard-VirtualKeyboard.kioskboard-theme-flat span.kioskboard-key-capslock.capslock-active::before, 510 | #KioskBoard-VirtualKeyboard.kioskboard-theme-light span.kioskboard-key-capslock.capslock-active::before, 511 | #KioskBoard-VirtualKeyboard.kioskboard-theme-dark span.kioskboard-key-capslock.capslock-active::before, 512 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material span.kioskboard-key-capslock.capslock-active::before { 513 | background: #5decaa; 514 | } 515 | 516 | #KioskBoard-VirtualKeyboard.kioskboard-theme-flat .kioskboard-row span[class^="kioskboard-key"] svg, 517 | #KioskBoard-VirtualKeyboard.kioskboard-theme-light .kioskboard-row span[class^="kioskboard-key"] svg { 518 | fill: #707070 !important; 519 | } 520 | 521 | #KioskBoard-VirtualKeyboard.kioskboard-theme-dark .kioskboard-row span[class^="kioskboard-key"] svg { 522 | fill: #a9a9a9 !important; 523 | } 524 | 525 | #KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool .kioskboard-row span[class^="kioskboard-key"] svg { 526 | left: 12px; 527 | fill: #a1a1a1 !important; 528 | } 529 | 530 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row span[class^="kioskboard-key"] svg { 531 | fill: #fafafa !important; 532 | } 533 | 534 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row-numpad span.kioskboard-key-backspace, 535 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row-bottom span.kioskboard-key-specialcharacter, 536 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row-bottom span.kioskboard-key-capslock, 537 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material .kioskboard-row-bottom span.kioskboard-key-backspace { 538 | -webkit-box-shadow: 0 4px 0 0.04px rgba(0, 0, 0, 0.3); 539 | box-shadow: 0 4px 0 0.04px rgba(0, 0, 0, 0.3); 540 | border-bottom-color: rgba(0, 0, 0, 0.03); 541 | color: #fafafa; 542 | background: #b0b0b0; 543 | } 544 | 545 | /* stylelint-disable no-descending-specificity */ 546 | #KioskBoard-VirtualKeyboard.kioskboard-theme-flat span.kioskboard-specialcharacter-close, 547 | #KioskBoard-VirtualKeyboard.kioskboard-theme-material span.kioskboard-specialcharacter-close, 548 | #KioskBoard-VirtualKeyboard.kioskboard-theme-light span.kioskboard-specialcharacter-close, 549 | #KioskBoard-VirtualKeyboard.kioskboard-theme-oldschool span.kioskboard-specialcharacter-close { 550 | background: #a9a9a9; 551 | } 552 | 553 | #KioskBoard-VirtualKeyboard.kioskboard-theme-dark span.kioskboard-specialcharacter-close { 554 | background: #323232; 555 | } 556 | 557 | #KioskBoard-VirtualKeyboard.kioskboard-theme-dark span.kioskboard-specialcharacter-close svg { 558 | fill: #b7b7b7 !important; 559 | } 560 | /* stylelint-enable no-descending-specificity */ 561 | 562 | /* KioskBoard: Theme: end */ 563 | 564 | /* KioskBoard: Responsive: begin */ 565 | @media only screen and (max-width: 767px) { 566 | #KioskBoard-VirtualKeyboard { 567 | min-height: 210px; 568 | padding: 12px 6px; 569 | } 570 | 571 | #KioskBoard-VirtualKeyboard .kioskboard-row span[class^="kioskboard-key"] { 572 | font-size: 13px !important; 573 | margin: 2px 2px 12px; 574 | padding: 8px 0; 575 | width: auto; 576 | min-width: 22.5px; 577 | -webkit-box-align: center; 578 | -webkit-align-items: center; 579 | -ms-flex-align: center; 580 | align-items: center; 581 | -webkit-box-pack: start; 582 | -webkit-justify-content: flex-start; 583 | -ms-flex-pack: start; 584 | justify-content: flex-start; 585 | text-align: center; 586 | border-radius: 4px; 587 | } 588 | 589 | #KioskBoard-VirtualKeyboard .kioskboard-row-numpad span[class^="kioskboard-key"] { 590 | margin: 4px 4px 12px; 591 | -webkit-box-pack: center; 592 | -webkit-justify-content: center; 593 | -ms-flex-pack: center; 594 | justify-content: center; 595 | font-size: 16px !important; 596 | width: calc(33.3333% - 16px); 597 | min-height: 55px; 598 | } 599 | 600 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-enter, 601 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-backspace, 602 | #KioskBoard-VirtualKeyboard .kioskboard-with-specialcharacter span.kioskboard-key-specialcharacter, 603 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-capslock { 604 | max-width: 60px; 605 | min-height: 45px; 606 | margin-bottom: 4px; 607 | } 608 | 609 | #KioskBoard-VirtualKeyboard .kioskboard-row-bottom span.kioskboard-key-space { 610 | padding-top: 10px; 611 | min-height: 45px; 612 | margin-bottom: 4px; 613 | } 614 | 615 | #KioskBoard-VirtualKeyboard .kioskboard-row span[class^="kioskboard-key"] svg { 616 | -webkit-transform: scale(0.7); 617 | transform: scale(0.7); 618 | -webkit-transform-origin: left top; 619 | transform-origin: left top; 620 | left: 8px; 621 | top: 8px; 622 | } 623 | 624 | #KioskBoard-VirtualKeyboard .kioskboard-row-numpad span[class^="kioskboard-key"] svg { 625 | top: 0; 626 | left: 18px; 627 | bottom: 0; 628 | margin: auto; 629 | -webkit-transform: scale(1); 630 | transform: scale(1); 631 | -webkit-transform-origin: center center; 632 | transform-origin: center center; 633 | } 634 | 635 | #KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters { 636 | padding: 15px 15px 10px; 637 | } 638 | 639 | #KioskBoard-VirtualKeyboard .kioskboard-row-specialcharacters span.kioskboard-specialcharacter-close { 640 | width: 30px; 641 | height: 30px; 642 | top: 0; 643 | right: 5px; 644 | } 645 | } 646 | 647 | /* KioskBoard: Responsive: end */ 648 | 649 | /* KioskBoard: Animations: begin */ 650 | #KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-fade { 651 | opacity: 1; 652 | -webkit-animation: kioskboard-animation-fade 0.36s ease-in-out 0s normal; 653 | animation: kioskboard-animation-fade 0.36s ease-in-out 0s normal; 654 | } 655 | 656 | @-webkit-keyframes kioskboard-animation-fade { 657 | 0% { 658 | opacity: 0; 659 | } 660 | 661 | 100% { 662 | opacity: 1; 663 | } 664 | } 665 | 666 | @keyframes kioskboard-animation-fade { 667 | 0% { 668 | opacity: 0; 669 | } 670 | 671 | 100% { 672 | opacity: 1; 673 | } 674 | } 675 | 676 | #KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-fade.kioskboard-fade-remove { 677 | opacity: 0; 678 | -webkit-animation: kioskboard-animation-fade-remove 0.36s ease-in-out 0s normal; 679 | animation: kioskboard-animation-fade-remove 0.36s ease-in-out 0s normal; 680 | } 681 | 682 | @-webkit-keyframes kioskboard-animation-fade-remove { 683 | 0% { 684 | opacity: 1; 685 | } 686 | 687 | 100% { 688 | opacity: 0; 689 | } 690 | } 691 | 692 | @keyframes kioskboard-animation-fade-remove { 693 | 0% { 694 | opacity: 1; 695 | } 696 | 697 | 100% { 698 | opacity: 0; 699 | } 700 | } 701 | 702 | #KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-placement-bottom.kioskboard-slide { 703 | bottom: 0; 704 | -webkit-animation: kioskboard-animation-slide-bottom 1.2s ease-in-out 0s normal; 705 | animation: kioskboard-animation-slide-bottom 1.2s ease-in-out 0s normal; 706 | } 707 | 708 | @-webkit-keyframes kioskboard-animation-slide-bottom { 709 | 0% { 710 | bottom: -100%; 711 | } 712 | 713 | 100% { 714 | bottom: 0; 715 | } 716 | } 717 | 718 | @keyframes kioskboard-animation-slide-bottom { 719 | 0% { 720 | bottom: -100%; 721 | } 722 | 723 | 100% { 724 | bottom: 0; 725 | } 726 | } 727 | 728 | #KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-slide.kioskboard-placement-bottom.kioskboard-slide-remove { 729 | bottom: -100%; 730 | -webkit-animation: kioskboard-animation-slide-bottom-remove 1.2s ease-in-out 0s normal; 731 | animation: kioskboard-animation-slide-bottom-remove 1.2s ease-in-out 0s normal; 732 | } 733 | 734 | @-webkit-keyframes kioskboard-animation-slide-bottom-remove { 735 | 0% { 736 | bottom: 0; 737 | } 738 | 739 | 100% { 740 | bottom: -100%; 741 | } 742 | } 743 | 744 | @keyframes kioskboard-animation-slide-bottom-remove { 745 | 0% { 746 | bottom: 0; 747 | } 748 | 749 | 100% { 750 | bottom: -100%; 751 | } 752 | } 753 | 754 | #KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-placement-top.kioskboard-slide { 755 | top: 0; 756 | -webkit-animation: kioskboard-animation-slide-top 1.2s ease-in-out 0s normal; 757 | animation: kioskboard-animation-slide-top 1.2s ease-in-out 0s normal; 758 | } 759 | 760 | @-webkit-keyframes kioskboard-animation-slide-top { 761 | 0% { 762 | top: -100%; 763 | } 764 | 765 | 100% { 766 | top: 0; 767 | } 768 | } 769 | 770 | @keyframes kioskboard-animation-slide-top { 771 | 0% { 772 | top: -100%; 773 | } 774 | 775 | 100% { 776 | top: 0; 777 | } 778 | } 779 | 780 | #KioskBoard-VirtualKeyboard.kioskboard-with-animation.kioskboard-slide.kioskboard-placement-top.kioskboard-slide-remove { 781 | top: -100%; 782 | -webkit-animation: kioskboard-animation-slide-top-remove 1.2s ease-in-out 0s normal; 783 | animation: kioskboard-animation-slide-top-remove 1.2s ease-in-out 0s normal; 784 | } 785 | 786 | @-webkit-keyframes kioskboard-animation-slide-top-remove { 787 | 0% { 788 | top: 0; 789 | } 790 | 791 | 100% { 792 | top: -100%; 793 | } 794 | } 795 | 796 | @keyframes kioskboard-animation-slide-top-remove { 797 | 0% { 798 | top: 0; 799 | } 800 | 801 | 100% { 802 | top: -100%; 803 | } 804 | } 805 | 806 | /* KioskBoard: Animations: end */ 807 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | KioskBoard - Virtual Keyboard | A pure JavaScript library for using virtual keyboards. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 |
36 | 37 | 49 | 50 |
51 |
52 | KioskBoard - Virtual Keyboard 53 |
54 |
55 |

KioskBoard

56 |

Virtual Keyboard

57 |

A pure JavaScript library for using virtual keyboards.

58 |

v2.3.0

59 |
60 |
Browser Compatibility
61 |
    62 |
  • 63 | 64 | Chrome 65 |
  • 66 |
  • 67 | 68 | Firefox 69 |
  • 70 |
  • 71 | 72 | Safari 73 |
  • 74 |
  • 75 | 76 | Opera 77 |
  • 78 |
  • 79 | 80 | Edge 81 |
  • 82 |
  • 83 | 84 | IE 11 85 |
  • 86 |
87 |
88 |
89 |
90 | 91 |
92 |
93 | 94 |
95 |

Keyboard Types

96 |

3 types of keyboards can be used: all, keyboard, and numpad.

97 |
98 |
99 |
100 |
101 | KioskBoard - All Keyboard 102 |

All

103 |

Number Keys (Static)

104 |

Custom Keys (From JSON or an Array of Objects)

105 |

Special Character Keys (Optional)

106 |
107 |
108 | 109 |
110 |
111 | 112 |
113 |
114 | KioskBoard - Keyboard 115 |

Keyboard

116 |

Custom Keys (From JSON or an Array of Objects)

117 |

Special Character Keys (Optional)

118 |
119 |
120 | 121 |
122 |
123 | 124 |
125 |
126 | KioskBoard - Numpad 127 |

Numpad

128 |

Number Keys

129 |
130 |
131 | 132 |
133 |
134 |
135 | 136 |
137 |
138 | 139 |
140 |
141 | 142 |
143 |

Themes

144 |

5 types of themes can be used. light, dark, flat, material, and oldschool.

145 |
146 | 147 |
148 |
149 |
150 | M 151 |

Light

152 |
153 |
154 | 155 |
156 |
157 |
158 |
159 | K 160 |

Dark

161 |
162 |
163 | 164 |
165 |
166 |
167 |
168 | A 169 |

Flat

170 |
171 |
172 | 173 |
174 |
175 |
176 |
177 | 8 178 |

Material

179 |
180 |
181 | 182 |
183 |
184 |
185 |
186 | 1 187 |

Oldschool

188 |
189 |
190 | 191 |
192 |
193 |
194 | 195 |
196 |
197 | 198 |
199 |
200 | 201 |
202 |

Adding to an HTML

203 |

There are two ways to add KioskBoard. The first one is adding CSS and JS files to the HTML file one by one. The second option is adding only the All In One file (Internal CSS).

204 |
205 | 206 |
207 | 208 | HTML CSS and JS 209 | 210 | <link rel="stylesheet" href="dist/kioskboard-2.3.0.min.css" /> 211 | 212 | <script src="dist/kioskboard-2.3.0.min.js"></script> 213 | 214 | 215 | 216 | HTML Only JS (Internal CSS) 217 | 218 | <script src="dist/kioskboard-aio-2.3.0.min.js"></script> 219 | 220 |
221 | 222 |
223 |
224 | 225 |
226 |
227 | 228 |
229 |

Import

230 |
231 | 232 |
233 | 234 | JS Import 235 | import KioskBoard from 'kioskboard'; 236 | 237 |
238 | 239 |
240 |
241 | 242 |
243 |
244 | 245 |
246 |

Run / Initialize

247 |

KioskBoard Virtual Keyboard can be used with the input or textarea elements.

248 |

KioskBoard must be initialized with the required options. The other ones are optional. Keyboard Type (the default value is "all") data-kioskboard-type, Keyboard Placement (the default value is "bottom") data-kioskboard-placement, and Special Characters data-kioskboard-specialcharacters settings are each element-based (data attributes).

249 |

All options and examples of data attribute usages are as below. Also, a custom class name can be defined as globally for all input and/or textarea elements to run KioskBoard.

250 |
251 | 252 |
253 | 254 | HTML data-* options 255 | 256 | <!-- An example of a textarea element: The keyboard type is "all", the placement is "top", and the availability of the special characters is "true". --> 257 | <textarea class="js-kioskboard-input" data-kioskboard-type="all" data-kioskboard-placement="top" data-kioskboard-specialcharacters="true" placeholder="Your Address"></textarea> 258 | 259 | 260 | 261 | <!-- An example of an input element: The keyboard type is "keyboard", the placement is "bottom", and the availability of the special characters is "false". --> 262 | <input class="js-kioskboard-input" data-kioskboard-type="keyboard" data-kioskboard-placement="bottom" data-kioskboard-specialcharacters="false" placeholder="Your Name" /> 263 | 264 | 265 | 266 | <!-- An example of an input element: The keyboard type is "numpad", and the placement is "bottom". (Special characters are not allowed for "numpad".) --> 267 | <input class="js-kioskboard-input" data-kioskboard-type="numpad" data-kioskboard-placement="bottom" placeholder="Your Number" /> 268 | 269 | 270 | 271 | JS Run with Init 272 | @param1 {string | HTMLInputElement | HTMLTextAreaElement}: CSS selector(s) that matches the element(s) or an input/textarea element. 273 | @param2 {Object}: The init options. 274 | KioskBoard.run('.js-kioskboard-input', { 275 | // ...init options 276 | }); 277 | 278 | 279 |

OR

280 | 281 | 282 | JS Step 1: Initialize 283 | 284 | // Initialize KioskBoard (default/all options) 285 | KioskBoard.init({ 286 | 287 | /*! 288 | * Required 289 | * An Array of Objects has to be defined for the custom keys. Hint: Each object creates a row element (HTML) on the keyboard. 290 | * e.g. [{"key":"value"}, {"key":"value"}] => [{"0":"A","1":"B","2":"C"}, {"0":"D","1":"E","2":"F"}] 291 | */ 292 | keysArrayOfObjects: null, 293 | 294 | 295 | 296 | /*! 297 | * Required only if "keysArrayOfObjects" is "null". 298 | * The path of the "kioskboard-keys-${langugage}.json" file must be set to the "keysJsonUrl" option. (XMLHttpRequest to get the keys from JSON file.) 299 | * e.g. '/Content/Plugins/KioskBoard/dist/kioskboard-keys-english.json' 300 | */ 301 | keysJsonUrl: null, 302 | 303 | 304 | 305 | /* 306 | * Optional: (Special Characters) 307 | * An Array of Strings can be set to override the built-in special characters. 308 | * e.g. ["#", "€", "%", "+", "-", "*"] 309 | */ 310 | keysSpecialCharsArrayOfStrings: null, 311 | 312 | 313 | 314 | /* 315 | * Optional: (Numpad Keys) 316 | * An Array of Numbers can be set to override the built-in numpad keys. (From 0 to 9, in any order.) 317 | * e.g. [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] 318 | */ 319 | keysNumpadArrayOfNumbers: null, 320 | 321 | 322 | // Optional: (Other Options) 323 | 324 | 325 | // Language Code (ISO 639-1) for custom keys (for language support) => e.g. "de" || "en" || "fr" || "hu" || "tr" etc... 326 | language: 'en', 327 | 328 | // The theme of keyboard => "light" || "dark" || "flat" || "material" || "oldschool" 329 | theme: 'light', 330 | 331 | // Scrolls the document to the top or bottom(by the placement option) of the input/textarea element. Prevented when "false" 332 | autoScroll: true, 333 | 334 | // Uppercase or lowercase to start. Uppercased when "true" 335 | capsLockActive: true, 336 | 337 | // Allow or prevent real/physical keyboard usage. Prevented when "false" 338 | // In addition, the "allowMobileKeyboard" option must be "true" as well, if the real/physical keyboard has wanted to be used. 339 | allowRealKeyboard: false, 340 | 341 | // Allow or prevent mobile keyboard usage. Prevented when "false" 342 | allowMobileKeyboard: false, 343 | 344 | // CSS animations for opening or closing the keyboard 345 | cssAnimations: true, 346 | 347 | // CSS animations duration as millisecond 348 | cssAnimationsDuration: 360, 349 | 350 | // CSS animations style for opening or closing the keyboard => "slide" || "fade" 351 | cssAnimationsStyle: 'slide', 352 | 353 | // Enable or Disable Spacebar functionality on the keyboard. The Spacebar will be passive when "false" 354 | keysAllowSpacebar: true, 355 | 356 | // Text of the Space key (Spacebar). Without text => " " 357 | keysSpacebarText: 'Space', 358 | 359 | // Font family of the keys 360 | keysFontFamily: 'sans-serif', 361 | 362 | // Font size of the keys 363 | keysFontSize: '22px', 364 | 365 | // Font weight of the keys 366 | keysFontWeight: 'normal', 367 | 368 | // Size of the icon keys 369 | keysIconSize: '25px', 370 | 371 | // Text of the Enter key (Enter/Return). Without text => " " 372 | keysEnterText: 'Enter', 373 | 374 | // The callback function of the Enter key. This function will be called when the enter key has been clicked. 375 | keysEnterCallback: undefined, 376 | 377 | // The Enter key can close and remove the keyboard. Prevented when "false" 378 | keysEnterCanClose: true, 379 | 380 | }); 381 | 382 | 383 | 384 | JS Step 2: Run 385 | // Select the input or the textarea element(s) to run the KioskBoard 386 | KioskBoard.run('.js-kioskboard-input'); 387 | 388 |
389 | 390 |
391 |
392 | 393 |
394 |
395 | 396 |
397 |

Language (JSON)

398 |

The keysJsonUrl option has to be set if custom keys are not defined with the keysArrayOfObjects option. JSON format has to be: [{"key":"value", "key":"value"}, ...]. Each object in that array creates a row element (HTML) on the keyboard. The "key" in the objects is used as an "index" for each Keyboard Keys. The "value" is each key's value and inner text.

399 |

400 | Additionally, KioskBoard includes 9 different language packages: 401 | Arabic 402 | , 403 | English 404 | , 405 | French 406 | , 407 | German 408 | , 409 | Hungarian 410 | , 411 | Persian 412 | , 413 | Russian 414 | , 415 | Spanish 416 | , and 417 | Turkish 418 | . 419 |

420 |
421 |
422 | 423 | JSON Custom Keys example in English 424 | 425 | [ 426 | { 427 | "0": "Q", 428 | "1": "W", 429 | "2": "E", 430 | "3": "R", 431 | "4": "T", 432 | "5": "Y", 433 | "6": "U", 434 | "7": "I", 435 | "8": "O", 436 | "9": "P" 437 | }, 438 | { 439 | "0": "A", 440 | "1": "S", 441 | "2": "D", 442 | "3": "F", 443 | "4": "G", 444 | "5": "H", 445 | "6": "J", 446 | "7": "K", 447 | "8": "L" 448 | }, 449 | { 450 | "0": "Z", 451 | "1": "X", 452 | "2": "C", 453 | "3": "V", 454 | "4": "B", 455 | "5": "N", 456 | "6": "M" 457 | } 458 | ] 459 | 460 |
461 | 462 |
463 |
464 | 465 |
466 | 467 | /furcan 468 |
469 | 470 |
471 | 472 |
473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | --------------------------------------------------------------------------------