├── .gitattributes ├── .gitignore ├── .vscode └── extensions.json ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── main.version ├── manifest.json ├── service-worker.js └── static │ └── icons │ ├── 128x128.png │ ├── 144x144.png │ ├── 152x152.png │ ├── 192x192.png │ ├── 256x256.png │ ├── 384x384.png │ ├── 512x512.png │ ├── 72x72.png │ ├── 96x96.png │ ├── apple-touch-icon.png │ └── favicon.png ├── src ├── assets │ └── svelte.png ├── fonts │ ├── Framework7Icons-Regular.eot │ ├── Framework7Icons-Regular.ttf │ ├── Framework7Icons-Regular.woff │ ├── Framework7Icons-Regular.woff2 │ ├── MaterialIcons-Regular.eot │ ├── MaterialIcons-Regular.ttf │ ├── MaterialIcons-Regular.woff │ └── MaterialIcons-Regular.woff2 ├── lib │ ├── components │ │ ├── InstallButton.svelte │ │ ├── Routes.svelte │ │ └── Snackbar.svelte │ ├── interfaces │ │ └── message.ts │ ├── pages │ │ ├── FallbackPage.svelte │ │ └── HomePage.svelte │ ├── scripts │ │ ├── app │ │ │ ├── app.ts │ │ │ └── findServiceWorker.ts │ │ ├── decode │ │ │ ├── decodeURIObject.ts │ │ │ └── hexToRgb.ts │ │ ├── encode │ │ │ └── encodeURIObject.ts │ │ ├── inline.ts │ │ ├── install.ts │ │ ├── notify.ts │ │ ├── sha256.ts │ │ ├── storable.ts │ │ ├── style.ts │ │ └── uuid.ts │ ├── stores │ │ ├── localStorageExists.ts │ │ ├── localVersion.ts │ │ ├── message.ts │ │ └── serviceWorkerRegistration.ts │ └── style │ │ ├── dimensions.scss │ │ ├── framework7-icons.scss │ │ ├── grid.scss │ │ ├── margin.scss │ │ ├── overwrite-platform-defaults.scss │ │ ├── padding.scss │ │ ├── pallete │ │ ├── generic │ │ │ └── colors.scss │ │ ├── tools │ │ │ ├── colors.scss │ │ │ ├── elevation.scss │ │ │ └── functions.scss │ │ └── variables.scss │ │ └── variables.scss ├── main.scss ├── main.svelte ├── main.ts └── vite-env.d.ts ├── svelte.config.js ├── tsconfig.json └── vite.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | /.svelte-kit 5 | /package 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["svelte.svelte-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Svelte + TS + Vite 2 | 3 | This template should help get you started developing with Svelte and TypeScript in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). 8 | 9 | ## Need an official Svelte framework? 10 | 11 | Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. 12 | 13 | ## Technical considerations 14 | 15 | **Why use this over SvelteKit?** 16 | 17 | - It brings its own routing solution which might not be preferable for some users. 18 | - It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. 19 | `vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example. 20 | 21 | This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-app` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. 22 | 23 | Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. 24 | 25 | **Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** 26 | 27 | Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. 28 | 29 | **Why include `.vscode/extensions.json`?** 30 | 31 | Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. 32 | 33 | **Why enable `allowJs` in the TS template?** 34 | 35 | While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. 36 | 37 | **Why is HMR not preserving my local component state?** 38 | 39 | HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). 40 | 41 | If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. 42 | 43 | ```ts 44 | // store.ts 45 | // An extremely simple external store 46 | import { writable } from 'svelte/store' 47 | export default writable(0) 48 | ``` 49 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | MyApp 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Svelte + TS + Vite App 29 | 30 | 31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-svelte-ts-f7-starter", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "serve": "vite preview", 9 | "check": "svelte-check --tsconfig ./tsconfig.json" 10 | }, 11 | "devDependencies": { 12 | "@sveltejs/vite-plugin-svelte": "^1.0.0-next.11", 13 | "@tsconfig/svelte": "^2.0.1", 14 | "dom7": "^3.0.0", 15 | "framework7": ">=6.1.0-beta.1", 16 | "framework7-icons": ">=3.0.1", 17 | "framework7-svelte": ">=6.1.0-beta.1", 18 | "npm-run-all": "^4.1.5", 19 | "rollup-plugin-svelte": "^7.1.0", 20 | "rollup-plugin-workbox": "^6.1.1", 21 | "sass": "^1.35.2", 22 | "svelte": "^3.49.0", 23 | "svelte-check": "^2.1.0", 24 | "svelte-preprocess": "^4.7.2", 25 | "svelte-routing": "^1.6.0", 26 | "tslib": "^2.2.0", 27 | "typescript": "^4.3.2", 28 | "vite": "^2.9.13", 29 | "workbox-build": "^6.5.4", 30 | "workbox-core": "^6.1.5", 31 | "workbox-routing": "^6.1.5", 32 | "workbox-strategies": "^6.1.5" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/favicon.ico -------------------------------------------------------------------------------- /public/main.version: -------------------------------------------------------------------------------- 1 | 0.0.1 -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MyApp", 3 | "short_name": "app", 4 | "description": "description", 5 | "lang": "en-US", 6 | "display": "standalone", 7 | 8 | "theme_color": "#000000", 9 | "background_color": "#000000", 10 | "Scope": "/", 11 | "start_url": "/", 12 | 13 | "icons": [ 14 | { 15 | "src": "/static/icons/128x128.png", 16 | "sizes": "128x128", 17 | "type": "image/png" 18 | }, 19 | { 20 | "src": "/static/icons/144x144.png", 21 | "sizes": "144x144", 22 | "type": "image/png" 23 | }, 24 | { 25 | "src": "/static/icons/152x152.png", 26 | "sizes": "152x152", 27 | "type": "image/png" 28 | }, 29 | { 30 | "src": "/static/icons/192x192.png", 31 | "sizes": "192x192", 32 | "type": "image/png" 33 | }, 34 | { 35 | "src": "/static/icons/256x256.png", 36 | "sizes": "256x256", 37 | "type": "image/png" 38 | }, 39 | { 40 | "src": "/static/icons/512x512.png", 41 | "sizes": "512x512", 42 | "type": "image/png" 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /public/service-worker.js: -------------------------------------------------------------------------------- 1 | var workbox = {} 2 | importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js'); 3 | 4 | 5 | const { registerRoute } = workbox.routing; 6 | const { CacheFirst } = workbox.strategies; 7 | 8 | registerRoute( 9 | ({url}) => ( 10 | !url.pathname.endsWith(".version") 11 | ), 12 | new CacheFirst() 13 | ); 14 | 15 | async function notify(title,body,vibrate=[200, 100, 200],icon='',tag=''){ 16 | this.registration.showNotification(title, { 17 | body: body, 18 | icon: icon, 19 | vibrate: vibrate, 20 | tag: tag 21 | }) 22 | } 23 | 24 | let vars = {}; 25 | 26 | self.addEventListener('message', async function(event){ 27 | let data = JSON.parse(event.data); 28 | console.log("Service worker recieved a message:",{data}); 29 | switch(data.action){ 30 | case "set-vars": 31 | for(let key in event.data.body) { 32 | vars[key] = event.data.body[key]; 33 | console.log(`vars['${key}'] set to `,event.data.body[key]); 34 | } 35 | break; 36 | case "send-notification": 37 | notify( 38 | data.body.title, 39 | data.body.body, 40 | data.body.vibrate, 41 | data.body.icon, 42 | data.body.tag 43 | ); 44 | break; 45 | } 46 | }); 47 | 48 | self.addEventListener('install', function (e) { 49 | console.log("Website saved locally."); 50 | }); -------------------------------------------------------------------------------- /public/static/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/128x128.png -------------------------------------------------------------------------------- /public/static/icons/144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/144x144.png -------------------------------------------------------------------------------- /public/static/icons/152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/152x152.png -------------------------------------------------------------------------------- /public/static/icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/192x192.png -------------------------------------------------------------------------------- /public/static/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/256x256.png -------------------------------------------------------------------------------- /public/static/icons/384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/384x384.png -------------------------------------------------------------------------------- /public/static/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/512x512.png -------------------------------------------------------------------------------- /public/static/icons/72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/72x72.png -------------------------------------------------------------------------------- /public/static/icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/96x96.png -------------------------------------------------------------------------------- /public/static/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /public/static/icons/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/public/static/icons/favicon.png -------------------------------------------------------------------------------- /src/assets/svelte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/assets/svelte.png -------------------------------------------------------------------------------- /src/fonts/Framework7Icons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/fonts/Framework7Icons-Regular.eot -------------------------------------------------------------------------------- /src/fonts/Framework7Icons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/fonts/Framework7Icons-Regular.ttf -------------------------------------------------------------------------------- /src/fonts/Framework7Icons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/fonts/Framework7Icons-Regular.woff -------------------------------------------------------------------------------- /src/fonts/Framework7Icons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/fonts/Framework7Icons-Regular.woff2 -------------------------------------------------------------------------------- /src/fonts/MaterialIcons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/fonts/MaterialIcons-Regular.eot -------------------------------------------------------------------------------- /src/fonts/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/fonts/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /src/fonts/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/fonts/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /src/fonts/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razshare/svelte-f7-starter/57232f0b1140d337b12f17380ee3db7058b8e84f/src/fonts/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /src/lib/components/InstallButton.svelte: -------------------------------------------------------------------------------- 1 | 16 | 17 |
18 | 22 |
23 | 24 | 25 | 36 | -------------------------------------------------------------------------------- /src/lib/components/Routes.svelte: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/lib/components/Snackbar.svelte: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | {#if Array.isArray(message.text)} 5 | {#each message.text as line} 6 | {line}
7 | {/each} 8 | {:else} 9 | {message.text} 10 | {/if} 11 |
12 |
13 | {#each message.buttons as button} 14 | 17 | {/each} 18 |
19 |
20 |
21 | 22 | 60 | -------------------------------------------------------------------------------- /src/lib/interfaces/message.ts: -------------------------------------------------------------------------------- 1 | interface RichMessageButton{ 2 | text:string 3 | action:Function 4 | } 5 | 6 | interface RichMessage{ 7 | text:string|Array 8 | timeout?:number 9 | onExpire?:Function 10 | buttons?:Array 11 | } 12 | 13 | export type { 14 | RichMessage, 15 | RichMessageButton, 16 | } -------------------------------------------------------------------------------- /src/lib/pages/FallbackPage.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | This is the fallback page 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/lib/pages/HomePage.svelte: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | 15 |
16 | svelte logo 17 |
18 |
19 | 20 | 25 | 26 | 27 | {#if $isInstallable} 28 | 29 | {/if} 30 |
-------------------------------------------------------------------------------- /src/lib/scripts/app/app.ts: -------------------------------------------------------------------------------- 1 | import { findServiceWorker } from "./findServiceWorker" 2 | import localVersion from '../../stores/localVersion' 3 | import message from "../../stores/message" 4 | 5 | 6 | async function initWebApp():Promise{ 7 | let $localVersion:string 8 | localVersion.subscribe($=>$localVersion=$)() 9 | 10 | try{ 11 | let response = await fetch('/main.version') 12 | let remoteVersion = await response.text() 13 | setup($localVersion,remoteVersion); 14 | }catch(e){ 15 | /** 16 | * This is very important. 17 | * 18 | * The above fetch request is the only request in the whole 19 | * application (besides API requests perhaps) that does not 20 | * hit the local cache storage at all, it will go straight to the server. 21 | * 22 | * This means the above request will always fail when your user is offline. 23 | * 24 | * In that case the application should keep working as usual, thus the 25 | * remote version should be set the same as the local version. 26 | */ 27 | 28 | setup($localVersion,$localVersion); 29 | } 30 | 31 | } 32 | 33 | function sync($localVersion:string, remoteVersion:string):void{ 34 | if($localVersion !== remoteVersion){ 35 | //location.reload(true); 36 | message.set({ 37 | text: `New version available ${remoteVersion}`, 38 | timeout: 1000*60*30, //30 minutes 39 | buttons:[ 40 | { 41 | text:'Update', 42 | action:()=>{ 43 | message.set(null) //this will close the snackbar menu 44 | console.log(`Updating from version ${$localVersion} to version ${remoteVersion}`) 45 | if(window.caches) 46 | caches.keys().then((keyList) => { 47 | console.log({keyList}); 48 | 49 | Promise.all(keyList.map((key) => caches.delete(key))) 50 | }); 51 | if(window.navigator && window.navigator.serviceWorker) 52 | window.navigator.serviceWorker.getRegistrations().then(function(registrations) { 53 | for(let registration of registrations) { 54 | registration.unregister() 55 | } 56 | }) 57 | localVersion.set(remoteVersion) 58 | 59 | location.reload(true) 60 | } 61 | }, 62 | { 63 | text:'Close', 64 | action:()=>message.set(null), 65 | } 66 | ] 67 | }); 68 | 69 | } 70 | } 71 | 72 | function setup($localVersion:string,remoteVersion:string):void{ 73 | try{ 74 | console.log("versions:",{ 75 | "local":$localVersion, 76 | "remote":remoteVersion 77 | }) 78 | 79 | sync($localVersion,remoteVersion); 80 | 81 | if(window.navigator && window.navigator.serviceWorker) 82 | navigator.serviceWorker.getRegistrations().then(findServiceWorker); 83 | 84 | }catch(e){ 85 | console.error(e) 86 | } 87 | } 88 | 89 | export { initWebApp } -------------------------------------------------------------------------------- /src/lib/scripts/app/findServiceWorker.ts: -------------------------------------------------------------------------------- 1 | import swr from "../../stores/serviceWorkerRegistration" 2 | 3 | const FILE_NAME = '/service-worker.js' 4 | 5 | async function findServiceWorker(registrations){ 6 | if(registrations.length > 0){ 7 | let reg = null; 8 | for(let i = 0; i < registrations.length; i++){ 9 | if(registrations[i].active && window.location.origin+FILE_NAME === registrations[i].active.scriptURL){ 10 | reg = registrations[i]; 11 | break; 12 | } 13 | } 14 | if(reg === null) 15 | console.info(`Service worker '${FILE_NAME}' not found!`); 16 | else{ 17 | console.info(`Service worker '${FILE_NAME}' found!`); 18 | swr.set(reg); 19 | } 20 | }else{ 21 | console.info("No service worker registered on this website."); 22 | console.log(`New worker registration request created for '${FILE_NAME}'.`); 23 | await navigator.serviceWorker.register(FILE_NAME); 24 | let wk:ServiceWorkerRegistration = await navigator.serviceWorker.ready; 25 | swr.set(wk); 26 | } 27 | } 28 | 29 | 30 | export { 31 | findServiceWorker 32 | }; -------------------------------------------------------------------------------- /src/lib/scripts/decode/decodeURIObject.ts: -------------------------------------------------------------------------------- 1 | export default function decodeURIObject(search:string):Record{ 2 | return JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) }) 3 | } -------------------------------------------------------------------------------- /src/lib/scripts/decode/hexToRgb.ts: -------------------------------------------------------------------------------- 1 | export default function hextToRgb(hex:string):Array{ 2 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 3 | return result ? [ 4 | parseInt(result[1], 16), 5 | parseInt(result[2], 16), 6 | parseInt(result[3], 16) 7 | ] : null; 8 | } -------------------------------------------------------------------------------- /src/lib/scripts/encode/encodeURIObject.ts: -------------------------------------------------------------------------------- 1 | export default function encodeURIObject(obj:any):string{ 2 | const str = []; 3 | for (var p in obj) 4 | if (obj.hasOwnProperty(p)) { 5 | str.push(`${encodeURIComponent(p)}=${encodeURIComponent(obj[p])}`); 6 | } 7 | return str.join("&"); 8 | } -------------------------------------------------------------------------------- /src/lib/scripts/inline.ts: -------------------------------------------------------------------------------- 1 | export default function inline(c:Function):string{ 2 | c(); 3 | return ''; 4 | } -------------------------------------------------------------------------------- /src/lib/scripts/install.ts: -------------------------------------------------------------------------------- 1 | import message from '../stores/message'; 2 | import {Writable, writable} from 'svelte/store'; 3 | const isInstallable:Writable = writable(false); 4 | 5 | let request; 6 | 7 | window.addEventListener('beforeinstallprompt', (r:any) => { 8 | // Prevent Chrome 67 and earlier from automatically showing the prompt 9 | r.preventDefault() 10 | request = r 11 | isInstallable.set(true) 12 | }); 13 | 14 | 15 | async function install():Promise{ 16 | if(!request){ 17 | let $isInstallable; 18 | isInstallable.subscribe(x=>$isInstallable=x)() 19 | if(!$isInstallable){ 20 | message.set( 21 | { 22 | text:[ 23 | "This application is not installable.", 24 | "Perhaps you've already installed it or the origin domain is not secure?" 25 | ] 26 | } 27 | ) 28 | }else if(!["127.0.0.1","localhost"].includes(location.hostname) && !location.protocol.startsWith("https")){ 29 | message.set({text:"You cannot install a Progressive Web Application from a non secure domain."}) 30 | }else{ 31 | message.set({text:"Unknown error."}) 32 | } 33 | return; 34 | } 35 | let installResponse = await request.prompt(); 36 | console.info({installResponse}); 37 | return installResponse.outcome === 'accepted'; 38 | } 39 | 40 | 41 | export { 42 | isInstallable, 43 | install, 44 | } -------------------------------------------------------------------------------- /src/lib/scripts/notify.ts: -------------------------------------------------------------------------------- 1 | import swr from '../stores/serviceWorkerRegistration'; 2 | import message from '../stores/message'; 3 | 4 | async function requestNotificationPermission():Promise{ 5 | return (await Notification.requestPermission()) === 'granted'; 6 | } 7 | 8 | 9 | export default async function notify( 10 | title:string, 11 | body:string, 12 | delay:number=1, 13 | vibrate:Array=[200, 100, 200], 14 | icon:string='static/images/logo.png', 15 | tag:string='' 16 | ):Promise{ 17 | if(!await requestNotificationPermission()){ 18 | console.warn("Notification won't be sent because notification permission has not been granted."); 19 | message.set({text:"This application does not have permission to send local notifications."}) 20 | return; 21 | } 22 | 23 | (swr.subscribe($swr=>{ 24 | if($swr === null){ 25 | console.warn("You need to install the main worker before sending a notification."); 26 | message.set({text:"The local notifications system is unavailable for this application."}) 27 | return; 28 | } 29 | $swr.active.postMessage(JSON.stringify({ 30 | action: "send-notification", 31 | body: { 32 | title, 33 | body, 34 | vibrate, 35 | icon, 36 | tag 37 | } 38 | })); 39 | }))(); 40 | } -------------------------------------------------------------------------------- /src/lib/scripts/sha256.ts: -------------------------------------------------------------------------------- 1 | export default async function sha256(message):Promise{ 2 | // encode as UTF-8 3 | const msgBuffer = new TextEncoder().encode(message); 4 | 5 | // hash the message 6 | const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer); 7 | 8 | // convert ArrayBuffer to Array 9 | const hashArray = Array.from(new Uint8Array(hashBuffer)); 10 | 11 | // convert bytes to hex string 12 | const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join(''); 13 | return hashHex; 14 | } -------------------------------------------------------------------------------- /src/lib/scripts/storable.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Example how to use: 3 | import storable from "../scripts/storable"; 4 | 5 | const stayConnected = storable("stayConnected",false); 6 | export default stayConnected; 7 | */ 8 | import { Writable, writable } from 'svelte/store'; 9 | import localStorageExists from '../stores/localStorageExists'; 10 | 11 | let $localStorageExists = false; 12 | const unsubscribe = localStorageExists.subscribe(_localStorageExists=>$localStorageExists=_localStorageExists); 13 | unsubscribe(); 14 | 15 | export default function storable(storeName:string, store:any):Writable{ 16 | if($localStorageExists && localStorage[storeName]){ 17 | try{ 18 | store = JSON.parse(localStorage[storeName]); 19 | }catch(e){ 20 | console.error("Could not load store \""+storeName+"\".",e); 21 | store = null; 22 | } 23 | } 24 | const result = writable(store); 25 | if($localStorageExists){ 26 | result.subscribe($result=>{ 27 | localStorage.setItem(storeName,JSON.stringify($result)); 28 | }); 29 | } 30 | return result; 31 | } 32 | -------------------------------------------------------------------------------- /src/lib/scripts/style.ts: -------------------------------------------------------------------------------- 1 | 2 | export default function style(contents:string):string{ 3 | return ``; 4 | } -------------------------------------------------------------------------------- /src/lib/scripts/uuid.ts: -------------------------------------------------------------------------------- 1 | export default function uuid(short=false):string{ 2 | let dt = new Date().getTime(); 3 | const BLUEPRINT = short?'xyxxyxyx':'xxxxxxxx-xxxx-yxxx-yxxx-xxxxxxxxxxxx'; 4 | const RESULT = BLUEPRINT.replace(/[xy]/g, function(c) { 5 | let r = (dt + Math.random()*16)%16 | 0; 6 | dt = Math.floor(dt/16); 7 | return (c=='x' ? r :(r&0x3|0x8)).toString(16); 8 | }); 9 | return RESULT; 10 | } -------------------------------------------------------------------------------- /src/lib/stores/localStorageExists.ts: -------------------------------------------------------------------------------- 1 | import { Writable, writable } from 'svelte/store'; 2 | import uuid from '../scripts/uuid'; 3 | 4 | let test = uuid(); 5 | let store = false; 6 | try { 7 | localStorage.setItem(test, test); 8 | localStorage.removeItem(test); 9 | store = true; 10 | } catch(e) { 11 | console.warn("This browser does not support the localStorage API."); 12 | store = false; 13 | } 14 | 15 | const localStorageExists:Writable = writable(store); 16 | 17 | export default localStorageExists; -------------------------------------------------------------------------------- /src/lib/stores/localVersion.ts: -------------------------------------------------------------------------------- 1 | import storable from '../scripts/storable'; 2 | const localVersion = storable("localVersion","0.0.1"); 3 | export default localVersion; -------------------------------------------------------------------------------- /src/lib/stores/message.ts: -------------------------------------------------------------------------------- 1 | import { Writable, writable } from 'svelte/store'; 2 | import type { RichMessage } from '../interfaces/message'; 3 | 4 | const message:Writable = writable(null); 5 | 6 | export default message; -------------------------------------------------------------------------------- /src/lib/stores/serviceWorkerRegistration.ts: -------------------------------------------------------------------------------- 1 | import {Writable, writable} from 'svelte/store'; 2 | 3 | const worker:Writable = writable(null); 4 | 5 | export default worker; -------------------------------------------------------------------------------- /src/lib/style/dimensions.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | .full-width{ 4 | width: 100%; 5 | } 6 | .full-height{ 7 | height: 100%; 8 | } 9 | .border-radius-0{ 10 | border-radius: 0; 11 | } 12 | .float-left{ 13 | float: left; 14 | } 15 | .float-right{ 16 | float: right; 17 | } 18 | -------------------------------------------------------------------------------- /src/lib/style/framework7-icons.scss: -------------------------------------------------------------------------------- 1 | /* Material Icons Font (for MD theme) */ 2 | @font-face { 3 | font-family: 'Material Icons'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: url(./fonts/MaterialIcons-Regular.eot); 7 | src: local('Material Icons'), 8 | local('MaterialIcons-Regular'), 9 | url(./fonts/MaterialIcons-Regular.woff2) format('woff2'), 10 | url(./fonts/MaterialIcons-Regular.woff) format('woff'), 11 | url(./fonts/MaterialIcons-Regular.ttf) format('truetype'); 12 | } 13 | .material-icons { 14 | font-family: 'Material Icons'; 15 | font-weight: normal; 16 | font-style: normal; 17 | font-size: 24px; 18 | display: inline-block; 19 | line-height: 1; 20 | text-transform: none; 21 | letter-spacing: normal; 22 | word-wrap: normal; 23 | white-space: nowrap; 24 | direction: ltr; 25 | -webkit-font-smoothing: antialiased; 26 | text-rendering: optimizeLegibility; 27 | -moz-osx-font-smoothing: grayscale; 28 | font-feature-settings: 'liga'; 29 | } 30 | 31 | /* Framework7 Icons Font (for iOS theme) */ 32 | @font-face { 33 | font-family: 'Framework7 Icons'; 34 | font-style: normal; 35 | font-weight: 400; 36 | src: url("./fonts/Framework7Icons-Regular.eot"); 37 | src: url("./fonts/Framework7Icons-Regular.woff2") format("woff2"), 38 | url("./fonts/Framework7Icons-Regular.woff") format("woff"), 39 | url("./fonts/Framework7Icons-Regular.ttf") format("truetype"); 40 | } 41 | .f7-icons { 42 | font-family: 'Framework7 Icons'; 43 | font-weight: normal; 44 | font-style: normal; 45 | font-size: 28px; 46 | line-height: 1; 47 | letter-spacing: normal; 48 | text-transform: none; 49 | display: inline-block; 50 | white-space: nowrap; 51 | word-wrap: normal; 52 | direction: ltr; 53 | -webkit-font-smoothing: antialiased; 54 | text-rendering: optimizeLegibility; 55 | -moz-osx-font-smoothing: grayscale; 56 | -webkit-font-feature-settings: "liga"; 57 | -moz-font-feature-settings: "liga=1"; 58 | -moz-font-feature-settings: "liga"; 59 | font-feature-settings: "liga"; 60 | text-align: center; 61 | } 62 | -------------------------------------------------------------------------------- /src/lib/style/grid.scss: -------------------------------------------------------------------------------- 1 | .grid{ 2 | display: grid; 3 | } 4 | 5 | /*COLS*/ 6 | .grid-cols-1{ 7 | grid-template-columns: 1fr; 8 | } 9 | .grid-cols-2{ 10 | grid-template-columns: repeat(2,1fr); 11 | } 12 | .grid-cols-3{ 13 | grid-template-columns: repeat(3,1fr); 14 | } 15 | .grid-cols-4{ 16 | grid-template-columns: repeat(4,1fr); 17 | } 18 | .grid-cols-5{ 19 | grid-template-columns: repeat(5,1fr); 20 | } 21 | .grid-cols-6{ 22 | grid-template-columns: repeat(6,1fr); 23 | } 24 | .grid-cols-7{ 25 | grid-template-columns: repeat(7,1fr); 26 | } 27 | .grid-cols-8{ 28 | grid-template-columns: repeat(8,1fr); 29 | } 30 | .grid-cols-9{ 31 | grid-template-columns: repeat(9,1fr); 32 | } 33 | .grid-cols-10{ 34 | grid-template-columns: repeat(10,1fr); 35 | } 36 | 37 | /*COLS AUTO*/ 38 | .grid-cols-1-auto{ 39 | grid-template-columns: auto; 40 | } 41 | .grid-cols-2-auto{ 42 | grid-template-columns: repeat(2,auto); 43 | } 44 | .grid-cols-3-auto{ 45 | grid-template-columns: repeat(3,auto); 46 | } 47 | .grid-cols-4-auto{ 48 | grid-template-columns: repeat(4,auto); 49 | } 50 | .grid-cols-5-auto{ 51 | grid-template-columns: repeat(5,auto); 52 | } 53 | .grid-cols-6-auto{ 54 | grid-template-columns: repeat(6,auto); 55 | } 56 | .grid-cols-7-auto{ 57 | grid-template-columns: repeat(7,auto); 58 | } 59 | .grid-cols-8-auto{ 60 | grid-template-columns: repeat(8,auto); 61 | } 62 | .grid-cols-9-auto{ 63 | grid-template-columns: repeat(9,auto); 64 | } 65 | .grid-cols-10-auto{ 66 | grid-template-columns: repeat(10,auto); 67 | } 68 | 69 | 70 | /*ROWS*/ 71 | .grid-rows-1{ 72 | grid-template-rows: 1fr; 73 | } 74 | .grid-rows-2{ 75 | grid-template-rows: repeat(2,1fr); 76 | } 77 | .grid-rows-3{ 78 | grid-template-rows: repeat(3,1fr); 79 | } 80 | .grid-rows-4{ 81 | grid-template-rows: repeat(4,1fr); 82 | } 83 | .grid-rows-5{ 84 | grid-template-rows: repeat(5,1fr); 85 | } 86 | .grid-rows-6{ 87 | grid-template-rows: repeat(6,1fr); 88 | } 89 | .grid-rows-7{ 90 | grid-template-rows: repeat(7,1fr); 91 | } 92 | .grid-rows-8{ 93 | grid-template-rows: repeat(8,1fr); 94 | } 95 | .grid-rows-9{ 96 | grid-template-rows: repeat(9,1fr); 97 | } 98 | .grid-rows-10{ 99 | grid-template-rows: repeat(10,1fr); 100 | } 101 | 102 | /*ROWS AUTO*/ 103 | .grid-rows-1-auto{ 104 | grid-template-rows: auto; 105 | } 106 | .grid-rows-2-auto{ 107 | grid-template-rows: repeat(2,auto); 108 | } 109 | .grid-rows-3-auto{ 110 | grid-template-rows: repeat(3,auto); 111 | } 112 | .grid-rows-4-auto{ 113 | grid-template-rows: repeat(4,auto); 114 | } 115 | .grid-rows-5-auto{ 116 | grid-template-rows: repeat(5,auto); 117 | } 118 | .grid-rows-6-auto{ 119 | grid-template-rows: repeat(6,auto); 120 | } 121 | .grid-rows-7-auto{ 122 | grid-template-rows: repeat(7,auto); 123 | } 124 | .grid-rows-8-auto{ 125 | grid-template-rows: repeat(8,auto); 126 | } 127 | .grid-rows-9-auto{ 128 | grid-template-rows: repeat(9,auto); 129 | } 130 | .grid-rows-10-auto{ 131 | grid-template-rows: repeat(10,auto); 132 | } 133 | 134 | 135 | /*COL GAP*/ 136 | .grid-col-gap-1{ 137 | column-gap: 1rem; 138 | } 139 | .grid-col-gap-2{ 140 | column-gap: 2rem; 141 | } 142 | .grid-col-gap-3{ 143 | column-gap: 3rem; 144 | } 145 | .grid-col-gap-4{ 146 | column-gap: 4rem; 147 | } 148 | .grid-col-gap-5{ 149 | column-gap: 5rem; 150 | } 151 | .grid-col-gap-6{ 152 | column-gap: 6rem; 153 | } 154 | .grid-col-gap-7{ 155 | column-gap: 7rem; 156 | } 157 | .grid-col-gap-8{ 158 | column-gap: 8rem; 159 | } 160 | .grid-col-gap-9{ 161 | column-gap: 9rem; 162 | } 163 | .grid-col-gap-10{ 164 | column-gap: 10rem; 165 | } 166 | 167 | /*ROW GAP*/ 168 | .grid-row-gap-1{ 169 | row-gap: 1rem; 170 | } 171 | .grid-row-gap-2{ 172 | row-gap: 2rem; 173 | } 174 | .grid-row-gap-3{ 175 | row-gap: 3rem; 176 | } 177 | .grid-row-gap-4{ 178 | row-gap: 4rem; 179 | } 180 | .grid-row-gap-5{ 181 | row-gap: 5rem; 182 | } 183 | .grid-row-gap-6{ 184 | row-gap: 6rem; 185 | } 186 | .grid-col-gap-7{ 187 | row-gap: 7rem; 188 | } 189 | .grid-row-gap-8{ 190 | row-gap: 8rem; 191 | } 192 | .grid-row-gap-9{ 193 | row-gap: 9rem; 194 | } 195 | .grid-row-gap-10{ 196 | row-gap: 10rem; 197 | } 198 | 199 | .grid-x-center{ 200 | display: grid; 201 | justify-self: center; 202 | justify-items: center; 203 | justify-content: center; 204 | } 205 | .grid-x-start{ 206 | display: grid; 207 | justify-self: left; 208 | justify-items: left; 209 | justify-content: left; 210 | } 211 | .grid-x-end{ 212 | display: grid; 213 | justify-self: right; 214 | justify-items: right; 215 | justify-content: right; 216 | } 217 | .grid-y-center{ 218 | display: grid; 219 | align-self: center; 220 | align-items: center; 221 | align-content: center; 222 | } 223 | .grid-y-start{ 224 | display: grid; 225 | align-self: start; 226 | align-items: start; 227 | align-content: start; 228 | } 229 | .grid-y-end{ 230 | display: grid; 231 | align-self: end; 232 | align-items: end; 233 | align-content: end; 234 | } -------------------------------------------------------------------------------- /src/lib/style/margin.scss: -------------------------------------------------------------------------------- 1 | .m-0{ 2 | margin: 0; 3 | } 4 | .m-1{ 5 | margin: 1rem; 6 | } 7 | .m-2{ 8 | margin: 2rem; 9 | } 10 | .m-3{ 11 | margin: 3rem; 12 | } 13 | .m-4{ 14 | margin: 4rem; 15 | } 16 | .m-5{ 17 | margin: 5rem; 18 | } 19 | .m-6{ 20 | margin: 6rem; 21 | } 22 | .m-7{ 23 | margin: 7rem; 24 | } 25 | .m-8{ 26 | margin: 8rem; 27 | } 28 | .m-9{ 29 | margin: 9rem; 30 | } 31 | .m-10{ 32 | margin: 10rem; 33 | } 34 | .m-11{ 35 | margin: 12rem; 36 | } 37 | .m-12{ 38 | margin: 12rem; 39 | } 40 | 41 | /*LEFT*/ 42 | .ml-0{ 43 | margin-left: 0; 44 | } 45 | .ml-1{ 46 | margin-left: 1rem; 47 | } 48 | .ml-2{ 49 | margin-left: 2rem; 50 | } 51 | .ml-3{ 52 | margin-left: 3rem; 53 | } 54 | .ml-4{ 55 | margin-left: 4rem; 56 | } 57 | .ml-5{ 58 | margin-left: 5rem; 59 | } 60 | .ml-6{ 61 | margin-left: 6rem; 62 | } 63 | .ml-7{ 64 | margin-left: 7rem; 65 | } 66 | .ml-8{ 67 | margin-left: 8rem; 68 | } 69 | .ml-9{ 70 | margin-left: 9rem; 71 | } 72 | .ml-10{ 73 | margin-left: 10rem; 74 | } 75 | .ml-11{ 76 | margin-left: 11rem; 77 | } 78 | .ml-12{ 79 | margin-left: 12rem; 80 | } 81 | 82 | /*RIGHT*/ 83 | .mr-0{ 84 | margin-right: 0; 85 | } 86 | .mr-1{ 87 | margin-right: 1rem; 88 | } 89 | .mr-2{ 90 | margin-right: 2rem; 91 | } 92 | .mr-3{ 93 | margin-right: 3rem; 94 | } 95 | .mr-4{ 96 | margin-right: 4rem; 97 | } 98 | .mr-5{ 99 | margin-right: 5rem; 100 | } 101 | .mr-6{ 102 | margin-right: 6rem; 103 | } 104 | .mr-7{ 105 | margin-right: 7rem; 106 | } 107 | .mr-8{ 108 | margin-right: 8rem; 109 | } 110 | .mr-9{ 111 | margin-right: 9rem; 112 | } 113 | .mr-10{ 114 | margin-right: 10rem; 115 | } 116 | .mr-11{ 117 | margin-right: 11rem; 118 | } 119 | .mr-12{ 120 | margin-right: 12rem; 121 | } 122 | 123 | /*TOP*/ 124 | .mt-0{ 125 | margin-top: 0; 126 | } 127 | .mt-1{ 128 | margin-top: 1rem; 129 | } 130 | .mt-2{ 131 | margin-top: 2rem; 132 | } 133 | .mt-3{ 134 | margin-top: 3rem; 135 | } 136 | .mt-4{ 137 | margin-top: 4rem; 138 | } 139 | .mt-5{ 140 | margin-top: 5rem; 141 | } 142 | .mt-6{ 143 | margin-top: 6rem; 144 | } 145 | .mt-7{ 146 | margin-top: 7rem; 147 | } 148 | .mt-8{ 149 | margin-top: 8rem; 150 | } 151 | .mt-9{ 152 | margin-top: 9rem; 153 | } 154 | .mt-10{ 155 | margin-top: 10rem; 156 | } 157 | .mt-11{ 158 | margin-top: 11rem; 159 | } 160 | .mt-12{ 161 | margin-top: 12rem; 162 | } 163 | 164 | /*Bottom*/ 165 | .mb-0{ 166 | margin-bottom: 0; 167 | } 168 | .mb-1{ 169 | margin-bottom: 1rem; 170 | } 171 | .mb-2{ 172 | margin-bottom: 2rem; 173 | } 174 | .mb-3{ 175 | margin-bottom: 3rem; 176 | } 177 | .mb-4{ 178 | margin-bottom: 4rem; 179 | } 180 | .mb-5{ 181 | margin-bottom: 5rem; 182 | } 183 | .mb-6{ 184 | margin-bottom: 6rem; 185 | } 186 | .mb-7{ 187 | margin-bottom: 7rem; 188 | } 189 | .mb-8{ 190 | margin-bottom: 8rem; 191 | } 192 | .mb-9{ 193 | margin-bottom: 9rem; 194 | } 195 | .mb-10{ 196 | margin-bottom: 10rem; 197 | } 198 | .mb-11{ 199 | margin-bottom: 11rem; 200 | } 201 | .mb-12{ 202 | margin-bottom: 12rem; 203 | } -------------------------------------------------------------------------------- /src/lib/style/overwrite-platform-defaults.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | html, body { 4 | height: 100%; 5 | } 6 | 7 | html{ 8 | overscroll-behavior: none; 9 | } 10 | 11 | * { 12 | -webkit-touch-callout: none; /* iOS Safari */ 13 | -webkit-user-select: none; /* Safari */ 14 | -khtml-user-select: none; /* Konqueror HTML */ 15 | -moz-user-select: none; /* Old versions of Firefox */ 16 | -ms-user-select: none; /* Internet Explorer/Edge */ 17 | user-select: none; /* Non-prefixed version, currently 18 | supported by Chrome, Edge, Opera and Firefox */ 19 | } 20 | .selection{ 21 | -webkit-touch-callout: text; /* iOS Safari */ 22 | -webkit-user-select: text; /* Safari */ 23 | -khtml-user-select: text; /* Konqueror HTML */ 24 | -moz-user-select: text; /* Old versions of Firefox */ 25 | -ms-user-select: text; /* Internet Explorer/Edge */ 26 | user-select: text; /* Non-prefixed version, currently 27 | supported by Chrome, Edge, Opera and Firefox */ 28 | } 29 | 30 | *:focus { 31 | outline: none; 32 | } 33 | 34 | /* Change the white to any color ;) */ 35 | input:-webkit-autofill, 36 | input:-webkit-autofill:hover, 37 | input:-webkit-autofill:focus, 38 | input:-webkit-autofill:active { 39 | -webkit-box-shadow: 0 0 0 30px white inset !important; 40 | } 41 | 42 | /*Change text in autofill textbox*/ 43 | input:-webkit-autofill { 44 | -webkit-text-fill-color: var(--text-color) !important; 45 | } -------------------------------------------------------------------------------- /src/lib/style/padding.scss: -------------------------------------------------------------------------------- 1 | 2 | .p-0{ 3 | padding: 0; 4 | } 5 | .p-1{ 6 | padding: 1rem; 7 | } 8 | .p-2{ 9 | padding: 2rem; 10 | } 11 | .p-3{ 12 | padding: 3rem; 13 | } 14 | .p-4{ 15 | padding: 4rem; 16 | } 17 | .p-5{ 18 | padding: 5rem; 19 | } 20 | .p-6{ 21 | padding: 6rem; 22 | } 23 | .p-7{ 24 | padding: 7rem; 25 | } 26 | .p-8{ 27 | padding: 8rem; 28 | } 29 | .p-9{ 30 | padding: 9rem; 31 | } 32 | .p-10{ 33 | padding: 10rem; 34 | } 35 | .p-11{ 36 | padding: 11rem; 37 | } 38 | .p-12{ 39 | padding: 12rem; 40 | } 41 | 42 | /*LEFT*/ 43 | .pl-0{ 44 | padding-left: 0; 45 | } 46 | .pl-1{ 47 | padding-left: 1rem; 48 | } 49 | .pl-2{ 50 | padding-left: 2rem; 51 | } 52 | .pl-3{ 53 | padding-left: 3rem; 54 | } 55 | .pl-4{ 56 | padding-left: 4rem; 57 | } 58 | .pl-5{ 59 | padding-left: 5rem; 60 | } 61 | .pl-6{ 62 | padding-left: 6rem; 63 | } 64 | .pl-7{ 65 | padding-left: 7rem; 66 | } 67 | .pl-8{ 68 | padding-left: 8rem; 69 | } 70 | .pl-9{ 71 | padding-left: 9rem; 72 | } 73 | .pl-10{ 74 | padding-left: 10rem; 75 | } 76 | .pl-11{ 77 | padding-left: 11rem; 78 | } 79 | .pl-12{ 80 | padding-left: 12rem; 81 | } 82 | 83 | /*RIGHT*/ 84 | .pr-0{ 85 | padding-right: 0; 86 | } 87 | .pr-1{ 88 | padding-right: 1rem; 89 | } 90 | .pr-2{ 91 | padding-right: 2rem; 92 | } 93 | .pr-3{ 94 | padding-right: 3rem; 95 | } 96 | .pr-4{ 97 | padding-right: 4rem; 98 | } 99 | .pr-5{ 100 | padding-right: 5rem; 101 | } 102 | .pr-6{ 103 | padding-right: 6rem; 104 | } 105 | .pr-7{ 106 | padding-right: 7rem; 107 | } 108 | .pr-8{ 109 | padding-right: 8rem; 110 | } 111 | .pr-9{ 112 | padding-right: 9rem; 113 | } 114 | .pr-10{ 115 | padding-right: 10rem; 116 | } 117 | .pr-11{ 118 | padding-right: 11rem; 119 | } 120 | .pr-12{ 121 | padding-right: 12rem; 122 | } 123 | 124 | /*TOP*/ 125 | .pt-0{ 126 | padding-top: 0; 127 | } 128 | .pt-1{ 129 | padding-top: 1rem; 130 | } 131 | .pt-2{ 132 | padding-top: 2rem; 133 | } 134 | .pt-3{ 135 | padding-top: 3rem; 136 | } 137 | .pt-4{ 138 | padding-top: 4rem; 139 | } 140 | .pt-5{ 141 | padding-top: 5rem; 142 | } 143 | .pt-6{ 144 | padding-top: 6rem; 145 | } 146 | .pt-7{ 147 | padding-top: 7rem; 148 | } 149 | .pt-8{ 150 | padding-top: 8rem; 151 | } 152 | .pt-9{ 153 | padding-top: 9rem; 154 | } 155 | .pt-10{ 156 | padding-top: 10rem; 157 | } 158 | .pt-11{ 159 | padding-top: 11rem; 160 | } 161 | .pt-12{ 162 | padding-top: 12rem; 163 | } 164 | 165 | /*Bottom*/ 166 | .pb-0{ 167 | padding-bottom: 0; 168 | } 169 | .pb-1{ 170 | padding-bottom: 1rem; 171 | } 172 | .pb-2{ 173 | padding-bottom: 2rem; 174 | } 175 | .pb-3{ 176 | padding-bottom: 3rem; 177 | } 178 | .pb-4{ 179 | padding-bottom: 4rem; 180 | } 181 | .pb-5{ 182 | padding-bottom: 5rem; 183 | } 184 | .pb-6{ 185 | padding-bottom: 6rem; 186 | } 187 | .pb-7{ 188 | padding-bottom: 7rem; 189 | } 190 | .pb-8{ 191 | padding-bottom: 8rem; 192 | } 193 | .pb-9{ 194 | padding-bottom: 9rem; 195 | } 196 | .pb-10{ 197 | padding-bottom: 10rem; 198 | } 199 | .pb-11{ 200 | padding-bottom: 11rem; 201 | } 202 | .pb-12{ 203 | padding-bottom: 12rem; 204 | } -------------------------------------------------------------------------------- /src/lib/style/pallete/generic/colors.scss: -------------------------------------------------------------------------------- 1 | @use '../tools/colors'; 2 | @use '../variables' as *; 3 | 4 | @each $color, $color_values in colors.$colors { 5 | @if $color != 'shades' { 6 | @each $color_variant, $value in $color_values { 7 | @if $color_variant == 'base' { 8 | .#{$color} { 9 | background-color: $value !important; 10 | border-color: $value !important; 11 | } 12 | .#{$color}-text { 13 | color: $value !important; 14 | caret-color: $value !important; 15 | } 16 | } 17 | .#{$color}.#{$color_variant} { 18 | background-color: $value !important; 19 | border-color: $value !important; 20 | } 21 | .#{$color}-text.text-#{$color_variant} { 22 | color: $value !important; 23 | caret-color: $value !important; 24 | } 25 | } 26 | } @else { 27 | @each $shade, $value in $color_values { 28 | .#{$shade} { 29 | background-color: $value !important; 30 | border-color: $value !important; 31 | } 32 | .#{$shade}-text { 33 | color: $value !important; 34 | caret-color: $value !important; 35 | } 36 | } 37 | } 38 | } 39 | 40 | @each $color, 41 | $value 42 | in ( 43 | 'primary': $primary-color, 44 | 'secondary': $secondary-color, 45 | 'success': $success-color, 46 | 'info': $info-color, 47 | 'warning': $warning-color, 48 | 'error': $error-color 49 | ) 50 | { 51 | .#{$color}-color { 52 | background-color: $value !important; 53 | border-color: $value !important; 54 | } 55 | .#{$color}-text { 56 | color: $value !important; 57 | caret-color: $value !important; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/lib/style/pallete/tools/colors.scss: -------------------------------------------------------------------------------- 1 | // From: https://raw.githubusercontent.com/Dogfalo/materialize/v1-dev/sass/components/_color-variables.scss 2 | // Google Color Palette defined: http://www.google.com/design/spec/style/color.html 3 | 4 | $colors: ( 5 | 'red': ( 6 | 'base': #f44336, 7 | 'lighten-5': #ffebee, 8 | 'lighten-4': #ffcdd2, 9 | 'lighten-3': #ef9a9a, 10 | 'lighten-2': #e57373, 11 | 'lighten-1': #ef5350, 12 | 'darken-1': #e53935, 13 | 'darken-2': #d32f2f, 14 | 'darken-3': #c62828, 15 | 'darken-4': #b71c1c, 16 | 'accent-1': #ff8a80, 17 | 'accent-2': #ff5252, 18 | 'accent-3': #ff1744, 19 | 'accent-4': #d50000, 20 | ), 21 | 'pink': ( 22 | 'base': #e91e63, 23 | 'lighten-5': #fce4ec, 24 | 'lighten-4': #f8bbd0, 25 | 'lighten-3': #f48fb1, 26 | 'lighten-2': #f06292, 27 | 'lighten-1': #ec407a, 28 | 'darken-1': #d81b60, 29 | 'darken-2': #c2185b, 30 | 'darken-3': #ad1457, 31 | 'darken-4': #880e4f, 32 | 'accent-1': #ff80ab, 33 | 'accent-2': #ff4081, 34 | 'accent-3': #f50057, 35 | 'accent-4': #c51162, 36 | ), 37 | 'purple': ( 38 | 'base': #9c27b0, 39 | 'lighten-5': #f3e5f5, 40 | 'lighten-4': #e1bee7, 41 | 'lighten-3': #ce93d8, 42 | 'lighten-2': #ba68c8, 43 | 'lighten-1': #ab47bc, 44 | 'darken-1': #8e24aa, 45 | 'darken-2': #7b1fa2, 46 | 'darken-3': #6a1b9a, 47 | 'darken-4': #4a148c, 48 | 'accent-1': #ea80fc, 49 | 'accent-2': #e040fb, 50 | 'accent-3': #d500f9, 51 | 'accent-4': #aa00ff, 52 | ), 53 | 'deep-purple': ( 54 | 'base': #673ab7, 55 | 'lighten-5': #ede7f6, 56 | 'lighten-4': #d1c4e9, 57 | 'lighten-3': #b39ddb, 58 | 'lighten-2': #9575cd, 59 | 'lighten-1': #7e57c2, 60 | 'darken-1': #5e35b1, 61 | 'darken-2': #512da8, 62 | 'darken-3': #4527a0, 63 | 'darken-4': #311b92, 64 | 'accent-1': #b388ff, 65 | 'accent-2': #7c4dff, 66 | 'accent-3': #651fff, 67 | 'accent-4': #6200ea, 68 | ), 69 | 'indigo': ( 70 | 'base': #3f51b5, 71 | 'lighten-5': #e8eaf6, 72 | 'lighten-4': #c5cae9, 73 | 'lighten-3': #9fa8da, 74 | 'lighten-2': #7986cb, 75 | 'lighten-1': #5c6bc0, 76 | 'darken-1': #3949ab, 77 | 'darken-2': #303f9f, 78 | 'darken-3': #283593, 79 | 'darken-4': #1a237e, 80 | 'accent-1': #8c9eff, 81 | 'accent-2': #536dfe, 82 | 'accent-3': #3d5afe, 83 | 'accent-4': #304ffe, 84 | ), 85 | 'blue': ( 86 | 'base': #2196f3, 87 | 'lighten-5': #e3f2fd, 88 | 'lighten-4': #bbdefb, 89 | 'lighten-3': #90caf9, 90 | 'lighten-2': #64b5f6, 91 | 'lighten-1': #42a5f5, 92 | 'darken-1': #1e88e5, 93 | 'darken-2': #1976d2, 94 | 'darken-3': #1565c0, 95 | 'darken-4': #0d47a1, 96 | 'accent-1': #82b1ff, 97 | 'accent-2': #448aff, 98 | 'accent-3': #2979ff, 99 | 'accent-4': #2962ff, 100 | ), 101 | 'light-blue': ( 102 | 'base': #03a9f4, 103 | 'lighten-5': #e1f5fe, 104 | 'lighten-4': #b3e5fc, 105 | 'lighten-3': #81d4fa, 106 | 'lighten-2': #4fc3f7, 107 | 'lighten-1': #29b6f6, 108 | 'darken-1': #039be5, 109 | 'darken-2': #0288d1, 110 | 'darken-3': #0277bd, 111 | 'darken-4': #01579b, 112 | 'accent-1': #80d8ff, 113 | 'accent-2': #40c4ff, 114 | 'accent-3': #00b0ff, 115 | 'accent-4': #0091ea, 116 | ), 117 | 'cyan': ( 118 | 'base': #00bcd4, 119 | 'lighten-5': #e0f7fa, 120 | 'lighten-4': #b2ebf2, 121 | 'lighten-3': #80deea, 122 | 'lighten-2': #4dd0e1, 123 | 'lighten-1': #26c6da, 124 | 'darken-1': #00acc1, 125 | 'darken-2': #0097a7, 126 | 'darken-3': #00838f, 127 | 'darken-4': #006064, 128 | 'accent-1': #84ffff, 129 | 'accent-2': #18ffff, 130 | 'accent-3': #00e5ff, 131 | 'accent-4': #00b8d4, 132 | ), 133 | 'teal': ( 134 | 'base': #009688, 135 | 'lighten-5': #e0f2f1, 136 | 'lighten-4': #b2dfdb, 137 | 'lighten-3': #80cbc4, 138 | 'lighten-2': #4db6ac, 139 | 'lighten-1': #26a69a, 140 | 'darken-1': #00897b, 141 | 'darken-2': #00796b, 142 | 'darken-3': #00695c, 143 | 'darken-4': #004d40, 144 | 'accent-1': #a7ffeb, 145 | 'accent-2': #64ffda, 146 | 'accent-3': #1de9b6, 147 | 'accent-4': #00bfa5, 148 | ), 149 | 'green': ( 150 | 'base': #4caf50, 151 | 'lighten-5': #e8f5e9, 152 | 'lighten-4': #c8e6c9, 153 | 'lighten-3': #a5d6a7, 154 | 'lighten-2': #81c784, 155 | 'lighten-1': #66bb6a, 156 | 'darken-1': #43a047, 157 | 'darken-2': #388e3c, 158 | 'darken-3': #2e7d32, 159 | 'darken-4': #1b5e20, 160 | 'accent-1': #b9f6ca, 161 | 'accent-2': #69f0ae, 162 | 'accent-3': #00e676, 163 | 'accent-4': #00c853, 164 | ), 165 | 'light-green': ( 166 | 'base': #8bc34a, 167 | 'lighten-5': #f1f8e9, 168 | 'lighten-4': #dcedc8, 169 | 'lighten-3': #c5e1a5, 170 | 'lighten-2': #aed581, 171 | 'lighten-1': #9ccc65, 172 | 'darken-1': #7cb342, 173 | 'darken-2': #689f38, 174 | 'darken-3': #558b2f, 175 | 'darken-4': #33691e, 176 | 'accent-1': #ccff90, 177 | 'accent-2': #b2ff59, 178 | 'accent-3': #76ff03, 179 | 'accent-4': #64dd17, 180 | ), 181 | 'lime': ( 182 | 'base': #cddc39, 183 | 'lighten-5': #f9fbe7, 184 | 'lighten-4': #f0f4c3, 185 | 'lighten-3': #e6ee9c, 186 | 'lighten-2': #dce775, 187 | 'lighten-1': #d4e157, 188 | 'darken-1': #c0ca33, 189 | 'darken-2': #afb42b, 190 | 'darken-3': #9e9d24, 191 | 'darken-4': #827717, 192 | 'accent-1': #f4ff81, 193 | 'accent-2': #eeff41, 194 | 'accent-3': #c6ff00, 195 | 'accent-4': #aeea00, 196 | ), 197 | 'yellow': ( 198 | 'base': #ffeb3b, 199 | 'lighten-5': #fffde7, 200 | 'lighten-4': #fff9c4, 201 | 'lighten-3': #fff59d, 202 | 'lighten-2': #fff176, 203 | 'lighten-1': #ffee58, 204 | 'darken-1': #fdd835, 205 | 'darken-2': #fbc02d, 206 | 'darken-3': #f9a825, 207 | 'darken-4': #f57f17, 208 | 'accent-1': #ffff8d, 209 | 'accent-2': #ffff00, 210 | 'accent-3': #ffea00, 211 | 'accent-4': #ffd600, 212 | ), 213 | 'amber': ( 214 | 'base': #ffc107, 215 | 'lighten-5': #fff8e1, 216 | 'lighten-4': #ffecb3, 217 | 'lighten-3': #ffe082, 218 | 'lighten-2': #ffd54f, 219 | 'lighten-1': #ffca28, 220 | 'darken-1': #ffb300, 221 | 'darken-2': #ffa000, 222 | 'darken-3': #ff8f00, 223 | 'darken-4': #ff6f00, 224 | 'accent-1': #ffe57f, 225 | 'accent-2': #ffd740, 226 | 'accent-3': #ffc400, 227 | 'accent-4': #ffab00, 228 | ), 229 | 'orange': ( 230 | 'base': #ff9800, 231 | 'lighten-5': #fff3e0, 232 | 'lighten-4': #ffe0b2, 233 | 'lighten-3': #ffcc80, 234 | 'lighten-2': #ffb74d, 235 | 'lighten-1': #ffa726, 236 | 'darken-1': #fb8c00, 237 | 'darken-2': #f57c00, 238 | 'darken-3': #ef6c00, 239 | 'darken-4': #e65100, 240 | 'accent-1': #ffd180, 241 | 'accent-2': #ffab40, 242 | 'accent-3': #ff9100, 243 | 'accent-4': #ff6d00, 244 | ), 245 | 'deep-orange': ( 246 | 'base': #ff5722, 247 | 'lighten-5': #fbe9e7, 248 | 'lighten-4': #ffccbc, 249 | 'lighten-3': #ffab91, 250 | 'lighten-2': #ff8a65, 251 | 'lighten-1': #ff7043, 252 | 'darken-1': #f4511e, 253 | 'darken-2': #e64a19, 254 | 'darken-3': #d84315, 255 | 'darken-4': #bf360c, 256 | 'accent-1': #ff9e80, 257 | 'accent-2': #ff6e40, 258 | 'accent-3': #ff3d00, 259 | 'accent-4': #dd2c00, 260 | ), 261 | 'brown': ( 262 | 'base': #795548, 263 | 'lighten-5': #efebe9, 264 | 'lighten-4': #d7ccc8, 265 | 'lighten-3': #bcaaa4, 266 | 'lighten-2': #a1887f, 267 | 'lighten-1': #8d6e63, 268 | 'darken-1': #6d4c41, 269 | 'darken-2': #5d4037, 270 | 'darken-3': #4e342e, 271 | 'darken-4': #3e2723, 272 | ), 273 | 'blue-grey': ( 274 | 'base': #607d8b, 275 | 'lighten-5': #eceff1, 276 | 'lighten-4': #cfd8dc, 277 | 'lighten-3': #b0bec5, 278 | 'lighten-2': #90a4ae, 279 | 'lighten-1': #78909c, 280 | 'darken-1': #546e7a, 281 | 'darken-2': #455a64, 282 | 'darken-3': #37474f, 283 | 'darken-4': #263238, 284 | ), 285 | 'grey': ( 286 | 'base': #9e9e9e, 287 | 'lighten-5': #fafafa, 288 | 'lighten-4': #f5f5f5, 289 | 'lighten-3': #eeeeee, 290 | 'lighten-2': #e0e0e0, 291 | 'lighten-1': #bdbdbd, 292 | 'darken-1': #757575, 293 | 'darken-2': #616161, 294 | 'darken-3': #424242, 295 | 'darken-4': #212121, 296 | ), 297 | 'shades': ( 298 | 'black': #000000, 299 | 'white': #ffffff, 300 | 'transparent': transparent, 301 | ), 302 | ) !default; 303 | 304 | // usage: material-color("name_of_color", "type_of_color") 305 | // to avoid to repeating map-get($colors, ...) 306 | 307 | @function material-color($color, $type) { 308 | @if map-has-key($colors, $color) { 309 | $curr_color: map-get($colors, $color); 310 | @if map-has-key($curr_color, $type) { 311 | @return map-get($curr_color, $type); 312 | } 313 | } 314 | @warn 'Unknown `#{$color}` - `#{$type}` in $colors.'; 315 | @return null; 316 | } 317 | 318 | @mixin has-theme-bg { 319 | &.primary-color, 320 | &.secondary-color, 321 | &.success-color, 322 | &.error-color, 323 | &.warning-color, 324 | &.info-color { 325 | @content; 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /src/lib/style/pallete/tools/elevation.scss: -------------------------------------------------------------------------------- 1 | // Adapted from: https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/styles/settings/_elevations.scss 2 | $_shadow-key-umbra-opacity: rgba(0, 0, 0, 0.2) !default; 3 | $_shadow-key-penumbra-opacity: rgba(0, 0, 0, 0.14) !default; 4 | $_shadow-key-ambient-opacity: rgba(0, 0, 0, 0.12) !default; 5 | 6 | $_shadow-key-umbra: ( 7 | 0: ( 8 | 0 0 0 0 $_shadow-key-umbra-opacity, 9 | ), 10 | 1: ( 11 | 0 2px 1px -1px $_shadow-key-umbra-opacity, 12 | ), 13 | 2: ( 14 | 0 3px 1px -2px $_shadow-key-umbra-opacity, 15 | ), 16 | 3: ( 17 | 0 3px 3px -2px $_shadow-key-umbra-opacity, 18 | ), 19 | 4: ( 20 | 0 2px 4px -1px $_shadow-key-umbra-opacity, 21 | ), 22 | 5: ( 23 | 0 3px 5px -1px $_shadow-key-umbra-opacity, 24 | ), 25 | 6: ( 26 | 0 3px 5px -1px $_shadow-key-umbra-opacity, 27 | ), 28 | 7: ( 29 | 0 4px 5px -2px $_shadow-key-umbra-opacity, 30 | ), 31 | 8: ( 32 | 0 5px 5px -3px $_shadow-key-umbra-opacity, 33 | ), 34 | 9: ( 35 | 0 5px 6px -3px $_shadow-key-umbra-opacity, 36 | ), 37 | 10: ( 38 | 0 6px 6px -3px $_shadow-key-umbra-opacity, 39 | ), 40 | 11: ( 41 | 0 6px 7px -4px $_shadow-key-umbra-opacity, 42 | ), 43 | 12: ( 44 | 0 7px 8px -4px $_shadow-key-umbra-opacity, 45 | ), 46 | 13: ( 47 | 0 7px 8px -4px $_shadow-key-umbra-opacity, 48 | ), 49 | 14: ( 50 | 0 7px 9px -4px $_shadow-key-umbra-opacity, 51 | ), 52 | 15: ( 53 | 0 8px 9px -5px $_shadow-key-umbra-opacity, 54 | ), 55 | 16: ( 56 | 0 8px 10px -5px $_shadow-key-umbra-opacity, 57 | ), 58 | 17: ( 59 | 0 8px 11px -5px $_shadow-key-umbra-opacity, 60 | ), 61 | 18: ( 62 | 0 9px 11px -5px $_shadow-key-umbra-opacity, 63 | ), 64 | 19: ( 65 | 0 9px 12px -6px $_shadow-key-umbra-opacity, 66 | ), 67 | 20: ( 68 | 0 10px 13px -6px $_shadow-key-umbra-opacity, 69 | ), 70 | 21: ( 71 | 0 10px 13px -6px $_shadow-key-umbra-opacity, 72 | ), 73 | 22: ( 74 | 0 10px 14px -6px $_shadow-key-umbra-opacity, 75 | ), 76 | 23: ( 77 | 0 11px 14px -7px $_shadow-key-umbra-opacity, 78 | ), 79 | 24: ( 80 | 0 11px 15px -7px $_shadow-key-umbra-opacity, 81 | ), 82 | ); 83 | 84 | $_shadow-key-penumbra: ( 85 | 0: ( 86 | 0 0 0 0 $_shadow-key-penumbra-opacity, 87 | ), 88 | 1: ( 89 | 0 1px 1px 0 $_shadow-key-penumbra-opacity, 90 | ), 91 | 2: ( 92 | 0 2px 2px 0 $_shadow-key-penumbra-opacity, 93 | ), 94 | 3: ( 95 | 0 3px 4px 0 $_shadow-key-penumbra-opacity, 96 | ), 97 | 4: ( 98 | 0 4px 5px 0 $_shadow-key-penumbra-opacity, 99 | ), 100 | 5: ( 101 | 0 5px 8px 0 $_shadow-key-penumbra-opacity, 102 | ), 103 | 6: ( 104 | 0 6px 10px 0 $_shadow-key-penumbra-opacity, 105 | ), 106 | 7: ( 107 | 0 7px 10px 1px $_shadow-key-penumbra-opacity, 108 | ), 109 | 8: ( 110 | 0 8px 10px 1px $_shadow-key-penumbra-opacity, 111 | ), 112 | 9: ( 113 | 0 9px 12px 1px $_shadow-key-penumbra-opacity, 114 | ), 115 | 10: ( 116 | 0 10px 14px 1px $_shadow-key-penumbra-opacity, 117 | ), 118 | 11: ( 119 | 0 11px 15px 1px $_shadow-key-penumbra-opacity, 120 | ), 121 | 12: ( 122 | 0 12px 17px 2px $_shadow-key-penumbra-opacity, 123 | ), 124 | 13: ( 125 | 0 13px 19px 2px $_shadow-key-penumbra-opacity, 126 | ), 127 | 14: ( 128 | 0 14px 21px 2px $_shadow-key-penumbra-opacity, 129 | ), 130 | 15: ( 131 | 0 15px 22px 2px $_shadow-key-penumbra-opacity, 132 | ), 133 | 16: ( 134 | 0 16px 24px 2px $_shadow-key-penumbra-opacity, 135 | ), 136 | 17: ( 137 | 0 17px 26px 2px $_shadow-key-penumbra-opacity, 138 | ), 139 | 18: ( 140 | 0 18px 28px 2px $_shadow-key-penumbra-opacity, 141 | ), 142 | 19: ( 143 | 0 19px 29px 2px $_shadow-key-penumbra-opacity, 144 | ), 145 | 20: ( 146 | 0 20px 31px 3px $_shadow-key-penumbra-opacity, 147 | ), 148 | 21: ( 149 | 0 21px 33px 3px $_shadow-key-penumbra-opacity, 150 | ), 151 | 22: ( 152 | 0 22px 35px 3px $_shadow-key-penumbra-opacity, 153 | ), 154 | 23: ( 155 | 0 23px 36px 3px $_shadow-key-penumbra-opacity, 156 | ), 157 | 24: ( 158 | 0 24px 38px 3px $_shadow-key-penumbra-opacity, 159 | ), 160 | ); 161 | 162 | $_shadow-key-ambient: ( 163 | 0: ( 164 | 0 0 0 0 $_shadow-key-ambient-opacity, 165 | ), 166 | 1: ( 167 | 0 1px 3px 0 $_shadow-key-ambient-opacity, 168 | ), 169 | 2: ( 170 | 0 1px 5px 0 $_shadow-key-ambient-opacity, 171 | ), 172 | 3: ( 173 | 0 1px 8px 0 $_shadow-key-ambient-opacity, 174 | ), 175 | 4: ( 176 | 0 1px 10px 0 $_shadow-key-ambient-opacity, 177 | ), 178 | 5: ( 179 | 0 1px 14px 0 $_shadow-key-ambient-opacity, 180 | ), 181 | 6: ( 182 | 0 1px 18px 0 $_shadow-key-ambient-opacity, 183 | ), 184 | 7: ( 185 | 0 2px 16px 1px $_shadow-key-ambient-opacity, 186 | ), 187 | 8: ( 188 | 0 3px 14px 2px $_shadow-key-ambient-opacity, 189 | ), 190 | 9: ( 191 | 0 3px 16px 2px $_shadow-key-ambient-opacity, 192 | ), 193 | 10: ( 194 | 0 4px 18px 3px $_shadow-key-ambient-opacity, 195 | ), 196 | 11: ( 197 | 0 4px 20px 3px $_shadow-key-ambient-opacity, 198 | ), 199 | 12: ( 200 | 0 5px 22px 4px $_shadow-key-ambient-opacity, 201 | ), 202 | 13: ( 203 | 0 5px 24px 4px $_shadow-key-ambient-opacity, 204 | ), 205 | 14: ( 206 | 0 5px 26px 4px $_shadow-key-ambient-opacity, 207 | ), 208 | 15: ( 209 | 0 6px 28px 5px $_shadow-key-ambient-opacity, 210 | ), 211 | 16: ( 212 | 0 6px 30px 5px $_shadow-key-ambient-opacity, 213 | ), 214 | 17: ( 215 | 0 6px 32px 5px $_shadow-key-ambient-opacity, 216 | ), 217 | 18: ( 218 | 0 7px 34px 6px $_shadow-key-ambient-opacity, 219 | ), 220 | 19: ( 221 | 0 7px 36px 6px $_shadow-key-ambient-opacity, 222 | ), 223 | 20: ( 224 | 0 8px 38px 7px $_shadow-key-ambient-opacity, 225 | ), 226 | 21: ( 227 | 0 8px 40px 7px $_shadow-key-ambient-opacity, 228 | ), 229 | 22: ( 230 | 0 8px 42px 7px $_shadow-key-ambient-opacity, 231 | ), 232 | 23: ( 233 | 0 9px 44px 8px $_shadow-key-ambient-opacity, 234 | ), 235 | 24: ( 236 | 0 9px 46px 8px $_shadow-key-ambient-opacity, 237 | ), 238 | ); 239 | 240 | @mixin elevation($z, $important: false) { 241 | /* prettier-ignore */ 242 | box-shadow: map-get($_shadow-key-umbra, $z), 243 | map-get($_shadow-key-penumbra, $z), 244 | map-get($_shadow-key-ambient, $z) if($important, !important, null); 245 | } 246 | -------------------------------------------------------------------------------- /src/lib/style/pallete/tools/functions.scss: -------------------------------------------------------------------------------- 1 | @function map-deep-get($map, $keys...) { 2 | $result: $map; 3 | @each $key in $keys { 4 | $result: map-get($result, $key); 5 | } 6 | @return $result; 7 | } 8 | 9 | // From: https://gist.github.com/pentzzsolt/4949bbd7691d43d00616dc4f1451cae9#file-non-destructive-map-merge-4-scss 10 | @function map-deep-merge($parent-map, $child-map) { 11 | $result: $parent-map; 12 | @each $key, $value in $child-map { 13 | @if (not map-has-key($result, $key)) or 14 | (type-of(map-get($result, $key)) != type-of($value)) or 15 | (not (type-of(map-get($result, $key)) == map and type-of($value) == map)) 16 | { 17 | $result: map-merge( 18 | $result, 19 | ( 20 | $key: $value, 21 | ) 22 | ); 23 | } @else { 24 | $result: map-merge( 25 | $result, 26 | ( 27 | $key: non-destructive-map-merge(map-get($result, $key), $value), 28 | ) 29 | ); 30 | } 31 | } 32 | @return $result; 33 | } 34 | -------------------------------------------------------------------------------- /src/lib/style/pallete/variables.scss: -------------------------------------------------------------------------------- 1 | @import './tools/functions'; 2 | @import './tools/colors'; 3 | @import './tools/elevation'; 4 | 5 | $primary-color: #6200ee !default; 6 | $secondary-color: #1976d2 !default; 7 | $success-color: #4caf50 !default; 8 | $info-color: #00bcd4 !default; 9 | $warning-color: #fb8c00 !default; 10 | $error-color: #f44336 !default; 11 | 12 | $font-size-root: 16px !default; 13 | $border-radius-root: 4px !default; 14 | $line-height-root: 1.5 !default; 15 | 16 | $rounded: () !default; 17 | 18 | $blockquote-font-size: 18px !default; 19 | $blockquote-font-weight: 300 !default; 20 | 21 | $code-color: #c0341d !default; 22 | $code-padding: 0 0.4rem !default; 23 | $code-background-color: #fbe5e1 !default; 24 | 25 | $kbd-color: #ffffff !default; 26 | $kbd-padding: 0.2rem 0.4rem !default; 27 | $kbd-background-color: #212529 !default; 28 | 29 | $code-kbd-font-size: 85% !default; 30 | $code-kbd-border-radius: 3px !default; 31 | $code-kbd-font-weight: 900 !default; 32 | 33 | $spacer: 4px !default; 34 | 35 | $body-font-family: 'Roboto', 'Segoe UI', sans-serif !default; 36 | 37 | $font-weights: () !default; 38 | $heading-font-family: $body-font-family !default; 39 | $headings: () !default; 40 | 41 | $grid-columns: 12 !default; 42 | $grid-gutter: $spacer * 6 !default; 43 | $form-grid-gutter: $spacer * 2 !default; 44 | $grid-gutters: () !default; 45 | $grid-breakpoints: () !default; 46 | $display-breakpoints: () !default; 47 | 48 | $container-max-widths: () !default; 49 | $container-padding-x: $grid-gutter / 2 !default; 50 | 51 | $transitions: () !default; 52 | 53 | $material-light-theme: () !default; 54 | $material-dark-elevation-colors: () !default; 55 | $material-dark-theme: () !default; 56 | 57 | // Importing user defined variables 58 | //@import 'material-theme'; 59 | 60 | $rounded: map-deep-merge( 61 | ( 62 | 0: 0, 63 | 'sm': $border-radius-root / 2, 64 | null: $border-radius-root, 65 | 'lg': $border-radius-root * 2, 66 | 'xl': $border-radius-root * 6, 67 | 'pill': 9999px, 68 | 'circle': 50%, 69 | ), 70 | $rounded 71 | ); 72 | 73 | $font-weights: map-merge( 74 | ( 75 | 'thin': 100, 76 | 'light': 300, 77 | 'regular': 400, 78 | 'medium': 500, 79 | 'bold': 700, 80 | 'black': 900, 81 | ), 82 | $font-weights 83 | ); 84 | 85 | $headings: map-deep-merge( 86 | ( 87 | 'h1': ( 88 | 'size': 6rem, 89 | 'weight': 300, 90 | 'line-height': 6rem, 91 | 'letter-spacing': -0.015625em, 92 | 'font-family': $heading-font-family, 93 | 'text-transform': false, 94 | ), 95 | 'h2': ( 96 | 'size': 3.75rem, 97 | 'weight': 300, 98 | 'line-height': 3.75rem, 99 | 'letter-spacing': -0.0083333333em, 100 | 'font-family': $heading-font-family, 101 | 'text-transform': false, 102 | ), 103 | 'h3': ( 104 | 'size': 3rem, 105 | 'weight': 400, 106 | 'line-height': 3.125rem, 107 | 'letter-spacing': normal, 108 | 'font-family': $heading-font-family, 109 | 'text-transform': false, 110 | ), 111 | 'h4': ( 112 | 'size': 2.125rem, 113 | 'weight': 400, 114 | 'line-height': 2.5rem, 115 | 'letter-spacing': 0.0073529412em, 116 | 'font-family': $heading-font-family, 117 | 'text-transform': false, 118 | ), 119 | 'h5': ( 120 | 'size': 1.5rem, 121 | 'weight': 400, 122 | 'line-height': 2rem, 123 | 'letter-spacing': normal, 124 | 'font-family': $heading-font-family, 125 | 'text-transform': false, 126 | ), 127 | 'h6': ( 128 | 'size': 1.25rem, 129 | 'weight': 500, 130 | 'line-height': 2rem, 131 | 'letter-spacing': 0.0125em, 132 | 'font-family': $heading-font-family, 133 | 'text-transform': false, 134 | ), 135 | 'subtitle-1': ( 136 | 'size': 1rem, 137 | 'weight': normal, 138 | 'line-height': 1.75rem, 139 | 'letter-spacing': 0.009375em, 140 | 'font-family': $body-font-family, 141 | 'text-transform': false, 142 | ), 143 | 'subtitle-2': ( 144 | 'size': 0.875rem, 145 | 'weight': 500, 146 | 'line-height': 1.375rem, 147 | 'letter-spacing': 0.0071428571em, 148 | 'font-family': $body-font-family, 149 | 'text-transform': false, 150 | ), 151 | 'body-1': ( 152 | 'size': 1rem, 153 | 'weight': 400, 154 | 'line-height': 1.5rem, 155 | 'letter-spacing': 0.03125em, 156 | 'font-family': $body-font-family, 157 | 'text-transform': false, 158 | ), 159 | 'body-2': ( 160 | 'size': 0.875rem, 161 | 'weight': 400, 162 | 'line-height': 1.25rem, 163 | 'letter-spacing': 0.0178571429em, 164 | 'font-family': $body-font-family, 165 | 'text-transform': false, 166 | ), 167 | 'button': ( 168 | 'size': 0.875rem, 169 | 'weight': 500, 170 | 'line-height': 2.25rem, 171 | 'letter-spacing': 0.0892857143em, 172 | 'font-family': $body-font-family, 173 | 'text-transform': uppercase, 174 | ), 175 | 'caption': ( 176 | 'size': 0.75rem, 177 | 'weight': 400, 178 | 'line-height': 1.25rem, 179 | 'letter-spacing': 0.0333333333em, 180 | 'font-family': $body-font-family, 181 | 'text-transform': false, 182 | ), 183 | 'overline': ( 184 | 'size': 0.75rem, 185 | 'weight': 500, 186 | 'line-height': 2rem, 187 | 'letter-spacing': 0.1666666667em, 188 | 'font-family': $body-font-family, 189 | 'text-transform': uppercase, 190 | ), 191 | ), 192 | $headings 193 | ); 194 | 195 | $grid-breakpoints: map-deep-merge( 196 | ( 197 | 'xs': 0, 198 | 'sm': 600px, 199 | 'md': 960px, 200 | 'lg': 1280px - 16px, 201 | 'xl': 1920px - 16px, 202 | ), 203 | $grid-breakpoints 204 | ); 205 | 206 | $grid-gutters: map-deep-merge( 207 | ( 208 | 'xs': $grid-gutter / 12, 209 | 'sm': $grid-gutter / 6, 210 | 'md': $grid-gutter / 3, 211 | 'lg': $grid-gutter * 2/3, 212 | 'xl': $grid-gutter, 213 | ), 214 | $grid-gutters 215 | ); 216 | 217 | /* prettier-ignore */ 218 | $display-breakpoints: map-deep-merge( 219 | ( 220 | 'print-only': 'only print', 221 | 'screen-only': 'only screen', 222 | 'xs-only': 'only screen and (max-width: #{map-get($grid-breakpoints, 'sm')-1})', 223 | 'sm-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')}) and (max-width: #{map-get($grid-breakpoints, 'md')-1})', 224 | 'sm-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'md')-1})', 225 | 'sm-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')})', 226 | 'md-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')}) and (max-width: #{map-get($grid-breakpoints, 'lg')-1})', 227 | 'md-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'lg')-1})', 228 | 'md-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')})', 229 | 'lg-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')}) and (max-width: #{map-get($grid-breakpoints, 'xl')-1})', 230 | 'lg-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints,'xl')-1})', 231 | 'lg-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints,'lg')})', 232 | 'xl-only': 'only screen and (min-width: #{map-get($grid-breakpoints,'xl')})', 233 | ), 234 | $display-breakpoints 235 | ); 236 | 237 | $container-max-widths: map-deep-merge( 238 | ( 239 | 'md': map-get($grid-breakpoints, 'md') * 0.9375, 240 | 'lg': map-get($grid-breakpoints, 'lg') * 0.9375, 241 | 'xl': map-get($grid-breakpoints, 'xl') * 0.9375, 242 | ), 243 | $container-max-widths 244 | ); 245 | 246 | $transitions: map-deep-merge( 247 | ( 248 | 'fast-out-slow-in': cubic-bezier(0.4, 0, 0.2, 1), 249 | 'linear-out-slow-in': cubic-bezier(0, 0, 0.2, 1), 250 | 'fast-out-linear-in': cubic-bezier(0.4, 0, 1, 1), 251 | 'ease-in-out': cubic-bezier(0.4, 0, 0.6, 1), 252 | 'fast-in-fast-out': cubic-bezier(0.25, 0.8, 0.25, 1), 253 | 'swing': cubic-bezier(0.25, 0.8, 0.5, 1), 254 | ), 255 | $transitions 256 | ); 257 | 258 | $material-light-theme: map-deep-merge( 259 | ( 260 | 'surface': #ffffff, 261 | 'text': ( 262 | 'primary': rgba(material-color('shades', 'black'), 0.87), 263 | 'secondary': rgba(material-color('shades', 'black'), 0.6), 264 | 'disabled': rgba(material-color('shades', 'black'), 0.38), 265 | 'link': material-color('blue', 'darken-2'), 266 | ), 267 | 'icons': ( 268 | 'active': rgba(material-color('shades', 'black'), 0.54), 269 | 'inactive': rgba(material-color('shades', 'black'), 0.38), 270 | ), 271 | 'inputs': ( 272 | 'box': rgba(material-color('shades', 'black'), 0.04), 273 | ), 274 | 'buttons': ( 275 | 'disabled': rgba(material-color('shades', 'black'), 0.26), 276 | ), 277 | 'tabs': rgba(0, 0, 0, 0.54), 278 | 'text-fields': ( 279 | 'filled': rgba(material-color('shades', 'black'), 0.06), 280 | 'filled-hover': rgba(material-color('shades', 'black'), 0.12), 281 | 'outlined': rgba(material-color('shades', 'black'), 0.38), 282 | 'outlined-disabled': rgba(material-color('shades', 'black'), 0.26), 283 | 'border': rgba(material-color('shades', 'black'), 0.42), 284 | ), 285 | 'controls': ( 286 | 'disabled': rgba(material-color('shades', 'black'), 0.26), 287 | 'thumb': ( 288 | 'inactive': material-color('shades', 'white'), 289 | 'disabled': material-color('grey', 'lighten-5'), 290 | ), 291 | 'track': ( 292 | 'inactive': rgba(material-color('shades', 'black'), 0.38), 293 | 'disabled': rgba(material-color('shades', 'black'), 0.12), 294 | ), 295 | ), 296 | 'tables': ( 297 | 'active': material-color('grey', 'lighten-4'), 298 | 'hover': material-color('grey', 'lighten-3'), 299 | 'group': material-color('grey', 'lighten-3'), 300 | ), 301 | 'dividers': rgba(material-color('shades', 'black'), 0.12), 302 | 'chips': #e0e0e0, 303 | 'cards': material-color('shades', 'white'), 304 | 'app-bar': material-color('grey', 'lighten-4'), 305 | 'navigation-drawer': material-color('shades', 'white'), 306 | ), 307 | $material-light-theme 308 | ); 309 | 310 | $material-dark-elevation-colors: map-merge( 311 | ( 312 | '0': #000000, 313 | '1': #1e1e1e, 314 | '2': #222222, 315 | '3': #252525, 316 | '4': #272727, 317 | '6': #2c2c2c, 318 | '8': #2e2e2e, 319 | '12': #333333, 320 | '16': #363636, 321 | '24': #373737, 322 | ), 323 | $material-dark-elevation-colors 324 | ); 325 | 326 | $material-dark-theme: map-deep-merge( 327 | ( 328 | 'surface': #212121, 329 | 'icons': ( 330 | 'active': material-color('shades', 'white'), 331 | 'inactive': rgba(material-color('shades', 'white'), 0.5), 332 | ), 333 | 'text': ( 334 | 'primary': material-color('shades', 'white'), 335 | 'secondary': rgba(material-color('shades', 'white'), 0.7), 336 | 'disabled': rgba(material-color('shades', 'white'), 0.5), 337 | 'link': material-color('blue', 'accent-1'), 338 | ), 339 | 'inputs': ( 340 | 'box': material-color('shades', 'white'), 341 | ), 342 | 'buttons': ( 343 | 'disabled': rgba(material-color('shades', 'white'), 0.3), 344 | ), 345 | 'tabs': rgba(material-color('shades', 'white'), 0.6), 346 | 'text-fields': ( 347 | 'filled': rgba(material-color('shades', 'white'), 0.08), 348 | 'filled-hover': rgba(material-color('shades', 'white'), 0.16), 349 | 'outlined': rgba(material-color('shades', 'white'), 0.24), 350 | 'outlined-disabled': rgba(material-color('shades', 'white'), 0.16), 351 | 'border': rgba(material-color('shades', 'white'), 0.7), 352 | ), 353 | 'controls': ( 354 | 'disabled': rgba(material-color('shades', 'white'), 0.3), 355 | 'thumb': ( 356 | 'inactive': material-color('grey', 'lighten-1'), 357 | 'disabled': material-color('grey', 'darken-3'), 358 | ), 359 | 'track': ( 360 | 'inactive': rgba(material-color('shades', 'white'), 0.3), 361 | 'disabled': rgba(material-color('shades', 'white'), 0.1), 362 | ), 363 | ), 364 | 'tables': ( 365 | 'active': #505050, 366 | 'hover': material-color('grey', 'darken-2'), 367 | 'group': material-color('grey', 'darken-2'), 368 | ), 369 | 'dividers': rgba(material-color('shades', 'white'), 0.12), 370 | 'chips': #555555, 371 | 'cards': map-get($material-dark-elevation-colors, '1'), 372 | 'app-bar': map-get($material-dark-elevation-colors, '4'), 373 | 'navigation-drawer': map-get($material-dark-elevation-colors, '16'), 374 | ), 375 | $material-dark-theme 376 | ); 377 | 378 | $primary-transition: 0.3s map-get($transitions, 'swing') !default; 379 | -------------------------------------------------------------------------------- /src/lib/style/variables.scss: -------------------------------------------------------------------------------- 1 | :root{ 2 | --text-color: #000; 3 | --f7-theme-color: #FECA16; 4 | --f7-theme-color-shade: #FECA16; 5 | --f7-theme-color-tint: #FECA16; 6 | --component-bg-color: #fff; 7 | 8 | --swiper-navigation-color: var(--text-color); 9 | --f7-navbar-bg-color: var(--f7-theme-color); 10 | --f7-toggle-active-color: var(--f7-theme-color); 11 | --f7-list-bg-color: var(--component-bg-color); 12 | --f7-popover-bg-color: var(--component-bg-color); 13 | --f7-calendar-sheet-bg-color: var(--component-bg-color); 14 | 15 | --f7-button-pressed-bg-color: rgba(0,0,0,0.1); 16 | --f7-toolbar-bg-color: var(--f7-theme-color); 17 | --f7-toolbar-link-color: var(--text-color); 18 | --f7-navbar-link-color: var(--text-color); 19 | --f7-checkbox-inactive-color: rgba(0,0,0,0.3); 20 | --f7-checkbox-icon-color: var(--text-color); 21 | --f7-button-text-color: var(--text-color); 22 | --f7-link-touch-ripple-color: rgba(0,0,0,0.3); 23 | --f7-tabbar-link-active-border-color: var(--text-color); 24 | --f7-tabbar-link-active-color: var(--text-color); 25 | --custom-button-text-success-color: #79AF3B; 26 | --f7-button-fill-text-color: var(--text-color); 27 | 28 | --f7-input-outline-border-color: rgba(0,0,0,0.7); 29 | --f7-list-item-border-color: rgba(0,0,0,0.7); 30 | 31 | /*search bar*/ 32 | --f7-searchbar-border-color: rgba(0,0,0,0.1); 33 | --f7-generic-border-color: rgba(0,0,0,0.1); 34 | } -------------------------------------------------------------------------------- /src/main.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import './lib/style/grid.scss'; 4 | @import './lib/style/margin.scss'; 5 | @import './lib/style/padding.scss'; 6 | @import './lib/style/variables.scss'; 7 | @import './lib/style/dimensions.scss'; 8 | @import './lib/style/pallete/generic/colors.scss'; 9 | @import './lib/style/framework7-icons.scss'; 10 | @import './lib/style/overwrite-platform-defaults.scss'; 11 | 12 | 13 | body { 14 | font-family: 'Roboto'; 15 | margin: 0; 16 | } -------------------------------------------------------------------------------- /src/main.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 | 20 | 21 | 22 | {#if $message} 23 | 24 | {/if} 25 | 26 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import Framework7 from 'framework7/lite-bundle' 2 | import Framework7Svelte from "framework7-svelte" 3 | import App from './main.svelte' 4 | 5 | import 'framework7/framework7-bundle.css' 6 | import './main.scss' 7 | 8 | Framework7.use(Framework7Svelte) 9 | 10 | const app = new App({ 11 | target: document.getElementById("app") 12 | }) 13 | 14 | export default app 15 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from 'svelte-preprocess' 2 | 3 | export default { 4 | // Consult https://github.com/sveltejs/svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: sveltePreprocess() 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "module": "esnext", 6 | "resolveJsonModule": true, 7 | "baseUrl": ".", 8 | /** 9 | * Typecheck JS in `.svelte` and `.js` files by default. 10 | * Disable checkJs if you'd like to use dynamic types in JS. 11 | * Note that setting allowJs false does not prevent the use 12 | * of JS in `.svelte` files. 13 | */ 14 | "allowJs": true, 15 | "checkJs": true 16 | }, 17 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte", "public/service-worker.js"] 18 | } 19 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import { svelte } from '@sveltejs/vite-plugin-svelte' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [ 7 | svelte() 8 | ], 9 | optimizeDeps: { 10 | exclude: ['framework7', 'framework7-svelte'], 11 | }, 12 | server:{ 13 | host:'::' 14 | } 15 | }) 16 | --------------------------------------------------------------------------------