├── screenshots └── vue-kaios-logo.png ├── src ├── assets │ ├── ionicons │ │ ├── fonts │ │ │ ├── ionicons.eot │ │ │ ├── ionicons.ttf │ │ │ └── ionicons.woff │ │ └── LICENSE │ ├── fonts │ │ ├── open-sans-v17-latin-300.eot │ │ ├── open-sans-v17-latin-300.ttf │ │ ├── open-sans-v17-latin-600.eot │ │ ├── open-sans-v17-latin-600.ttf │ │ ├── open-sans-v17-latin-700.eot │ │ ├── open-sans-v17-latin-700.ttf │ │ ├── open-sans-v17-latin-300.woff │ │ ├── open-sans-v17-latin-300.woff2 │ │ ├── open-sans-v17-latin-600.woff │ │ ├── open-sans-v17-latin-600.woff2 │ │ ├── open-sans-v17-latin-700.woff │ │ ├── open-sans-v17-latin-700.woff2 │ │ ├── open-sans-v17-latin-regular.eot │ │ ├── open-sans-v17-latin-regular.ttf │ │ ├── open-sans-v17-latin-regular.woff │ │ ├── open-sans-v17-latin-regular.woff2 │ │ └── open-sans-v17-latin-300.svg │ └── css │ │ └── theme.css ├── mixins │ ├── Toast.mixin.vue │ └── Notice.mixin.vue ├── utils │ └── Utils.js ├── components │ ├── Text.vue │ ├── Separator.vue │ ├── TabItem.vue │ ├── Header.vue │ ├── RadioGroup.vue │ ├── Toast.vue │ ├── Input.vue │ ├── InputFloat.vue │ ├── Tabs.vue │ ├── Notice.vue │ ├── InputMulti.vue │ ├── Button.vue │ ├── Softkeys.vue │ ├── Checkbox.vue │ ├── RadioButton.vue │ ├── ListItem.vue │ ├── Content.vue │ ├── Dialog.vue │ └── Slider.vue ├── plugin.js └── navigation │ └── Navigation.js ├── docs ├── Text.md ├── Separator.md ├── Tabs.md ├── Header.md ├── Softkeys.md ├── Content.md ├── RadioGroup.md ├── TabItem.md ├── InputFloat.md ├── Input.md ├── Toast.md ├── Dialog.md ├── Notice.md ├── Checkbox.md ├── Button.md ├── RadioButton.md ├── InputMulti.md ├── ListItem.md └── Slider.md ├── .gitignore ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── LICENSE.md ├── CONTRIBUTING.md ├── package.json ├── CODE_OF_CONDUCT.md └── README.md /screenshots/vue-kaios-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/screenshots/vue-kaios-logo.png -------------------------------------------------------------------------------- /src/assets/ionicons/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/ionicons/fonts/ionicons.eot -------------------------------------------------------------------------------- /src/assets/ionicons/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/ionicons/fonts/ionicons.ttf -------------------------------------------------------------------------------- /src/assets/ionicons/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/ionicons/fonts/ionicons.woff -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-300.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-300.eot -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-300.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-300.ttf -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-600.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-600.eot -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-600.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-600.ttf -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-700.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-700.eot -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-700.ttf -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-300.woff -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-300.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-600.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-600.woff -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-600.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-700.woff -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-700.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-regular.eot -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-regular.woff -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sebastianbaar/vue-kaiui/HEAD/src/assets/fonts/open-sans-v17-latin-regular.woff2 -------------------------------------------------------------------------------- /src/mixins/Toast.mixin.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /docs/Text.md: -------------------------------------------------------------------------------- 1 | # kaiui-text 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `text` ***String*** (*required*) 11 | 12 | The Text 13 | 14 | -------------------------------------------------------------------------------- /docs/Separator.md: -------------------------------------------------------------------------------- 1 | # kaiui-separator 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `title` ***String*** (*required*) 11 | 12 | The Title 13 | 14 | -------------------------------------------------------------------------------- /docs/Tabs.md: -------------------------------------------------------------------------------- 1 | # kaiui-tabs 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## slots 9 | 10 | - `default` Use this slot to set `` components. 11 | 12 | ## events 13 | 14 | - `set-tab-element-selected` 15 | 16 | -------------------------------------------------------------------------------- /docs/Header.md: -------------------------------------------------------------------------------- 1 | # kaiui-header 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `title` ***String*** (*required*) 11 | 12 | The Title 13 | 14 | ## events 15 | 16 | - `update-header-registered` 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /docs/Softkeys.md: -------------------------------------------------------------------------------- 1 | # kaiui-softkeys 2 | 3 | **PRIVATE: This component is automatically integrated in the `` component.** 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## events 9 | 10 | - `softkey-left-pressed` 11 | 12 | - `softkey-center-pressed` 13 | 14 | - `softkey-right-pressed` 15 | 16 | -------------------------------------------------------------------------------- /src/utils/Utils.js: -------------------------------------------------------------------------------- 1 | // https://stackoverflow.com/a/2117523 2 | const uuid = () => { 3 | return `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, (c) => 4 | ( 5 | c ^ 6 | (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4))) 7 | ).toString(16) 8 | ); 9 | }; 10 | 11 | export default { 12 | uuid, 13 | }; 14 | -------------------------------------------------------------------------------- /docs/Content.md: -------------------------------------------------------------------------------- 1 | # kaiui-content 2 | 3 | The `` component. 4 | 5 | **This is the root component of all other UI components. You HAVE TO put all other components inside of it.** 6 | 7 | - **author** - Sebastian Baar 8 | - **license** - MIT 9 | 10 | ## slots 11 | 12 | - `default` Use this slot to include all of your UI components. 13 | 14 | -------------------------------------------------------------------------------- /src/mixins/Notice.mixin.vue: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /docs/RadioGroup.md: -------------------------------------------------------------------------------- 1 | # kaiui-radiogroup 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## slots 9 | 10 | - `default` Use this slot to set `` components. 11 | 12 | ## props 13 | 14 | - `selected-value` ***String | Number | Boolean*** (*required*) `default: null` 15 | 16 | Use `v-model` to define a reactive value of the selected Radio Button 17 | 18 | -------------------------------------------------------------------------------- /docs/TabItem.md: -------------------------------------------------------------------------------- 1 | # kaiui-tab-item 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## slots 9 | 10 | - `default` Use this slot to include components in a tab-item. 11 | 12 | ## props 13 | 14 | - `name` ***String*** (*required*) 15 | 16 | The Name 17 | 18 | - `selected` ***Boolean*** (*optional*) `default: false` 19 | 20 | If the Tab Item should be selected 21 | 22 | -------------------------------------------------------------------------------- /docs/InputFloat.md: -------------------------------------------------------------------------------- 1 | # kaiui-input-float 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `label` ***String*** (*required*) 11 | 12 | The Input Label 13 | 14 | ## data 15 | 16 | - `value` 17 | 18 | **initial value:** `''` 19 | 20 | ## events 21 | 22 | - `input` 23 | 24 | Emit the event `input` with `value` when the input value changes 25 | 26 | - `set-element-selected` 27 | 28 | -------------------------------------------------------------------------------- /docs/Input.md: -------------------------------------------------------------------------------- 1 | # kaiui-input 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `placeholder` ***String*** (*optional*) 11 | 12 | The Placeholder 13 | 14 | - `label` ***String*** (*required*) 15 | 16 | The Input Label 17 | 18 | ## data 19 | 20 | - `value` 21 | 22 | **initial value:** `''` 23 | 24 | ## events 25 | 26 | - `input` 27 | 28 | Emit the event `input` with `value` when the input value changes 29 | 30 | - `set-element-selected` 31 | 32 | -------------------------------------------------------------------------------- /docs/Toast.md: -------------------------------------------------------------------------------- 1 | # kaiui-toast 2 | 3 | **PRIVATE: This component is automatically integrated as a global Mixin. Just use** 4 | 5 | `this.showToast("I'm a Toast")` 6 | 7 | **in any of your components.** 8 | 9 | - **author** - Sebastian Baar 10 | - **license** - MIT 11 | 12 | ## data 13 | 14 | - `title` 15 | 16 | The Title 17 | ***String*** (*required*) 18 | `default: ''` 19 | 20 | **initial value:** `''` 21 | 22 | - `time` 23 | 24 | The Time in ms 25 | ***Number*** (*optional*) 26 | `default: 2500` 27 | 28 | **initial value:** `2500` 29 | 30 | ## methods 31 | 32 | - `show(title, time)` 33 | 34 | -------------------------------------------------------------------------------- /src/components/Text.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 27 | 28 | 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /docs/Dialog.md: -------------------------------------------------------------------------------- 1 | # kaiui-dialog 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## slots 9 | 10 | - `default` Use this slot to include other UI components. 11 | 12 | ## props 13 | 14 | - `should-show` ***Boolean*** (*required*) `default: false` 15 | 16 | Use `v-model` to define a reactive value to hide/show the dialog 17 | 18 | - `softkeys` ***{ left: String, right: String }*** (*optional*) `default: { left: "Cancel", right: "OK" }` 19 | 20 | The Softkeys Object 21 | 22 | - `title` ***String*** (*required*) 23 | 24 | The Title 25 | 26 | ## events 27 | 28 | - `softLeft` 29 | 30 | Emit the event `softLeft` when left softkey is selected 31 | 32 | - `softRight` 33 | 34 | Emit the event `softRight` when right softkey is selected 35 | 36 | -------------------------------------------------------------------------------- /docs/Notice.md: -------------------------------------------------------------------------------- 1 | # kaiui-notice 2 | 3 | **PRIVATE: This component is automatically integrated as a global Mixin. Just use** 4 | 5 | `this.showNotice("ion-battery-empty", "Battery Full", "Battery is fully charged")` 6 | 7 | **in any of your components.** 8 | 9 | - **author** - Sebastian Baar 10 | - **license** - MIT 11 | 12 | ## data 13 | 14 | - `icon` 15 | 16 | The Icon CSS class 17 | ***String*** (*required*) 18 | `default: ''` 19 | 20 | **initial value:** `''` 21 | 22 | - `title` 23 | 24 | The Title 25 | ***String*** (*required*) 26 | `default: ''` 27 | 28 | **initial value:** `''` 29 | 30 | - `subtitle` 31 | 32 | The Subtitle 33 | ***String*** (*required*) 34 | `default: ''` 35 | 36 | **initial value:** `''` 37 | 38 | - `time` 39 | 40 | The Time in ms 41 | ***Number*** (*optional*) 42 | `default: 4000` 43 | 44 | **initial value:** `4000` 45 | 46 | -------------------------------------------------------------------------------- /docs/Checkbox.md: -------------------------------------------------------------------------------- 1 | # kaiui-checkbox 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `softkeys` ***{ left: String, center: String, right: String }*** (*optional*) `default: { center: "Select" }` 11 | 12 | The Softkeys Object 13 | 14 | - `primary-text` ***String*** (*required*) 15 | 16 | The Primary Text 17 | 18 | - `secondary-text` ***String*** (*optional*) 19 | 20 | The Secondary Text 21 | 22 | ## events 23 | 24 | - `softLeft` 25 | 26 | Emit the event `softLeft` when left softkey is selected 27 | 28 | - `softRight` 29 | 30 | Emit the event `softRight` when right softkey is selected 31 | 32 | - `softCenter` 33 | 34 | Emit the event `softCenter` when center softkey is selected 35 | 36 | - `update-softkeys-register` 37 | 38 | - `update-softkeys-unregister` 39 | 40 | - `set-element-selected` 41 | 42 | -------------------------------------------------------------------------------- /src/components/Separator.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 27 | 28 | 45 | -------------------------------------------------------------------------------- /docs/Button.md: -------------------------------------------------------------------------------- 1 | # kaiui-button 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `softkeys` ***{ left: String, center: String, right: String }*** (*optional*) `default: { center: "Select" }` 11 | 12 | The Softkeys Object 13 | 14 | - `title` ***String*** (*required*) 15 | 16 | The Title 17 | 18 | - `icon` ***String*** (*optional*) 19 | 20 | The Icon CSS class 21 | 22 | - `icon-right` ***Boolean*** (*optional*) 23 | 24 | If the Icon should be displayed on the right side 25 | 26 | ## events 27 | 28 | - `softLeft` 29 | 30 | Emit the event `softLeft` when left softkey is selected 31 | 32 | - `softRight` 33 | 34 | Emit the event `softRight` when right softkey is selected 35 | 36 | - `softCenter` 37 | 38 | Emit the event `softCenter` when center softkey is selected 39 | 40 | - `update-softkeys-register` 41 | 42 | - `update-softkeys-unregister` 43 | 44 | - `set-element-selected` 45 | 46 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. macOS Catalina] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. Nokia 8110 4G] 33 | - KaiOS: [e.g. 2.5.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /docs/RadioButton.md: -------------------------------------------------------------------------------- 1 | # kaiui-radiobutton 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `softkeys` ***{ left: String, center: String, right: String }*** (*optional*) `default: { center: "Select" }` 11 | 12 | The Softkeys Object 13 | 14 | - `value` ***String*** (*required*) 15 | 16 | The Value 17 | 18 | - `primary-text` ***String*** (*required*) 19 | 20 | The Primary Text 21 | 22 | - `secondary-text` ***String*** (*optional*) 23 | 24 | The Secondary Text 25 | 26 | ## events 27 | 28 | - `radiobutton-mounted` 29 | 30 | - `softLeft` 31 | 32 | Emit the event `softLeft` when left softkey is selected 33 | 34 | - `softRight` 35 | 36 | Emit the event `softRight` when right softkey is selected 37 | 38 | - `radiobutton-selected` 39 | 40 | - `softCenter` 41 | 42 | Emit the event `softCenter` when center softkey is selected 43 | 44 | - `update-softkeys-register` 45 | 46 | - `update-softkeys-unregister` 47 | 48 | - `set-element-selected` 49 | 50 | -------------------------------------------------------------------------------- /docs/InputMulti.md: -------------------------------------------------------------------------------- 1 | # kaiui-input-multi 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `softkeys` ***{ left: String, center: String, right: String }*** (*optional*) `default: { center: "Select" }` 11 | 12 | The Softkeys Object 13 | 14 | - `placeholder` ***String*** (*optional*) 15 | 16 | The Placeholder 17 | 18 | - `label` ***String*** (*required*) 19 | 20 | The Input Label 21 | 22 | ## data 23 | 24 | - `value` 25 | 26 | **initial value:** `''` 27 | 28 | ## events 29 | 30 | - `softLeft` 31 | 32 | Emit the event `softLeft` when left softkey is selected 33 | 34 | - `softRight` 35 | 36 | Emit the event `softRight` when right softkey is selected 37 | 38 | - `softCenter` 39 | 40 | Add line break & Emit the event `softCenter` when center softkey is selected 41 | 42 | - `input` 43 | 44 | Emit the event `input` with `value` when the input value changes 45 | 46 | - `update-softkeys-register` 47 | 48 | - `update-softkeys-unregister` 49 | 50 | - `set-element-selected` 51 | 52 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Sebastian Baar 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 | -------------------------------------------------------------------------------- /src/assets/ionicons/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Drifty (http://drifty.com/) 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/ListItem.md: -------------------------------------------------------------------------------- 1 | # kaiui-list-item 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `softkeys` ***{ left: String, center: String, right: String }*** (*optional*) `default: { center: "Select" }` 11 | 12 | The Softkeys Object 13 | 14 | - `primary-text` ***String*** (*required*) 15 | 16 | The Primary Text 17 | 18 | - `secondary-text` ***String*** (*optional*) 19 | 20 | The Secondary Text 21 | 22 | - `tertiary-text` ***String*** (*optional*) 23 | 24 | The Tertiary Text 25 | 26 | - `icon-left` ***String*** (*optional*) `default: 'none'` 27 | 28 | The Left Icon CSS class 29 | 30 | - `icon-right` ***String*** (*optional*) `default: 'kai-icon-arrow'` 31 | 32 | The Right Icon CSS class 33 | 34 | ## events 35 | 36 | - `softLeft` 37 | 38 | Emit the event `softLeft` when left softkey is selected 39 | 40 | - `softRight` 41 | 42 | Emit the event `softRight` when right softkey is selected 43 | 44 | - `softCenter` 45 | 46 | Emit the event `softCenter` when center softkey is selected 47 | 48 | - `update-softkeys-register` 49 | 50 | - `update-softkeys-unregister` 51 | 52 | - `set-element-selected` 53 | 54 | -------------------------------------------------------------------------------- /docs/Slider.md: -------------------------------------------------------------------------------- 1 | # kaiui-slider 2 | 3 | The `` component. 4 | 5 | - **author** - Sebastian Baar 6 | - **license** - MIT 7 | 8 | ## props 9 | 10 | - `softkeys` ***{ left: String, center: String, right: String }*** (*optional*) `default: { center: "Select" }` 11 | 12 | The Softkeys Object 13 | 14 | - `title` ***String*** (*required*) 15 | 16 | The Title 17 | 18 | - `start-value` ***Number*** (*optional*) 19 | 20 | The Start Value 21 | 22 | - `step` ***Number*** (*required*) `default: 1` 23 | 24 | The Step Value 25 | 26 | - `min-value` ***Number*** (*required*) `default: 1` 27 | 28 | The Minimum Value 29 | 30 | - `max-value` ***Number*** (*required*) `default: 10` 31 | 32 | The Maximum Value 33 | 34 | ## events 35 | 36 | - `softLeft` 37 | 38 | Emit the event `softLeft` when left softkey is selected 39 | 40 | - `softRight` 41 | 42 | Emit the event `softRight` when right softkey is selected 43 | 44 | - `softCenter` 45 | 46 | Emit the event `softCenter` when center softkey is selected 47 | 48 | - `update-softkeys-register` 49 | 50 | - `update-softkeys-unregister` 51 | 52 | - `change` 53 | 54 | Emit the event `change` with `value` when the Slider input value changes 55 | 56 | - `set-element-selected` 57 | 58 | -------------------------------------------------------------------------------- /src/components/TabItem.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 46 | 47 | 63 | -------------------------------------------------------------------------------- /src/components/Header.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 41 | 42 | 68 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to KaiUI Vue 2 | 3 | #### **Did you find a bug?** 4 | 5 | * **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/sebastianbaar/vue-kaiui/issues). 6 | 7 | * If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/sebastianbaar/vue-kaiui/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. 8 | 9 | * If possible, use the relevant bug report templates to create the issue. 10 | 11 | #### **Did you write a patch that fixes a bug?** 12 | 13 | * Open a new GitHub pull request with the patch. 14 | 15 | * Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. 16 | 17 | * Inlcude screenshots or screen video captures for all UI related work, before and after behaviour 18 | 19 | #### **Do you intend to add a new feature or change an existing one?** 20 | 21 | * Do not open an issue on GitHub until you have collected positive feedback about the change. 22 | 23 | * Several feature issues that are currently open are most likely more high prio, so please prioritize them before suggesting new features 24 | 25 | Thanks! :heart: :heart: :heart: 26 | 27 | Sebastian Baar 28 | 29 | __Credits to the Rails team for providing a template for this contributors guide__ 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-kaiui", 3 | "version": "0.1.1", 4 | "description": "Vue component library for KaiOS apps", 5 | "main": "dist/vue-kaiui.js", 6 | "module": "dist/vue-kaiui.esm.js", 7 | "unpkg": "dist/vue-kaiui.min.js", 8 | "scripts": { 9 | "release": "prettier --write ./src && vuedoc.md ./src/components/*.vue --output ./docs && npm run build", 10 | "build": "rimraf ./dist && npm run build:umd & npm run build:es & npm run build:unpkg", 11 | "build:umd": "rollup --config build/rollup.config.js --format umd --file dist/vue-kaiui.js", 12 | "build:es": "rollup --config build/rollup.config.js --format es --file dist/vue-kaiui.esm.js", 13 | "build:unpkg": "rollup --config build/rollup.config.js --format iife --file dist/vue-kaiui.min.js", 14 | "rimraf": "./node_modules/rimraf/bin.js" 15 | }, 16 | "keywords": [ 17 | "kai", 18 | "kaios", 19 | "vue", 20 | "vuejs", 21 | "kaiui", 22 | "component library" 23 | ], 24 | "files": [ 25 | "dist/" 26 | ], 27 | "author": { 28 | "name": "Sebastian Baar" 29 | }, 30 | "license": "MIT", 31 | "dependencies": {}, 32 | "repository": { 33 | "type": "git", 34 | "url": "https://github.com/sebastianbaar/vue-kaiui" 35 | }, 36 | "devDependencies": { 37 | "@vuedoc/md": "^1.6.0", 38 | "prettier": "2.0.5", 39 | "rimraf": "^3.0.2", 40 | "rollup": "^1.17.0", 41 | "rollup-plugin-buble": "^0.19.8", 42 | "rollup-plugin-commonjs": "^10.0.1", 43 | "rollup-plugin-copy": "^3.3.0", 44 | "rollup-plugin-vue": "^5.0.1", 45 | "vue": "^2.6.10", 46 | "vue-template-compiler": "^2.6.10" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/components/RadioGroup.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 65 | 66 | 72 | -------------------------------------------------------------------------------- /src/components/Toast.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 63 | 64 | 98 | -------------------------------------------------------------------------------- /src/components/Input.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 67 | 68 | 100 | -------------------------------------------------------------------------------- /src/plugin.js: -------------------------------------------------------------------------------- 1 | // Components 2 | import Content from "./components/Content.vue"; 3 | import Softkeys from "./components/Softkeys.vue"; 4 | import Header from "./components/Header.vue"; 5 | import Input from "./components/Input.vue"; 6 | import InputMulti from "./components/InputMulti.vue"; 7 | import InputFloat from "./components/InputFloat.vue"; 8 | import Button from "./components/Button.vue"; 9 | import Text from "./components/Text.vue"; 10 | import Separator from "./components/Separator.vue"; 11 | import Tabs from "./components/Tabs.vue"; 12 | import TabItem from "./components/TabItem.vue"; 13 | import ListItem from "./components/ListItem.vue"; 14 | import Checkbox from "./components/Checkbox.vue"; 15 | import RadioGroup from "./components/RadioGroup.vue"; 16 | import RadioButton from "./components/RadioButton.vue"; 17 | import Slider from "./components/Slider.vue"; 18 | import Toast from "./components/Toast.vue"; 19 | import Dialog from "./components/Dialog.vue"; 20 | import Notice from "./components/Notice.vue"; 21 | // Mixins 22 | import ToastMixin from "./mixins/Toast.mixin.vue"; 23 | import NoticeMixin from "./mixins/Notice.mixin.vue"; 24 | 25 | // CSS & Ionicons icons 26 | require("./assets/css/theme.css"); 27 | require("./assets/ionicons/css/style.css"); 28 | 29 | function install(Vue) { 30 | if (install.installed) return; 31 | install.installed = true; 32 | 33 | // components 34 | Vue.component(Content.name, Content); 35 | Vue.component(Softkeys.name, Softkeys); 36 | Vue.component(Header.name, Header); 37 | Vue.component(Input.name, Input); 38 | Vue.component(InputMulti.name, InputMulti); 39 | Vue.component(InputFloat.name, InputFloat); 40 | Vue.component(Button.name, Button); 41 | Vue.component(Text.name, Text); 42 | Vue.component(Separator.name, Separator); 43 | Vue.component(Tabs.name, Tabs); 44 | Vue.component(TabItem.name, TabItem); 45 | Vue.component(ListItem.name, ListItem); 46 | Vue.component(Checkbox.name, Checkbox); 47 | Vue.component(RadioGroup.name, RadioGroup); 48 | Vue.component(RadioButton.name, RadioButton); 49 | Vue.component(Slider.name, Slider); 50 | Vue.component(Toast.name, Toast); 51 | Vue.component(Dialog.name, Dialog); 52 | Vue.component(Notice.name, Notice); 53 | // mixins 54 | Vue.mixin(ToastMixin); 55 | Vue.mixin(NoticeMixin); 56 | } 57 | 58 | const plugin = { 59 | install, 60 | }; 61 | 62 | // Auto-install when vue is found (eg. in browser via 59 | 60 | 117 | -------------------------------------------------------------------------------- /src/components/Tabs.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 73 | 74 | 132 | -------------------------------------------------------------------------------- /src/components/Notice.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 79 | 80 | 137 | -------------------------------------------------------------------------------- /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 adrianm7151@gmail.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 | -------------------------------------------------------------------------------- /src/components/InputMulti.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 117 | 118 | 149 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Logo of vue-kaiui](./screenshots/vue-kaios-logo.png) 2 | 3 | > **Vue component library for KaiOS apps.** 4 | 5 | 6 | - [Installation](#installation) 7 | - [Usage](#usage) 8 | - [Components API](#components-api) 9 | - [Styles](#styles) 10 | - [Status](#status) 11 | - [Components](#components) 12 | - [Navigation](#navigation) 13 | - [Typography](#typography) 14 | - [Miscellaneous](#miscellaneous) 15 | - [Styling, Colors, Fonts](#styling-colors-fonts) 16 | - [Icons](#icons) 17 | - [Contributing](#contributing) 18 | 19 | # Installation 20 | ``` 21 | npm install vue-kaiui 22 | ``` 23 | In your `main.js` add 24 | 25 | ```javascript 26 | import Vue from 'vue' 27 | import App from './App.vue' 28 | 29 | import VueKaiUI from "vue-kaiui"; // ! 30 | Vue.use(VueKaiUI) // ! 31 | 32 | new Vue({ 33 | render: h => h(App), 34 | }).$mount('#app') 35 | ``` 36 | 37 | # Usage 38 | Most importantly, put all the components in the `` root so that KaiUI can manage all the Softkeys and Header design elements for you. 39 | 40 | ## Components API 41 | 42 | See the [Components API docs](https://github.com/sebastianbaar/vue-kaiui/tree/master/docs/) and the [Sample App](https://github.com/sebastianbaar/sample-vue-kaiui-app) for usage examples. 43 | 44 | ## Styles 45 | You can simply override CSS variables in your styles using the `:root` scope. All theme CSS variables are found [here](https://github.com/sebastianbaar/vue-kaiui/tree/master/src/assets/css/theme.css). 46 | 47 | ```css 48 | 59 | ``` 60 | 61 | # Status 62 | See [Contributing](#contributing). 63 | 64 | ## [Components](https://developer.kaiostech.com/design-guide/ui-component) 65 | - [x] Header 66 | - [x] Tab 67 | - [x] Software Key 68 | - [x] List Item 69 | - [x] Separator 70 | - [x] Checkbox 71 | - [x] Button 72 | - [x] Input 73 | - [x] Multiple-line Input 74 | - [x] Toast 75 | - [x] Radio Button (Group) 76 | - [ ] Progress 77 | - [ ] Slider (update Design!) 78 | - [ ] Date/Time Value Selector 79 | - [x] Dialog / Value Selector / Option Menu 80 | - [x] Notice 81 | ## [Navigation](https://developer.kaiostech.com/design-guide/basic-navigation) 82 | - [x] List View 83 | - [x] Tab View 84 | - [ ] Grid View 85 | ## [Typography](https://developer.kaiostech.com/design-guide/typography) 86 | - [x] Fonts 87 | - [x] Ionicons icons 88 | ## Miscellaneous 89 | - [ ] [Theming](https://developer.kaiostech.com/getting-started/build-your-first-package-app/sample-code#theme-apps) 90 | - [ ] [Translation](https://developer.kaiostech.com/getting-started/build-your-first-package-app/sample-code#apps-with-translation--l10n) 91 | - [ ] [LargeText](https://developer.kaiostech.com/api/largetext) 92 | - [ ] [Portrait/Landscape Mode](https://developer.kaiostech.com/core-developer-topics/supporting-multiple) 93 | 94 | 95 | # Styling, Colors, Fonts 96 | 97 | Typography details can be found [here](https://developer.kaiostech.com/design-guide/typography). 98 | 99 | Standardized stylings, colors and fonts are found in the [asset directory](https://github.com/sebastianbaar/vue-kaiui/tree/master/src/assets). 100 | 101 | # Icons 102 | 103 | Vue KaiUI uses the awesome [Ionicons](https://ionicons.com/) icons. 104 | 105 | Icons are found in the [asset directory](https://github.com/sebastianbaar/vue-kaiui/tree/master/src/assets). 106 | 107 | # Contributing 108 | 109 | There's much work to be done on building out more UI components, writing tests, etc... 110 | 111 | Please look at currently [open issues](https://github.com/sebastianbaar/vue-kaiui/issues?q=is%3Aopen+is%3Aissue) and our [Contributing Guide](https://github.com/sebastianbaar/vue-kaiui/blob/master/CONTRIBUTING.md). 112 | 113 | To build & test the project run: 114 | 115 | `npm install` 116 | 117 | `npm run build` 118 | 119 | To build the project and create API docs run: 120 | 121 | `npm run release` 122 | 123 | --- 124 | 125 | > Thanks [Adrian Machado](https://github.com/AdrianMachado) for the inspiration. Check out his awesome [KaiUI](https://github.com/AdrianMachado/KaiUI) (React component library for KaiOS apps). 126 | 127 | --- -------------------------------------------------------------------------------- /src/components/Button.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 120 | 121 | 164 | -------------------------------------------------------------------------------- /src/components/Softkeys.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 115 | 116 | 168 | -------------------------------------------------------------------------------- /src/components/Checkbox.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 128 | 129 | 192 | -------------------------------------------------------------------------------- /src/components/RadioButton.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 137 | 138 | 202 | -------------------------------------------------------------------------------- /src/components/ListItem.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 144 | 145 | 211 | -------------------------------------------------------------------------------- /src/components/Content.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 196 | 197 | 227 | -------------------------------------------------------------------------------- /src/components/Dialog.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 174 | 175 | 267 | -------------------------------------------------------------------------------- /src/components/Slider.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 166 | 167 | 277 | -------------------------------------------------------------------------------- /src/assets/css/theme.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html, 6 | body, 7 | #root { 8 | font-family: "Open Sans Regular/400", sans-serif; 9 | font-size: 17px; 10 | margin: 0; 11 | display: flex; 12 | flex-direction: column; 13 | height: 100%; 14 | color: var(--text-dark-color); 15 | overflow: hidden; 16 | outline: 0; 17 | } 18 | 19 | html { 20 | --primary-color: #6f02b5; 21 | --primary-light-color: #af8ed8; 22 | --primary-dark-color: #320276; 23 | --secondary-color: #e6e6e6; 24 | --secondary-dark-color: #cccccc; 25 | --dark-color: #6a6a6a; 26 | --light-color: #ffffff; 27 | 28 | --text-dark-color: #6a6a6a; 29 | --text-light-color: #ffffff; 30 | 31 | --softkeys-background-color: #cccccc; 32 | --softkeys-border-color: #cbcbcb; 33 | --softkeys-text-color: #242424; 34 | 35 | --header-background-color: var(--primary-dark-color); 36 | --header-text-color: var(--text-light-color); 37 | 38 | --separator-background-color: var(--secondary-color); 39 | --separator-text-color: var(--text-dark-color); 40 | 41 | --tabbar-tabs-selected-color: var(--primary-dark-color); 42 | --tabbar-tabs-background-color: var(--secondary-color); 43 | 44 | --listitem-selected-background-color: var(--primary-color); 45 | --listitem-selected-text-color: var(--text-light-color); 46 | --listitem-icon-right-color: var(--dark-color); 47 | 48 | --checkbox-selected-background-color: var(--primary-color); 49 | --checkbox-selected-text-color: var(--text-light-color); 50 | --checkbox-icon-selected-color: var(--light-color); 51 | --checkbox-icon-selected-checked-color: var(--light-color); 52 | --checkbox-icon-color: var(--text-dark-color); 53 | --checkbox-icon-color-checked: var(--primary-color); 54 | 55 | --button-background-color: var(--secondary-dark-color); 56 | --button-selected-background-color: var(--primary-color); 57 | --button-text-color: var(--text-dark-color); 58 | --button-selected-text-color: var(--text-light-color); 59 | --button-icon-color: var(--primary-color); 60 | --button-selected-icon-color: var(--light-color); 61 | 62 | --slider-selected-background-color: var(--primary-color); 63 | --slider-text-color: var(--text-dark-color); 64 | --slider-selected-text-color: var(--text-light-color); 65 | --slider-slider-color: var(--primary-color); 66 | --slider-selected-slider-color: var(--light-color); 67 | --slider-slider-thumb-color: var(--primary-color); 68 | --slider-selected-slider-thumb-color: var(--light-color); 69 | 70 | --input-selected-color: var(--primary-color); 71 | --input-border-color: var(--secondary-dark-color); 72 | --input-placeholder-color: #9b9b9b; 73 | --input-text-shadow-color: 0 0 0 rgba(0, 0, 0, 1); 74 | 75 | --toast-background-color: #323232; 76 | --toast-box-shadow: 0px 4px 5px 0px rgba(0, 0, 0, 0.5); 77 | --toast-text-color: var(--text-light-color); 78 | 79 | --dialog-background-color: var(--light-color); 80 | --dialog-backdrop-color: rgba(0, 0, 0, 0.9); 81 | --dialog-header-background-color: var(--secondary-dark-color); 82 | 83 | --notice-box-shadow: 0px 4px 5px 0px rgba(0, 0, 0, 0.5); 84 | --notice-icon-color: var(--light-color); 85 | --notice-icon-wrapper-color: var(--primary-color); 86 | --notice-background-color: var(--secondary-color); 87 | 88 | --radio-button-selected-background-color: var(--primary-color); 89 | --radio-button-selected-text-color: var(--text-light-color); 90 | --radio-button-icon-selected-color: var(--light-color); 91 | --radio-button-icon-selected-checked-color: var(--light-color); 92 | --radio-button-icon-color: var(--text-dark-color); 93 | --radio-button-icon-color-checked: var(--primary-color); 94 | } 95 | 96 | /* KaiOS Typography*/ 97 | /* https://developer.kaiostech.com/design-guide/typography */ 98 | .kaiui-h1 { 99 | font-family: "Open Sans Light/300"; 100 | font-size: 17px; 101 | } 102 | .kaiui-h2 { 103 | font-family: "Open Sans Semi-Bold/600"; 104 | font-size: 17px; 105 | } 106 | .kaiui-h3 { 107 | font-family: "Open Sans Regular/400"; 108 | font-size: 14px; 109 | } 110 | .kaiui-h4 { 111 | font-family: "Open Sans Regular/400"; 112 | font-size: 14px; 113 | } 114 | .kaiui-h5 { 115 | font-family: "Open Sans Semi-Bold/600"; 116 | font-size: 14px; 117 | } 118 | .kaiui-p_pri { 119 | font-family: "Open Sans Regular/400"; 120 | font-size: 17px; 121 | } 122 | .kaiui-p_sec { 123 | font-family: "Open Sans Regular/400"; 124 | font-size: 14px; 125 | } 126 | .kaiui-p_thi { 127 | font-family: "Open Sans Regular/400"; 128 | font-size: 12px; 129 | } 130 | .kaiui-p_ul { 131 | font-family: "Open Sans Regular/400"; 132 | font-size: 17px; 133 | } 134 | .p_link { 135 | font-family: "Open Sans Bold/700"; 136 | font-size: 17px; 137 | } 138 | .kaiui-p_btn { 139 | font-family: "Open Sans Regular/400"; 140 | font-size: 17px; 141 | } 142 | 143 | /* open-sans-300 - latin */ 144 | @font-face { 145 | font-family: "Open Sans Light/300"; 146 | font-style: normal; 147 | font-weight: 300; 148 | src: url("../fonts/open-sans-v17-latin-300.eot"); /* IE9 Compat Modes */ 149 | src: local("Open Sans Light"), local("OpenSans-Light"), 150 | url("../fonts/open-sans-v17-latin-300.eot?#iefix") 151 | format("embedded-opentype"), 152 | /* IE6-IE8 */ url("../fonts/open-sans-v17-latin-300.woff2") format("woff2"), 153 | /* Super Modern Browsers */ url("../fonts/open-sans-v17-latin-300.woff") 154 | format("woff"), 155 | /* Modern Browsers */ url("../fonts/open-sans-v17-latin-300.ttf") 156 | format("truetype"), 157 | /* Safari, Android, iOS */ 158 | url("../fonts/open-sans-v17-latin-300.svg#OpenSans") format("svg"); /* Legacy iOS */ 159 | } 160 | /* open-sans-regular - latin */ 161 | @font-face { 162 | font-family: "Open Sans Regular/400"; 163 | font-style: normal; 164 | font-weight: 400; 165 | src: url("../fonts/open-sans-v17-latin-regular.eot"); /* IE9 Compat Modes */ 166 | src: local("Open Sans Regular"), local("OpenSans-Regular"), 167 | url("../fonts/open-sans-v17-latin-regular.eot?#iefix") 168 | format("embedded-opentype"), 169 | /* IE6-IE8 */ url("../fonts/open-sans-v17-latin-regular.woff2") 170 | format("woff2"), 171 | /* Super Modern Browsers */ url("../fonts/open-sans-v17-latin-regular.woff") 172 | format("woff"), 173 | /* Modern Browsers */ url("../fonts/open-sans-v17-latin-regular.ttf") 174 | format("truetype"), 175 | /* Safari, Android, iOS */ 176 | url("../fonts/open-sans-v17-latin-regular.svg#OpenSans") format("svg"); /* Legacy iOS */ 177 | } 178 | /* open-sans-600 - latin */ 179 | @font-face { 180 | font-family: "Open Sans Semi-Bold/600"; 181 | font-style: normal; 182 | font-weight: 600; 183 | src: url("../fonts/open-sans-v17-latin-600.eot"); /* IE9 Compat Modes */ 184 | src: local("Open Sans SemiBold"), local("OpenSans-SemiBold"), 185 | url("../fonts/open-sans-v17-latin-600.eot?#iefix") 186 | format("embedded-opentype"), 187 | /* IE6-IE8 */ url("../fonts/open-sans-v17-latin-600.woff2") format("woff2"), 188 | /* Super Modern Browsers */ url("../fonts/open-sans-v17-latin-600.woff") 189 | format("woff"), 190 | /* Modern Browsers */ url("../fonts/open-sans-v17-latin-600.ttf") 191 | format("truetype"), 192 | /* Safari, Android, iOS */ 193 | url("../fonts/open-sans-v17-latin-600.svg#OpenSans") format("svg"); /* Legacy iOS */ 194 | } 195 | /* open-sans-700 - latin */ 196 | @font-face { 197 | font-family: "Open Sans Bold/700"; 198 | font-style: normal; 199 | font-weight: 700; 200 | src: url("../fonts/open-sans-v17-latin-700.eot"); /* IE9 Compat Modes */ 201 | src: local("Open Sans Bold"), local("OpenSans-Bold"), 202 | url("../fonts/open-sans-v17-latin-700.eot?#iefix") 203 | format("embedded-opentype"), 204 | /* IE6-IE8 */ url("../fonts/open-sans-v17-latin-700.woff2") format("woff2"), 205 | /* Super Modern Browsers */ url("../fonts/open-sans-v17-latin-700.woff") 206 | format("woff"), 207 | /* Modern Browsers */ url("../fonts/open-sans-v17-latin-700.ttf") 208 | format("truetype"), 209 | /* Safari, Android, iOS */ 210 | url("../fonts/open-sans-v17-latin-700.svg#OpenSans") format("svg"); /* Legacy iOS */ 211 | } 212 | -------------------------------------------------------------------------------- /src/navigation/Navigation.js: -------------------------------------------------------------------------------- 1 | var scope = null; 2 | 3 | /** 4 | * -------------------- 5 | * Scope & Init Methods 6 | * -------------------- 7 | */ 8 | 9 | const getCurrentScope = () => { 10 | return scope; 11 | }; 12 | 13 | const setCurrentScope = (rootComponent) => { 14 | removeAllNavigation(); 15 | scope = rootComponent; 16 | }; 17 | 18 | const init = () => { 19 | initElements(); 20 | initTabElements(); 21 | }; 22 | 23 | const removeAllNavigation = () => { 24 | [].forEach.call( 25 | document.querySelectorAll("[nav-selectable]"), 26 | (element, index) => { 27 | element.setAttribute("nav-selected", "false"); 28 | element.blur(); 29 | } 30 | ); 31 | }; 32 | 33 | /** 34 | * -------------------- 35 | * Elements Navigation 36 | * -------------------- 37 | */ 38 | const initElements = () => { 39 | [].forEach.call(getAllElements(), (element, index) => { 40 | element.setAttribute("nav-selected", "false"); 41 | }); 42 | 43 | const firstElement = getAllElements()[0]; 44 | if (!firstElement) return; 45 | 46 | firstElement.setAttribute("nav-selected", "true"); 47 | firstElement.setAttribute("nav-index", "0"); 48 | window.setTimeout(function () { 49 | // https://stackoverflow.com/questions/1096436/document-getelementbyidid-focus-is-not-working-for-firefox-or-chrome 50 | firstElement.focus(); 51 | }, 0); 52 | }; 53 | 54 | const getAllElements = () => scope.querySelectorAll("[nav-selectable]"); 55 | 56 | const getCurrentElement = () => scope.querySelector("[nav-selected=true]"); 57 | 58 | const getTheIndexOfTheSelectedElement = (current) => { 59 | const currentElement = current || getCurrentElement(); 60 | return currentElement 61 | ? parseInt(currentElement.getAttribute("nav-index")) 62 | : 0; 63 | }; 64 | 65 | const getCurrentItem = () => { 66 | const item = getCurrentElement(); 67 | const index = getTheIndexOfTheSelectedElement(item); 68 | return [item, index]; 69 | }; 70 | 71 | const selectElement = (selectElement) => { 72 | [].forEach.call(getAllElements(), (element, index) => { 73 | const selectThisElement = element === selectElement; 74 | element.setAttribute("nav-selected", selectThisElement); 75 | element.setAttribute("nav-index", index); 76 | if (selectThisElement) { 77 | element.focus(); 78 | element.scrollIntoView({ 79 | inline: "center", 80 | behavior: "smooth", 81 | }); 82 | } else { 83 | element.blur(); 84 | } 85 | }); 86 | }; 87 | 88 | const Down = () => { 89 | if (shouldBeHandledByElement("DOWN")) return; 90 | 91 | const allElements = getAllElements(); 92 | const currentIndex = getTheIndexOfTheSelectedElement(); 93 | const goToFirstElement = currentIndex + 1 > allElements.length - 1; 94 | const setIndex = goToFirstElement ? 0 : currentIndex + 1; 95 | selectElement(allElements[setIndex] || allElements[0]); 96 | }; 97 | 98 | const Up = () => { 99 | if (shouldBeHandledByElement("UP")) return; 100 | 101 | const allElements = getAllElements(); 102 | const currentIndex = getTheIndexOfTheSelectedElement(); 103 | const goToLastElement = currentIndex === 0; 104 | // const setIndex = goToLastElement ? allElements.length - 1 : currentIndex - 1; 105 | const setIndex = goToLastElement ? 0 : currentIndex - 1; 106 | selectElement(allElements[setIndex] || allElements[0]); 107 | }; 108 | 109 | /** 110 | * -------------------- 111 | * Tabbar Navigation 112 | * -------------------- 113 | */ 114 | const initTabElements = () => { 115 | const firstTabElement = getAllTabElements()[0]; 116 | if (!firstTabElement) return; 117 | firstTabElement.setAttribute("tab-selected", "true"); 118 | firstTabElement.setAttribute("tab-index", "0"); 119 | firstTabElement.focus(); 120 | }; 121 | 122 | const getAllTabElements = () => scope.querySelectorAll("[tab-selectable]"); 123 | 124 | const getCurrentTabElement = () => scope.querySelector("[tab-selected=true]"); 125 | 126 | const getTheIndexOfTheSelectedTabElement = (current) => { 127 | const currentElement = current || getCurrentTabElement(); 128 | return currentElement 129 | ? parseInt(currentElement.getAttribute("tab-index")) 130 | : 0; 131 | }; 132 | 133 | const getCurrentTabItem = () => { 134 | const item = getCurrentTabElement(); 135 | const index = getTheIndexOfTheSelectedTabElement(item); 136 | return [item, index]; 137 | }; 138 | 139 | const selectTabElement = (selectElement) => { 140 | [].forEach.call(getAllTabElements(), (element, index) => { 141 | const selectThisElement = element === selectElement; 142 | element.setAttribute("tab-selected", selectThisElement); 143 | element.setAttribute("tab-index", index); 144 | if (selectThisElement) { 145 | element.focus(); 146 | element.scrollIntoView({ 147 | inline: "center", 148 | behavior: "smooth", 149 | }); 150 | } else { 151 | element.blur(); 152 | } 153 | }); 154 | }; 155 | 156 | const Right = (callback) => { 157 | if (shouldBeHandledByElement("RIGHT")) return; 158 | 159 | const allElements = getAllTabElements(); 160 | const currentIndex = getTheIndexOfTheSelectedTabElement(); 161 | const reachedEnd = currentIndex + 1 > allElements.length - 1; 162 | 163 | if (!reachedEnd) { 164 | const setIndex = currentIndex + 1; 165 | selectTabElement(allElements[setIndex] || allElements[0]); 166 | 167 | callback(); 168 | } 169 | }; 170 | 171 | const Left = (callback) => { 172 | if (shouldBeHandledByElement("LEFT")) return; 173 | 174 | const allElements = getAllTabElements(); 175 | const currentIndex = getTheIndexOfTheSelectedTabElement(); 176 | const reachedStart = currentIndex === 0; 177 | 178 | if (!reachedStart) { 179 | const setIndex = currentIndex - 1; 180 | selectTabElement(allElements[setIndex] || allElements[0]); 181 | 182 | callback(); 183 | } 184 | }; 185 | 186 | const shouldBeHandledByElement = (direction) => { 187 | // check if current element is scrollable 188 | const currentElement = getCurrentItem()[0]; 189 | if (!currentElement) return false; 190 | 191 | switch (currentElement.tagName) { 192 | case "TEXTAREA": 193 | const rowNumber = currentElement.value.split("\n").length; 194 | const currentRow = currentElement.value 195 | .substr(0, currentElement.selectionStart) 196 | .split("\n").length; 197 | 198 | switch (direction) { 199 | case "LEFT": 200 | if (currentElement.selectionStart == 0) { 201 | Up(); 202 | } 203 | return true; 204 | case "RIGHT": 205 | if (currentElement.selectionStart >= currentElement.value.length) { 206 | Down(); 207 | } 208 | return true; 209 | case "UP": 210 | if (currentRow > 1) { 211 | return true; 212 | } 213 | break; 214 | case "DOWN": 215 | if (currentRow < rowNumber) { 216 | return true; 217 | } 218 | break; 219 | default: 220 | break; 221 | } 222 | break; 223 | case "INPUT": 224 | switch (direction) { 225 | case "LEFT": 226 | if (currentElement.getAttribute("type") == "kaiui-slider") { 227 | return true; 228 | } 229 | 230 | if (currentElement.selectionStart == 0) { 231 | Up(); 232 | } 233 | return true; 234 | case "RIGHT": 235 | if (currentElement.getAttribute("type") == "kaiui-slider") { 236 | return true; 237 | } 238 | 239 | if (currentElement.selectionStart >= currentElement.value.length) { 240 | Down(); 241 | } 242 | return true; 243 | case "UP": 244 | if (currentElement.getAttribute("type") == "kaiui-slider") { 245 | return false; 246 | } 247 | case "DOWN": 248 | if (currentElement.getAttribute("type") == "kaiui-slider") { 249 | return false; 250 | } 251 | default: 252 | break; 253 | } 254 | break; 255 | default: 256 | break; 257 | } 258 | return false; 259 | }; 260 | 261 | export default { 262 | getCurrentScope, 263 | setCurrentScope, 264 | init, 265 | Up, 266 | Down, 267 | Right, 268 | Left, 269 | initElements, 270 | getCurrentElement, 271 | selectElement, 272 | selectTabElement, 273 | }; 274 | -------------------------------------------------------------------------------- /src/assets/fonts/open-sans-v17-latin-300.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 14 | 15 | 17 | 19 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 39 | 41 | 42 | 44 | 46 | 47 | 50 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 62 | 63 | 65 | 67 | 68 | 69 | 70 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 81 | 82 | 84 | 85 | 87 | 88 | 89 | 90 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 103 | 105 | 106 | 108 | 110 | 111 | 114 | 115 | 116 | 118 | 119 | 120 | 122 | 123 | 125 | 127 | 129 | 130 | 132 | 133 | 134 | 135 | 137 | 138 | 140 | 141 | 143 | 144 | 146 | 147 | 148 | 149 | 151 | 153 | 155 | 156 | 157 | 160 | 161 | 164 | 166 | 167 | 168 | 169 | 172 | 173 | 175 | 176 | 178 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 188 | 189 | 191 | 193 | 196 | 198 | 200 | 202 | 204 | 206 | 208 | 210 | 211 | 213 | 214 | 215 | 216 | 218 | 219 | 220 | 221 | 223 | 224 | 226 | 228 | 230 | 232 | 235 | 237 | 238 | 240 | 242 | 244 | 246 | 248 | 249 | 250 | 253 | 255 | 257 | 259 | 262 | 265 | 268 | 271 | 273 | 275 | 277 | 279 | 281 | 282 | 283 | 284 | 286 | 288 | 290 | 292 | 294 | 296 | 299 | 301 | 303 | 305 | 307 | 309 | 311 | 313 | 315 | 317 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | --------------------------------------------------------------------------------