├── .gitignore ├── README.md ├── dev ├── index.js ├── package.json └── yarn.lock ├── docs └── logo.png ├── nuxt ├── README.md ├── assets │ └── styles │ │ ├── index.css │ │ ├── normalize.css │ │ └── skeleton.css ├── components │ ├── Item.vue │ └── Rectangle.vue ├── layouts │ └── default.vue ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages │ ├── caveats │ │ └── random.vue │ ├── examples │ │ ├── basic.vue │ │ ├── global.vue │ │ ├── inherit.vue │ │ └── inline.vue │ ├── index.js │ └── index.vue ├── store │ ├── Item.ts │ ├── Rectangle.ts │ └── Square.ts └── tsconfig.json ├── package-lock.json ├── package.json ├── vue-2 ├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── components │ │ ├── App.vue │ │ ├── CodeView.vue │ │ ├── Home.vue │ │ └── RectangleView.vue │ ├── examples │ │ ├── class-store │ │ │ ├── basic │ │ │ │ ├── Rectangle.ts │ │ │ │ ├── RectangleStore.ts │ │ │ │ └── index.vue │ │ │ ├── global │ │ │ │ ├── Item.vue │ │ │ │ ├── ItemsStore.ts │ │ │ │ ├── index.vue │ │ │ │ └── store.d.ts │ │ │ ├── inherit │ │ │ │ ├── Square.ts │ │ │ │ ├── SquareStore.ts │ │ │ │ └── index.vue │ │ │ └── inline │ │ │ │ └── index.vue │ │ ├── index.js │ │ └── other │ │ │ ├── vue-component │ │ │ └── index.vue │ │ │ ├── vue-model │ │ │ ├── Rectangle.js │ │ │ ├── RectangleService.js │ │ │ └── index.vue │ │ │ └── vuex │ │ │ ├── index.vue │ │ │ └── store │ │ │ ├── index.ts │ │ │ └── modules │ │ │ └── rectangle.ts │ ├── main.ts │ ├── router │ │ └── index.ts │ ├── shims-vue.d.ts │ └── styles │ │ ├── index.css │ │ ├── normalize.css │ │ └── skeleton.css ├── tsconfig.json ├── vue.config.js └── yarn.lock └── vue-3 ├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── components │ ├── App.vue │ ├── CodeView.vue │ ├── Home.vue │ └── RectangleView.vue ├── examples │ ├── class-store │ │ ├── basic │ │ │ ├── Rectangle.ts │ │ │ └── index.vue │ │ ├── global │ │ │ ├── Item.vue │ │ │ ├── ItemsStore.ts │ │ │ └── index.vue │ │ ├── inherit │ │ │ ├── Square.ts │ │ │ └── index.vue │ │ └── inline │ │ │ └── index.vue │ ├── index.js │ └── vue │ │ ├── reactive-helper │ │ ├── factory.ts │ │ └── index.vue │ │ ├── reactive-model │ │ ├── factory.ts │ │ └── index.vue │ │ └── setup-function │ │ └── index.vue ├── main.ts ├── router │ └── index.ts ├── shims-vue.d.ts └── styles │ ├── index.css │ ├── normalize.css │ └── skeleton.css ├── tsconfig.json ├── vue.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | /logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE / Editor 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | 86 | # macOS 87 | .DS_Store 88 | 89 | # Vim swap files 90 | *.swp 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Vue Class Store - Demos 2 | 3 | > Vue Class Store demos for Vue 2, Vue 3 and Nuxt 4 | 5 |

6 | 7 |

8 | 9 | ## Abstract 10 | 11 | This repo provides demos for [Vue Class Store](https://github.com/davestewart/vue-class-store) for Vue 2, Vue 3 and Nuxt. 12 | 13 | Currently, only the Nuxt Demo will run on Code Sandbox (all run locally; I'm investigating): 14 | 15 | - https://codesandbox.io/s/github/davestewart/vue-class-store-demos/tree/master/nuxt 16 | 17 | Each of the demos shows core Vue Class Store functionality in comparison to alternate state management functionality: 18 | 19 | Class Store: 20 | 21 | - [Basic Class Store](vue-2/src/examples/class-store/basic) 22 | - [Inline Class Store](vue-2/src/examples/class-store/inline) 23 | - [Class Store with Inheritance](vue-2/src/examples/class-store/inherit) 24 | - [Global Class Store](vue-2/src/examples/class-store/global) 25 | 26 | Alternatives (installed on Vue 2 demo only): 27 | 28 | - [Vue Component](vue-2/src/examples/other/vue-component) 29 | - [Vue Model](vue-2/src/examples/other/vue-model) 30 | - [Vuex](vue-2/src/examples/other/vuex) 31 | 32 | 33 | ## Setup 34 | 35 | To install and run, call these NPM scripts from the root folder: 36 | 37 | ``` 38 | # install all demo dependencies 39 | yarn install-demos 40 | 41 | # run demos 42 | yarn vue-2 43 | yarn vue-3 44 | yarn nuxt 45 | ``` 46 | 47 | Note, you can also use `npm *`, though the Vue Class Store is set up to use Yarn. 48 | 49 | ## Demos 50 | 51 | Each demo example uses a single methodology to model a rectangle with the following common functionality: 52 | 53 | - Width and height props / parameters 54 | - Computed / getter area property 55 | - A watch on the area property 56 | - A logs property and log method 57 | - A randomize method 58 | 59 | Look in the `/src/examples/*` folder to compare the code, or open the debugger Sources panel to see it in action. 60 | 61 | Make sure to check both the view and the model files within each! 62 | 63 | ## Development 64 | 65 | ### Getting started 66 | 67 | If you want to develop the Vue Class Store source, follow these steps: 68 | 69 | #### Common folder 70 | 71 | Decide upon, or create a common parent folder: 72 | 73 | ``` 74 | mkdir VueClassStore 75 | cd VueClassStore 76 | ``` 77 | 78 | #### Source 79 | 80 | Clone, install and link the `vue-class-store` source: 81 | 82 | ```bash 83 | git clone https://github.com/davestewart/vue-class-store.git 84 | cd vue-class-store 85 | yarn install 86 | yarn link 87 | ``` 88 | 89 | Compile the source for the Vue version of the package you want to work on: 90 | 91 | ``` 92 | # check out the correct branch 93 | git checkout master # or git checkout feature/vue-3 94 | 95 | # install the dependencies 96 | yarn install 97 | 98 | # build and watch the source 99 | yarn dev 100 | ``` 101 | 102 | #### Demos 103 | 104 | Back in the parent folder, clone and install the `vue-class-store-demos` repository (this repo): 105 | 106 | ``` 107 | git clone https://github.com/davestewart/vue-class-store-demos.git 108 | cd vue-class-store-demos 109 | yarn install-demos 110 | ``` 111 | 112 | You will then need to `yarn link` the local folders: 113 | 114 | ```bash 115 | yarn link-source 116 | ``` 117 | 118 | Finally, run the demo you want to work on: 119 | 120 | ``` 121 | yarn vue-2 # or your chosen version 122 | ``` 123 | 124 | 125 | ### A note about local development and symlinks 126 | 127 | In order for Vue Class Store to work correctly, the *package* Vue and the *project* Vue must be the **same** Vue. 128 | 129 | Because of Node's module resolution rules, if you symlink the package rather than NPM installing it, Node will load two different Vues for the project and package. 130 | 131 | To fix this, you need to tell the project's webpack setup to use **only** the project's Vue: 132 | 133 | ```js 134 | // vue.config.js 135 | const path = require('path') 136 | 137 | module.exports = { 138 | chainWebpack: (config) => { 139 | config.resolve.symlinks(false) 140 | config.resolve.alias.set('vue$', path.resolve(__dirname, 'node_modules/vue/')) 141 | } 142 | } 143 | ``` 144 | 145 | This is already set up in each of the demos, but good to know. 146 | -------------------------------------------------------------------------------- /dev/index.js: -------------------------------------------------------------------------------- 1 | const { exec } = require('child_process') 2 | const fs = require('fs') 3 | 4 | function stats (folder) { 5 | const path = '../vue-2/src/examples/' + folder 6 | const folders = fs.readdirSync(path) 7 | 8 | return new Promise((resolve, reject) => { 9 | console.log(folder) 10 | 11 | const promises = folders.map((folder) => { 12 | return new Promise((resolve, reject) => { 13 | const command = `node_modules/.bin/sloc ${path}/${folder} --details --format cli-table --keys total,source,comment` 14 | exec(command, (err, stdout, stderr) => { 15 | console.error(err || stdout) 16 | resolve() 17 | }) 18 | }) 19 | }) 20 | 21 | return Promise.all(promises).then(resolve) 22 | }) 23 | } 24 | 25 | stats('class-store') 26 | .then(() => { 27 | stats('other') 28 | }) 29 | -------------------------------------------------------------------------------- /dev/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-class-store-dev", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "private": true, 10 | "devDependencies": { 11 | "sloc": "^0.2.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /dev/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | arr-diff@^4.0.0: 6 | version "4.0.0" 7 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" 8 | integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= 9 | 10 | arr-flatten@^1.1.0: 11 | version "1.1.0" 12 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" 13 | integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== 14 | 15 | arr-union@^3.1.0: 16 | version "3.1.0" 17 | resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" 18 | integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= 19 | 20 | array-unique@^0.3.2: 21 | version "0.3.2" 22 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" 23 | integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= 24 | 25 | assign-symbols@^1.0.0: 26 | version "1.0.0" 27 | resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" 28 | integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= 29 | 30 | async@~2.1.4: 31 | version "2.1.5" 32 | resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" 33 | integrity sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw= 34 | dependencies: 35 | lodash "^4.14.0" 36 | 37 | atob@^2.1.2: 38 | version "2.1.2" 39 | resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" 40 | integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== 41 | 42 | base@^0.11.1: 43 | version "0.11.2" 44 | resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" 45 | integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== 46 | dependencies: 47 | cache-base "^1.0.1" 48 | class-utils "^0.3.5" 49 | component-emitter "^1.2.1" 50 | define-property "^1.0.0" 51 | isobject "^3.0.1" 52 | mixin-deep "^1.2.0" 53 | pascalcase "^0.1.1" 54 | 55 | braces@^2.3.1: 56 | version "2.3.2" 57 | resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" 58 | integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== 59 | dependencies: 60 | arr-flatten "^1.1.0" 61 | array-unique "^0.3.2" 62 | extend-shallow "^2.0.1" 63 | fill-range "^4.0.0" 64 | isobject "^3.0.1" 65 | repeat-element "^1.1.2" 66 | snapdragon "^0.8.1" 67 | snapdragon-node "^2.0.1" 68 | split-string "^3.0.2" 69 | to-regex "^3.0.1" 70 | 71 | cache-base@^1.0.1: 72 | version "1.0.1" 73 | resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" 74 | integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== 75 | dependencies: 76 | collection-visit "^1.0.0" 77 | component-emitter "^1.2.1" 78 | get-value "^2.0.6" 79 | has-value "^1.0.0" 80 | isobject "^3.0.1" 81 | set-value "^2.0.0" 82 | to-object-path "^0.3.0" 83 | union-value "^1.0.0" 84 | unset-value "^1.0.0" 85 | 86 | class-utils@^0.3.5: 87 | version "0.3.6" 88 | resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" 89 | integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== 90 | dependencies: 91 | arr-union "^3.1.0" 92 | define-property "^0.2.5" 93 | isobject "^3.0.0" 94 | static-extend "^0.1.1" 95 | 96 | cli-table@^0.3.1: 97 | version "0.3.1" 98 | resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" 99 | integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM= 100 | dependencies: 101 | colors "1.0.3" 102 | 103 | collection-visit@^1.0.0: 104 | version "1.0.0" 105 | resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" 106 | integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= 107 | dependencies: 108 | map-visit "^1.0.0" 109 | object-visit "^1.0.0" 110 | 111 | colors@1.0.3: 112 | version "1.0.3" 113 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" 114 | integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= 115 | 116 | commander@~2.9.0: 117 | version "2.9.0" 118 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" 119 | integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= 120 | dependencies: 121 | graceful-readlink ">= 1.0.0" 122 | 123 | component-emitter@^1.2.1: 124 | version "1.3.0" 125 | resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" 126 | integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== 127 | 128 | copy-descriptor@^0.1.0: 129 | version "0.1.1" 130 | resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" 131 | integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= 132 | 133 | core-util-is@~1.0.0: 134 | version "1.0.2" 135 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 136 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 137 | 138 | debug@^2.2.0, debug@^2.3.3: 139 | version "2.6.9" 140 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 141 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 142 | dependencies: 143 | ms "2.0.0" 144 | 145 | decode-uri-component@^0.2.0: 146 | version "0.2.0" 147 | resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" 148 | integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= 149 | 150 | define-property@^0.2.5: 151 | version "0.2.5" 152 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" 153 | integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= 154 | dependencies: 155 | is-descriptor "^0.1.0" 156 | 157 | define-property@^1.0.0: 158 | version "1.0.0" 159 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" 160 | integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= 161 | dependencies: 162 | is-descriptor "^1.0.0" 163 | 164 | define-property@^2.0.2: 165 | version "2.0.2" 166 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" 167 | integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== 168 | dependencies: 169 | is-descriptor "^1.0.2" 170 | isobject "^3.0.1" 171 | 172 | expand-brackets@^2.1.4: 173 | version "2.1.4" 174 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" 175 | integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= 176 | dependencies: 177 | debug "^2.3.3" 178 | define-property "^0.2.5" 179 | extend-shallow "^2.0.1" 180 | posix-character-classes "^0.1.0" 181 | regex-not "^1.0.0" 182 | snapdragon "^0.8.1" 183 | to-regex "^3.0.1" 184 | 185 | extend-shallow@^2.0.1: 186 | version "2.0.1" 187 | resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" 188 | integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= 189 | dependencies: 190 | is-extendable "^0.1.0" 191 | 192 | extend-shallow@^3.0.0, extend-shallow@^3.0.2: 193 | version "3.0.2" 194 | resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" 195 | integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= 196 | dependencies: 197 | assign-symbols "^1.0.0" 198 | is-extendable "^1.0.1" 199 | 200 | extglob@^2.0.4: 201 | version "2.0.4" 202 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" 203 | integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== 204 | dependencies: 205 | array-unique "^0.3.2" 206 | define-property "^1.0.0" 207 | expand-brackets "^2.1.4" 208 | extend-shallow "^2.0.1" 209 | fragment-cache "^0.2.1" 210 | regex-not "^1.0.0" 211 | snapdragon "^0.8.1" 212 | to-regex "^3.0.1" 213 | 214 | fill-range@^4.0.0: 215 | version "4.0.0" 216 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" 217 | integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= 218 | dependencies: 219 | extend-shallow "^2.0.1" 220 | is-number "^3.0.0" 221 | repeat-string "^1.6.1" 222 | to-regex-range "^2.1.0" 223 | 224 | for-in@^1.0.2: 225 | version "1.0.2" 226 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 227 | integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= 228 | 229 | fragment-cache@^0.2.1: 230 | version "0.2.1" 231 | resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" 232 | integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= 233 | dependencies: 234 | map-cache "^0.2.2" 235 | 236 | get-value@^2.0.3, get-value@^2.0.6: 237 | version "2.0.6" 238 | resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" 239 | integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= 240 | 241 | graceful-fs@^4.1.11: 242 | version "4.2.4" 243 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" 244 | integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== 245 | 246 | "graceful-readlink@>= 1.0.0": 247 | version "1.0.1" 248 | resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" 249 | integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= 250 | 251 | has-value@^0.3.1: 252 | version "0.3.1" 253 | resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" 254 | integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= 255 | dependencies: 256 | get-value "^2.0.3" 257 | has-values "^0.1.4" 258 | isobject "^2.0.0" 259 | 260 | has-value@^1.0.0: 261 | version "1.0.0" 262 | resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" 263 | integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= 264 | dependencies: 265 | get-value "^2.0.6" 266 | has-values "^1.0.0" 267 | isobject "^3.0.0" 268 | 269 | has-values@^0.1.4: 270 | version "0.1.4" 271 | resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" 272 | integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= 273 | 274 | has-values@^1.0.0: 275 | version "1.0.0" 276 | resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" 277 | integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= 278 | dependencies: 279 | is-number "^3.0.0" 280 | kind-of "^4.0.0" 281 | 282 | inherits@~2.0.3: 283 | version "2.0.4" 284 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 285 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 286 | 287 | is-accessor-descriptor@^0.1.6: 288 | version "0.1.6" 289 | resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" 290 | integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= 291 | dependencies: 292 | kind-of "^3.0.2" 293 | 294 | is-accessor-descriptor@^1.0.0: 295 | version "1.0.0" 296 | resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" 297 | integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== 298 | dependencies: 299 | kind-of "^6.0.0" 300 | 301 | is-buffer@^1.1.5: 302 | version "1.1.6" 303 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 304 | integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== 305 | 306 | is-data-descriptor@^0.1.4: 307 | version "0.1.4" 308 | resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" 309 | integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= 310 | dependencies: 311 | kind-of "^3.0.2" 312 | 313 | is-data-descriptor@^1.0.0: 314 | version "1.0.0" 315 | resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" 316 | integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== 317 | dependencies: 318 | kind-of "^6.0.0" 319 | 320 | is-descriptor@^0.1.0: 321 | version "0.1.6" 322 | resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" 323 | integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== 324 | dependencies: 325 | is-accessor-descriptor "^0.1.6" 326 | is-data-descriptor "^0.1.4" 327 | kind-of "^5.0.0" 328 | 329 | is-descriptor@^1.0.0, is-descriptor@^1.0.2: 330 | version "1.0.2" 331 | resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" 332 | integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== 333 | dependencies: 334 | is-accessor-descriptor "^1.0.0" 335 | is-data-descriptor "^1.0.0" 336 | kind-of "^6.0.2" 337 | 338 | is-extendable@^0.1.0, is-extendable@^0.1.1: 339 | version "0.1.1" 340 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 341 | integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= 342 | 343 | is-extendable@^1.0.1: 344 | version "1.0.1" 345 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" 346 | integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== 347 | dependencies: 348 | is-plain-object "^2.0.4" 349 | 350 | is-number@^3.0.0: 351 | version "3.0.0" 352 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" 353 | integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= 354 | dependencies: 355 | kind-of "^3.0.2" 356 | 357 | is-plain-object@^2.0.3, is-plain-object@^2.0.4: 358 | version "2.0.4" 359 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" 360 | integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== 361 | dependencies: 362 | isobject "^3.0.1" 363 | 364 | is-windows@^1.0.2: 365 | version "1.0.2" 366 | resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" 367 | integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== 368 | 369 | isarray@1.0.0, isarray@~1.0.0: 370 | version "1.0.0" 371 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 372 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 373 | 374 | isobject@^2.0.0: 375 | version "2.1.0" 376 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 377 | integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= 378 | dependencies: 379 | isarray "1.0.0" 380 | 381 | isobject@^3.0.0, isobject@^3.0.1: 382 | version "3.0.1" 383 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" 384 | integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= 385 | 386 | kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: 387 | version "3.2.2" 388 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 389 | integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= 390 | dependencies: 391 | is-buffer "^1.1.5" 392 | 393 | kind-of@^4.0.0: 394 | version "4.0.0" 395 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" 396 | integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= 397 | dependencies: 398 | is-buffer "^1.1.5" 399 | 400 | kind-of@^5.0.0: 401 | version "5.1.0" 402 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" 403 | integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== 404 | 405 | kind-of@^6.0.0, kind-of@^6.0.2: 406 | version "6.0.3" 407 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" 408 | integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== 409 | 410 | lodash@^4.14.0: 411 | version "4.17.15" 412 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" 413 | integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== 414 | 415 | map-cache@^0.2.2: 416 | version "0.2.2" 417 | resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" 418 | integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= 419 | 420 | map-visit@^1.0.0: 421 | version "1.0.0" 422 | resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" 423 | integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= 424 | dependencies: 425 | object-visit "^1.0.0" 426 | 427 | micromatch@^3.1.10: 428 | version "3.1.10" 429 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" 430 | integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== 431 | dependencies: 432 | arr-diff "^4.0.0" 433 | array-unique "^0.3.2" 434 | braces "^2.3.1" 435 | define-property "^2.0.2" 436 | extend-shallow "^3.0.2" 437 | extglob "^2.0.4" 438 | fragment-cache "^0.2.1" 439 | kind-of "^6.0.2" 440 | nanomatch "^1.2.9" 441 | object.pick "^1.3.0" 442 | regex-not "^1.0.0" 443 | snapdragon "^0.8.1" 444 | to-regex "^3.0.2" 445 | 446 | mixin-deep@^1.2.0: 447 | version "1.3.2" 448 | resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" 449 | integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== 450 | dependencies: 451 | for-in "^1.0.2" 452 | is-extendable "^1.0.1" 453 | 454 | ms@2.0.0: 455 | version "2.0.0" 456 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 457 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 458 | 459 | nanomatch@^1.2.9: 460 | version "1.2.13" 461 | resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" 462 | integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== 463 | dependencies: 464 | arr-diff "^4.0.0" 465 | array-unique "^0.3.2" 466 | define-property "^2.0.2" 467 | extend-shallow "^3.0.2" 468 | fragment-cache "^0.2.1" 469 | is-windows "^1.0.2" 470 | kind-of "^6.0.2" 471 | object.pick "^1.3.0" 472 | regex-not "^1.0.0" 473 | snapdragon "^0.8.1" 474 | to-regex "^3.0.1" 475 | 476 | object-copy@^0.1.0: 477 | version "0.1.0" 478 | resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" 479 | integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= 480 | dependencies: 481 | copy-descriptor "^0.1.0" 482 | define-property "^0.2.5" 483 | kind-of "^3.0.3" 484 | 485 | object-visit@^1.0.0: 486 | version "1.0.1" 487 | resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" 488 | integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= 489 | dependencies: 490 | isobject "^3.0.0" 491 | 492 | object.pick@^1.3.0: 493 | version "1.3.0" 494 | resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" 495 | integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= 496 | dependencies: 497 | isobject "^3.0.1" 498 | 499 | pascalcase@^0.1.1: 500 | version "0.1.1" 501 | resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" 502 | integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= 503 | 504 | posix-character-classes@^0.1.0: 505 | version "0.1.1" 506 | resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" 507 | integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= 508 | 509 | process-nextick-args@~2.0.0: 510 | version "2.0.1" 511 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 512 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 513 | 514 | readable-stream@^2.0.2: 515 | version "2.3.7" 516 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 517 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== 518 | dependencies: 519 | core-util-is "~1.0.0" 520 | inherits "~2.0.3" 521 | isarray "~1.0.0" 522 | process-nextick-args "~2.0.0" 523 | safe-buffer "~5.1.1" 524 | string_decoder "~1.1.1" 525 | util-deprecate "~1.0.1" 526 | 527 | readdirp@^2.1.0: 528 | version "2.2.1" 529 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" 530 | integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== 531 | dependencies: 532 | graceful-fs "^4.1.11" 533 | micromatch "^3.1.10" 534 | readable-stream "^2.0.2" 535 | 536 | regex-not@^1.0.0, regex-not@^1.0.2: 537 | version "1.0.2" 538 | resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" 539 | integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== 540 | dependencies: 541 | extend-shallow "^3.0.2" 542 | safe-regex "^1.1.0" 543 | 544 | repeat-element@^1.1.2: 545 | version "1.1.3" 546 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" 547 | integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== 548 | 549 | repeat-string@^1.6.1: 550 | version "1.6.1" 551 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 552 | integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= 553 | 554 | resolve-url@^0.2.1: 555 | version "0.2.1" 556 | resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" 557 | integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= 558 | 559 | ret@~0.1.10: 560 | version "0.1.15" 561 | resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" 562 | integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== 563 | 564 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 565 | version "5.1.2" 566 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 567 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 568 | 569 | safe-regex@^1.1.0: 570 | version "1.1.0" 571 | resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" 572 | integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= 573 | dependencies: 574 | ret "~0.1.10" 575 | 576 | set-value@^2.0.0, set-value@^2.0.1: 577 | version "2.0.1" 578 | resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" 579 | integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== 580 | dependencies: 581 | extend-shallow "^2.0.1" 582 | is-extendable "^0.1.1" 583 | is-plain-object "^2.0.3" 584 | split-string "^3.0.1" 585 | 586 | sloc@^0.2.1: 587 | version "0.2.1" 588 | resolved "https://registry.yarnpkg.com/sloc/-/sloc-0.2.1.tgz#42ad891e76838c1a22bbd8483468e9d74c7f531e" 589 | integrity sha512-8XJnwCFR4DatLz1s0nGFe6IJPJ+5pjRFhoBuBKq8SLgFI40eD7ak6jOXpzeG0tmIpyOc1zCs9bjKAxMFm1451A== 590 | dependencies: 591 | async "~2.1.4" 592 | cli-table "^0.3.1" 593 | commander "~2.9.0" 594 | readdirp "^2.1.0" 595 | 596 | snapdragon-node@^2.0.1: 597 | version "2.1.1" 598 | resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" 599 | integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== 600 | dependencies: 601 | define-property "^1.0.0" 602 | isobject "^3.0.0" 603 | snapdragon-util "^3.0.1" 604 | 605 | snapdragon-util@^3.0.1: 606 | version "3.0.1" 607 | resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" 608 | integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== 609 | dependencies: 610 | kind-of "^3.2.0" 611 | 612 | snapdragon@^0.8.1: 613 | version "0.8.2" 614 | resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" 615 | integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== 616 | dependencies: 617 | base "^0.11.1" 618 | debug "^2.2.0" 619 | define-property "^0.2.5" 620 | extend-shallow "^2.0.1" 621 | map-cache "^0.2.2" 622 | source-map "^0.5.6" 623 | source-map-resolve "^0.5.0" 624 | use "^3.1.0" 625 | 626 | source-map-resolve@^0.5.0: 627 | version "0.5.3" 628 | resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" 629 | integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== 630 | dependencies: 631 | atob "^2.1.2" 632 | decode-uri-component "^0.2.0" 633 | resolve-url "^0.2.1" 634 | source-map-url "^0.4.0" 635 | urix "^0.1.0" 636 | 637 | source-map-url@^0.4.0: 638 | version "0.4.0" 639 | resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" 640 | integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= 641 | 642 | source-map@^0.5.6: 643 | version "0.5.7" 644 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 645 | integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= 646 | 647 | split-string@^3.0.1, split-string@^3.0.2: 648 | version "3.1.0" 649 | resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" 650 | integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== 651 | dependencies: 652 | extend-shallow "^3.0.0" 653 | 654 | static-extend@^0.1.1: 655 | version "0.1.2" 656 | resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" 657 | integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= 658 | dependencies: 659 | define-property "^0.2.5" 660 | object-copy "^0.1.0" 661 | 662 | string_decoder@~1.1.1: 663 | version "1.1.1" 664 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 665 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 666 | dependencies: 667 | safe-buffer "~5.1.0" 668 | 669 | to-object-path@^0.3.0: 670 | version "0.3.0" 671 | resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" 672 | integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= 673 | dependencies: 674 | kind-of "^3.0.2" 675 | 676 | to-regex-range@^2.1.0: 677 | version "2.1.1" 678 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" 679 | integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= 680 | dependencies: 681 | is-number "^3.0.0" 682 | repeat-string "^1.6.1" 683 | 684 | to-regex@^3.0.1, to-regex@^3.0.2: 685 | version "3.0.2" 686 | resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" 687 | integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== 688 | dependencies: 689 | define-property "^2.0.2" 690 | extend-shallow "^3.0.2" 691 | regex-not "^1.0.2" 692 | safe-regex "^1.1.0" 693 | 694 | union-value@^1.0.0: 695 | version "1.0.1" 696 | resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" 697 | integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== 698 | dependencies: 699 | arr-union "^3.1.0" 700 | get-value "^2.0.6" 701 | is-extendable "^0.1.1" 702 | set-value "^2.0.1" 703 | 704 | unset-value@^1.0.0: 705 | version "1.0.0" 706 | resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" 707 | integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= 708 | dependencies: 709 | has-value "^0.3.1" 710 | isobject "^3.0.0" 711 | 712 | urix@^0.1.0: 713 | version "0.1.0" 714 | resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" 715 | integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= 716 | 717 | use@^3.1.0: 718 | version "3.1.1" 719 | resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" 720 | integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== 721 | 722 | util-deprecate@~1.0.1: 723 | version "1.0.2" 724 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 725 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 726 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davestewart/vue-class-store-demos/64d1987b2e284a65cf3cc25f0007a0cf00cd5394/docs/logo.png -------------------------------------------------------------------------------- /nuxt/README.md: -------------------------------------------------------------------------------- 1 | # Nuxt Class Store 2 | 3 | > Nuxt demo of Vue Class Store 4 | 5 | ## Abstract 6 | 7 | [Vue Class Store](https://github.com/davestewart/vue-class-store) is a fully-reactive, zero boilerplate store setup for Vue, and now Nuxt. 8 | 9 | This repo is a demo, using the Vue package. 10 | 11 | ## Online demo 12 | 13 | Go to: 14 | 15 | - https://codesandbox.io/s/github/davestewart/nuxt-class-store?file=/pages/examples/basic.vue 16 | 17 | 18 | ## Setup 19 | 20 | ```bash 21 | # install dependencies 22 | $ npm install 23 | 24 | # serve with hot reload at localhost:3000 25 | $ npm run dev 26 | 27 | # build for production and launch server 28 | $ npm run build 29 | $ npm run start 30 | 31 | # generate static project and serve at localhost:5000 32 | $ npm run generate 33 | $ npx serve dist 34 | ``` 35 | 36 | For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org). 37 | -------------------------------------------------------------------------------- /nuxt/assets/styles/index.css: -------------------------------------------------------------------------------- 1 | @import './normalize.css'; 2 | @import './skeleton.css'; 3 | 4 | body { 5 | padding: 3rem; 6 | } 7 | 8 | pre { 9 | font-family: unset; 10 | } 11 | 12 | p { 13 | margin-bottom: 1em; 14 | } 15 | 16 | ul { 17 | margin-left: 3rem; 18 | } 19 | 20 | li { 21 | margin-bottom: .2em; 22 | } 23 | 24 | .is-warning { 25 | color: red; 26 | } 27 | -------------------------------------------------------------------------------- /nuxt/assets/styles/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | -moz-box-sizing: content-box; 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-appearance: textfield; /* 1 */ 359 | -moz-box-sizing: content-box; 360 | -webkit-box-sizing: content-box; /* 2 */ 361 | box-sizing: content-box; 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | border: 1px solid #c0c0c0; 381 | margin: 0 2px; 382 | padding: 0.35em 0.625em 0.75em; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | border: 0; /* 1 */ 392 | padding: 0; /* 2 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-collapse: collapse; 421 | border-spacing: 0; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } -------------------------------------------------------------------------------- /nuxt/assets/styles/skeleton.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V2.0.4 3 | * Copyright 2014, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 12/29/2014 8 | */ 9 | 10 | 11 | /* Table of contents 12 | –––––––––––––––––––––––––––––––––––––––––––––––––– 13 | - Grid 14 | - Base Styles 15 | - Typography 16 | - Links 17 | - Buttons 18 | - Forms 19 | - Lists 20 | - Code 21 | - Tables 22 | - Spacing 23 | - Utilities 24 | - Clearing 25 | - Media Queries 26 | */ 27 | 28 | 29 | /* Grid 30 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 31 | .container { 32 | position: relative; 33 | width: 100%; 34 | max-width: 960px; 35 | margin: 0 auto; 36 | padding: 0 20px; 37 | box-sizing: border-box; } 38 | .column, 39 | .columns { 40 | width: 100%; 41 | float: left; 42 | box-sizing: border-box; } 43 | 44 | /* For devices larger than 400px */ 45 | @media (min-width: 400px) { 46 | .container { 47 | width: 85%; 48 | padding: 0; } 49 | } 50 | 51 | /* For devices larger than 550px */ 52 | @media (min-width: 550px) { 53 | .container { 54 | width: 80%; } 55 | .column, 56 | .columns { 57 | margin-left: 4%; } 58 | .column:first-child, 59 | .columns:first-child { 60 | margin-left: 0; } 61 | 62 | .one.column, 63 | .one.columns { width: 4.66666666667%; } 64 | .two.columns { width: 13.3333333333%; } 65 | .three.columns { width: 22%; } 66 | .four.columns { width: 30.6666666667%; } 67 | .five.columns { width: 39.3333333333%; } 68 | .six.columns { width: 48%; } 69 | .seven.columns { width: 56.6666666667%; } 70 | .eight.columns { width: 65.3333333333%; } 71 | .nine.columns { width: 74.0%; } 72 | .ten.columns { width: 82.6666666667%; } 73 | .eleven.columns { width: 91.3333333333%; } 74 | .twelve.columns { width: 100%; margin-left: 0; } 75 | 76 | .one-third.column { width: 30.6666666667%; } 77 | .two-thirds.column { width: 65.3333333333%; } 78 | 79 | .one-half.column { width: 48%; } 80 | 81 | /* Offsets */ 82 | .offset-by-one.column, 83 | .offset-by-one.columns { margin-left: 8.66666666667%; } 84 | .offset-by-two.column, 85 | .offset-by-two.columns { margin-left: 17.3333333333%; } 86 | .offset-by-three.column, 87 | .offset-by-three.columns { margin-left: 26%; } 88 | .offset-by-four.column, 89 | .offset-by-four.columns { margin-left: 34.6666666667%; } 90 | .offset-by-five.column, 91 | .offset-by-five.columns { margin-left: 43.3333333333%; } 92 | .offset-by-six.column, 93 | .offset-by-six.columns { margin-left: 52%; } 94 | .offset-by-seven.column, 95 | .offset-by-seven.columns { margin-left: 60.6666666667%; } 96 | .offset-by-eight.column, 97 | .offset-by-eight.columns { margin-left: 69.3333333333%; } 98 | .offset-by-nine.column, 99 | .offset-by-nine.columns { margin-left: 78.0%; } 100 | .offset-by-ten.column, 101 | .offset-by-ten.columns { margin-left: 86.6666666667%; } 102 | .offset-by-eleven.column, 103 | .offset-by-eleven.columns { margin-left: 95.3333333333%; } 104 | 105 | .offset-by-one-third.column, 106 | .offset-by-one-third.columns { margin-left: 34.6666666667%; } 107 | .offset-by-two-thirds.column, 108 | .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } 109 | 110 | .offset-by-one-half.column, 111 | .offset-by-one-half.columns { margin-left: 52%; } 112 | 113 | } 114 | 115 | 116 | /* Base Styles 117 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 118 | /* NOTE 119 | html is set to 62.5% so that all the REM measurements throughout Skeleton 120 | are based on 10px sizing. So basically 1.5rem = 15px :) */ 121 | html { 122 | font-size: 62.5%; } 123 | body { 124 | font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ 125 | line-height: 1.6; 126 | font-weight: 400; 127 | font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; 128 | color: #222; } 129 | 130 | 131 | /* Typography 132 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 133 | h1, h2, h3, h4, h5, h6 { 134 | margin-top: 0; 135 | margin-bottom: 2rem; 136 | font-weight: 300; } 137 | h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} 138 | h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } 139 | h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } 140 | h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } 141 | h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } 142 | h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } 143 | 144 | /* Larger than phablet */ 145 | @media (min-width: 550px) { 146 | h1 { font-size: 5.0rem; } 147 | h2 { font-size: 4.2rem; } 148 | h3 { font-size: 3.6rem; } 149 | h4 { font-size: 3.0rem; } 150 | h5 { font-size: 2.4rem; } 151 | h6 { font-size: 1.5rem; } 152 | } 153 | 154 | p { 155 | margin-top: 0; } 156 | 157 | 158 | /* Links 159 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 160 | a { 161 | color: #1EAEDB; } 162 | a:hover { 163 | color: #0FA0CE; } 164 | 165 | 166 | /* Buttons 167 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 168 | .button, 169 | button, 170 | input[type="submit"], 171 | input[type="reset"], 172 | input[type="button"] { 173 | display: inline-block; 174 | height: 38px; 175 | padding: 0 30px; 176 | color: #555; 177 | text-align: center; 178 | font-size: 11px; 179 | font-weight: 600; 180 | line-height: 38px; 181 | letter-spacing: .1rem; 182 | text-transform: uppercase; 183 | text-decoration: none; 184 | white-space: nowrap; 185 | background-color: transparent; 186 | border-radius: 4px; 187 | border: 1px solid #bbb; 188 | cursor: pointer; 189 | box-sizing: border-box; } 190 | .button:hover, 191 | button:hover, 192 | input[type="submit"]:hover, 193 | input[type="reset"]:hover, 194 | input[type="button"]:hover, 195 | .button:focus, 196 | button:focus, 197 | input[type="submit"]:focus, 198 | input[type="reset"]:focus, 199 | input[type="button"]:focus { 200 | color: #333; 201 | border-color: #888; 202 | outline: 0; } 203 | .button.button-primary, 204 | button.button-primary, 205 | input[type="submit"].button-primary, 206 | input[type="reset"].button-primary, 207 | input[type="button"].button-primary { 208 | color: #FFF; 209 | background-color: #33C3F0; 210 | border-color: #33C3F0; } 211 | .button.button-primary:hover, 212 | button.button-primary:hover, 213 | input[type="submit"].button-primary:hover, 214 | input[type="reset"].button-primary:hover, 215 | input[type="button"].button-primary:hover, 216 | .button.button-primary:focus, 217 | button.button-primary:focus, 218 | input[type="submit"].button-primary:focus, 219 | input[type="reset"].button-primary:focus, 220 | input[type="button"].button-primary:focus { 221 | color: #FFF; 222 | background-color: #1EAEDB; 223 | border-color: #1EAEDB; } 224 | 225 | 226 | /* Forms 227 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 228 | input[type="email"], 229 | input[type="number"], 230 | input[type="search"], 231 | input[type="text"], 232 | input[type="tel"], 233 | input[type="url"], 234 | input[type="password"], 235 | textarea, 236 | select { 237 | height: 38px; 238 | padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ 239 | background-color: #fff; 240 | border: 1px solid #D1D1D1; 241 | border-radius: 4px; 242 | box-shadow: none; 243 | box-sizing: border-box; } 244 | /* Removes awkward default styles on some inputs for iOS */ 245 | input[type="email"], 246 | input[type="number"], 247 | input[type="search"], 248 | input[type="text"], 249 | input[type="tel"], 250 | input[type="url"], 251 | input[type="password"], 252 | textarea { 253 | -webkit-appearance: none; 254 | -moz-appearance: none; 255 | appearance: none; } 256 | textarea { 257 | min-height: 65px; 258 | padding-top: 6px; 259 | padding-bottom: 6px; } 260 | input[type="email"]:focus, 261 | input[type="number"]:focus, 262 | input[type="search"]:focus, 263 | input[type="text"]:focus, 264 | input[type="tel"]:focus, 265 | input[type="url"]:focus, 266 | input[type="password"]:focus, 267 | textarea:focus, 268 | select:focus { 269 | border: 1px solid #33C3F0; 270 | outline: 0; } 271 | label, 272 | legend { 273 | display: block; 274 | margin-bottom: .5rem; 275 | font-weight: 600; } 276 | fieldset { 277 | padding: 0; 278 | border-width: 0; } 279 | input[type="checkbox"], 280 | input[type="radio"] { 281 | display: inline; } 282 | label > .label-body { 283 | display: inline-block; 284 | margin-left: .5rem; 285 | font-weight: normal; } 286 | 287 | 288 | /* Lists 289 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 290 | ul { 291 | list-style: circle inside; } 292 | ol { 293 | list-style: decimal inside; } 294 | ol, ul { 295 | padding-left: 0; 296 | margin-top: 0; } 297 | ul ul, 298 | ul ol, 299 | ol ol, 300 | ol ul { 301 | margin: 1.5rem 0 1.5rem 3rem; 302 | font-size: 90%; } 303 | li { 304 | margin-bottom: 1rem; } 305 | 306 | 307 | /* Code 308 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 309 | code { 310 | padding: .2rem .5rem; 311 | margin: 0 .2rem; 312 | font-size: 90%; 313 | white-space: nowrap; 314 | background: #F1F1F1; 315 | border: 1px solid #E1E1E1; 316 | border-radius: 4px; } 317 | pre > code { 318 | display: block; 319 | padding: 1rem 1.5rem; 320 | white-space: pre; } 321 | 322 | 323 | /* Tables 324 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 325 | th, 326 | td { 327 | padding: 12px 15px; 328 | text-align: left; 329 | border-bottom: 1px solid #E1E1E1; } 330 | th:first-child, 331 | td:first-child { 332 | padding-left: 0; } 333 | th:last-child, 334 | td:last-child { 335 | padding-right: 0; } 336 | 337 | 338 | /* Spacing 339 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 340 | button, 341 | .button { 342 | margin-bottom: 1rem; } 343 | input, 344 | textarea, 345 | select, 346 | fieldset { 347 | margin-bottom: 1.5rem; } 348 | pre, 349 | blockquote, 350 | dl, 351 | figure, 352 | table, 353 | p, 354 | ul, 355 | ol, 356 | form { 357 | margin-bottom: 2.5rem; } 358 | 359 | 360 | /* Utilities 361 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 362 | .u-full-width { 363 | width: 100%; 364 | box-sizing: border-box; } 365 | .u-max-full-width { 366 | max-width: 100%; 367 | box-sizing: border-box; } 368 | .u-pull-right { 369 | float: right; } 370 | .u-pull-left { 371 | float: left; } 372 | 373 | 374 | /* Misc 375 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 376 | hr { 377 | margin-top: 3rem; 378 | margin-bottom: 3.5rem; 379 | border-width: 0; 380 | border-top: 1px solid #E1E1E1; } 381 | 382 | 383 | /* Clearing 384 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 385 | 386 | /* Self Clearing Goodness */ 387 | .container:after, 388 | .row:after, 389 | .u-cf { 390 | content: ""; 391 | display: table; 392 | clear: both; } 393 | 394 | 395 | /* Media Queries 396 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 397 | /* 398 | Note: The best way to structure the use of media queries is to create the queries 399 | near the relevant code. For example, if you wanted to change the styles for buttons 400 | on small devices, paste the mobile query code up in the buttons section and style it 401 | there. 402 | */ 403 | 404 | 405 | /* Larger than mobile */ 406 | @media (min-width: 400px) {} 407 | 408 | /* Larger than phablet (also point when grid becomes active) */ 409 | @media (min-width: 550px) {} 410 | 411 | /* Larger than tablet */ 412 | @media (min-width: 750px) {} 413 | 414 | /* Larger than desktop */ 415 | @media (min-width: 1000px) {} 416 | 417 | /* Larger than Desktop HD */ 418 | @media (min-width: 1200px) {} 419 | -------------------------------------------------------------------------------- /nuxt/components/Item.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 41 | 42 | 62 | -------------------------------------------------------------------------------- /nuxt/components/Rectangle.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 25 | -------------------------------------------------------------------------------- /nuxt/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /nuxt/nuxt.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | 3 | export default { 4 | mode: 'universal', 5 | head: { 6 | title: 'Index', 7 | titleTemplate: '%s - Vue Class Store', 8 | meta: [ 9 | { charset: 'utf-8' }, 10 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 11 | { hid: 'description', name: 'description', content: process.env.npm_package_description || '' } 12 | ] 13 | }, 14 | css: [ 15 | '~/assets/styles/index.css' 16 | ], 17 | buildModules: [ 18 | '@nuxt/typescript-build' 19 | ], 20 | build: { 21 | extend (config) { 22 | config.resolve.alias.vue$ = path.resolve(__dirname, 'node_modules/vue/') 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /nuxt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-class-store-demo-nuxt", 3 | "description": "Nuxt demo of Vue Class Store", 4 | "version": "1.0.0", 5 | "author": "Dave Stewart", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore ." 13 | }, 14 | "dependencies": { 15 | "nuxt": "^2.0.0", 16 | "vue-class-store": "^2.0.4" 17 | }, 18 | "devDependencies": { 19 | "@nuxt/typescript-build": "^0.6.0", 20 | "@nuxtjs/eslint-config-typescript": "^1.0.0", 21 | "@nuxtjs/eslint-module": "^1.0.0", 22 | "babel-eslint": "^10.0.1", 23 | "eslint": "^6.1.0", 24 | "eslint-plugin-nuxt": ">=0.4.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /nuxt/pages/caveats/random.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 44 | -------------------------------------------------------------------------------- /nuxt/pages/examples/basic.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 30 | -------------------------------------------------------------------------------- /nuxt/pages/examples/global.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 40 | 41 | 46 | -------------------------------------------------------------------------------- /nuxt/pages/examples/inherit.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 31 | -------------------------------------------------------------------------------- /nuxt/pages/examples/inline.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 31 | -------------------------------------------------------------------------------- /nuxt/pages/index.js: -------------------------------------------------------------------------------- 1 | import Rectangle from '~/components/Rectangle.vue' 2 | 3 | export function page (title) { 4 | return { 5 | name: title.replace(/ /, ''), 6 | 7 | components: { 8 | Rectangle 9 | }, 10 | 11 | head () { 12 | return { 13 | title 14 | } 15 | }, 16 | 17 | data () { 18 | return { 19 | title 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /nuxt/pages/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 45 | -------------------------------------------------------------------------------- /nuxt/store/Item.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | 3 | let id = 1 4 | 5 | export class ItemModel { 6 | public id: number 7 | public title: string 8 | 9 | constructor () { 10 | this.id = id++ 11 | this.title = `Item ${this.id}` 12 | } 13 | } 14 | 15 | @VueStore 16 | export class ItemsStore { 17 | public items: ItemModel[] = [] 18 | 19 | public selectedIds: number[] = [] 20 | 21 | constructor (numItems: number = 0) { 22 | for (let i = 0; i < numItems; i++) { 23 | this.addItem() 24 | } 25 | } 26 | 27 | get numSelected () { 28 | return this.selectedIds.length 29 | } 30 | 31 | addItem () { 32 | this.items.push(new ItemModel()) 33 | } 34 | 35 | toggleRandom () { 36 | const item = this.items[Math.floor(Math.random() * this.items.length)] 37 | this.toggleItem(item.id) 38 | } 39 | 40 | toggleItem (id: number) { 41 | const index = this.selectedIds.indexOf(id) 42 | index === -1 43 | ? this.selectedIds.push(id) 44 | : this.selectedIds.splice(index, 1) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nuxt/store/Rectangle.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | 3 | export class Rectangle { 4 | public width: number 5 | 6 | public height: number 7 | 8 | public logs: string[] = [] 9 | 10 | constructor (width = 2, height = 2) { 11 | this.width = width 12 | this.height = height 13 | this.log('Rectangle constructor called!') 14 | } 15 | 16 | get area () { 17 | return this.width * this.height 18 | } 19 | 20 | 'on:area' (value: number) { 21 | this.log(`Area is ${value}`) 22 | } 23 | 24 | randomize () { 25 | this.width = Math.random() * 20 26 | this.height = Math.random() * 10 27 | } 28 | 29 | log (message: string) { 30 | this.logs.push(`${new Date().toISOString().match(/\d{2}:\d{2}:\d{2}/)}: ${message}`) 31 | } 32 | } 33 | 34 | @VueStore 35 | export class RectangleStore extends Rectangle { 36 | // there's no need to provide a constructor here, this is just to log some output 37 | constructor (width: number, height: number) { 38 | super(width, height) 39 | this.log('RectangleStore constructor called!') 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /nuxt/store/Square.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | import { Rectangle } from './Rectangle' 3 | 4 | export class Square extends Rectangle { 5 | constructor (size: number) { 6 | super(size, size) 7 | this.log('Square constructor called!') 8 | } 9 | 10 | 'on:width' = 'update' 11 | 12 | 'on:height' = 'update' 13 | 14 | randomize () { 15 | this.width = this.height = Math.random() * 20 16 | } 17 | 18 | update (value: number) { 19 | this.width = value 20 | this.height = value 21 | } 22 | } 23 | 24 | @VueStore 25 | export class SquareStore extends Square { 26 | // there's no need to provide a constructor here, this is just to log some output 27 | constructor (size: number) { 28 | super(size) 29 | this.log(`SquareStore constructor called!`) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /nuxt/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "lib": [ 7 | "esnext", 8 | "esnext.asynciterable", 9 | "dom" 10 | ], 11 | "esModuleInterop": true, 12 | "allowJs": true, 13 | "sourceMap": true, 14 | "strict": true, 15 | "noEmit": true, 16 | "experimentalDecorators": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "~/*": [ 20 | "./*" 21 | ], 22 | "@/*": [ 23 | "./*" 24 | ] 25 | }, 26 | "types": [ 27 | "@types/node", 28 | "@nuxt/types" 29 | ] 30 | }, 31 | "exclude": [ 32 | "node_modules", 33 | ".nuxt", 34 | "dist" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-class-store-demos", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "vuex": { 7 | "version": "3.4.0", 8 | "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.4.0.tgz", 9 | "integrity": "sha512-ajtqwEW/QhnrBZQsZxCLHThZZaa+Db45c92Asf46ZDXu6uHXgbfVuBaJ4gzD2r4UX0oMJHstFwd2r2HM4l8umg==" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-class-store-demos", 3 | "private": true, 4 | "scripts": { 5 | "install-demos": "cd vue-2 && yarn i && cd ../vue-3 && yarn i && cd ../nuxt && yarn i", 6 | "link-source": "cd vue-2 && yarn link vue-class-store && cd ../vue-3 && yarn link vue-class-store && cd ../nuxt && yarn link vue-class-store", 7 | "vue-2": "cd vue-2 && yarn run serve", 8 | "vue-3": "cd vue-3 && yarn run serve", 9 | "nuxt": "cd nuxt && yarn run dev" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /vue-2/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /vue-2/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /vue-2/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: [ 7 | 'plugin:vue/essential', 8 | '@vue/standard', 9 | '@vue/typescript/recommended' 10 | ], 11 | parserOptions: { 12 | ecmaVersion: 2020 13 | }, 14 | rules: { 15 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 16 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 17 | '@typescript-eslint/no-explicit-any': 'off' 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /vue-2/.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 | -------------------------------------------------------------------------------- /vue-2/README.md: -------------------------------------------------------------------------------- 1 | # vue-2 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /vue-2/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vue-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-class-store-demo-vue-2", 3 | "description": "Vue 2 demo of Vue Class Store", 4 | "version": "1.0.1", 5 | "private": true, 6 | "scripts": { 7 | "serve": "vue-cli-service serve", 8 | "build": "vue-cli-service build", 9 | "lint": "vue-cli-service lint" 10 | }, 11 | "dependencies": { 12 | "core-js": "^3.6.4", 13 | "vue": "2.5.21", 14 | "vue-class-store": "^2.0.4", 15 | "vue-router": "^3.1.6", 16 | "vuex": "^3.4.0" 17 | }, 18 | "devDependencies": { 19 | "@typescript-eslint/eslint-plugin": "^2.26.0", 20 | "@typescript-eslint/parser": "^2.26.0", 21 | "@vue/cli-plugin-babel": "~4.3.0", 22 | "@vue/cli-plugin-eslint": "~4.3.0", 23 | "@vue/cli-plugin-router": "~4.3.0", 24 | "@vue/cli-plugin-typescript": "~4.3.0", 25 | "@vue/cli-service": "~4.3.0", 26 | "@vue/eslint-config-standard": "^5.1.2", 27 | "@vue/eslint-config-typescript": "^5.0.2", 28 | "eslint": "^6.7.2", 29 | "eslint-plugin-import": "^2.20.2", 30 | "eslint-plugin-node": "^11.1.0", 31 | "eslint-plugin-promise": "^4.2.1", 32 | "eslint-plugin-standard": "^4.0.0", 33 | "eslint-plugin-vue": "^6.2.2", 34 | "lint-staged": "^9.5.0", 35 | "node-sass": "^4.14.1", 36 | "sass-loader": "^10.0.4", 37 | "typescript": "~3.8.3", 38 | "vue-template-compiler": "2.5.21" 39 | }, 40 | "gitHooks": { 41 | "pre-commit": "lint-staged" 42 | }, 43 | "lint-staged": { 44 | "*.{js,jsx,vue,ts,tsx}": [ 45 | "vue-cli-service lint", 46 | "git add" 47 | ] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vue-2/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davestewart/vue-class-store-demos/64d1987b2e284a65cf3cc25f0007a0cf00cd5394/vue-2/public/favicon.ico -------------------------------------------------------------------------------- /vue-2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vue-2/src/components/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 19 | -------------------------------------------------------------------------------- /vue-2/src/components/CodeView.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 59 | -------------------------------------------------------------------------------- /vue-2/src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 39 | -------------------------------------------------------------------------------- /vue-2/src/components/RectangleView.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 25 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/basic/Rectangle.ts: -------------------------------------------------------------------------------- 1 | export class Rectangle { 2 | public width: number 3 | 4 | public height: number 5 | 6 | public logs: string[] = [] 7 | 8 | constructor (width = 2, height = 2) { 9 | this.width = width 10 | this.height = height 11 | this.log('Rectangle constructor called!') 12 | } 13 | 14 | get area () { 15 | return this.width * this.height 16 | } 17 | 18 | 'on:area' (value: number) { 19 | this.log(`Area is ${value}`) 20 | } 21 | 22 | randomize () { 23 | this.width = Math.random() * 20 24 | this.height = Math.random() * 10 25 | } 26 | 27 | log (message: string) { 28 | this.logs.push(`${new Date().toISOString().match(/\d{2}:\d{2}:\d{2}/)}: ${message}`) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/basic/RectangleStore.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | import { Rectangle } from './Rectangle' 3 | 4 | @VueStore 5 | export class RectangleStore extends Rectangle { 6 | // there's no need to provide a constructor here, this is just to log some output 7 | constructor (width = 10, height = 10) { 8 | super(width, height) 9 | this.log('RectangleStore constructor called!') 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/basic/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 33 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/global/Item.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 41 | 42 | 62 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/global/ItemsStore.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | 3 | let id = 1 4 | 5 | export class ItemModel { 6 | public id: number 7 | public title: string 8 | 9 | constructor () { 10 | this.id = id++ 11 | this.title = `Item ${this.id}` 12 | } 13 | } 14 | 15 | @VueStore 16 | export class ItemsStore { 17 | public items: ItemModel[] = [] 18 | 19 | public selectedIds: number[] = [] 20 | 21 | constructor (numItems = 0) { 22 | for (let i = 0; i < numItems; i++) { 23 | this.addItem() 24 | } 25 | } 26 | 27 | get numSelected () { 28 | return this.selectedIds.length 29 | } 30 | 31 | addItem () { 32 | this.items.push(new ItemModel()) 33 | } 34 | 35 | toggleRandom () { 36 | const item = this.items[Math.floor(Math.random() * this.items.length)] 37 | this.toggleItem(item.id) 38 | } 39 | 40 | toggleItem (id: number) { 41 | const index = this.selectedIds.indexOf(id) 42 | index === -1 43 | ? this.selectedIds.push(id) 44 | : this.selectedIds.splice(index, 1) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/global/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 43 | 44 | 49 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/global/store.d.ts: -------------------------------------------------------------------------------- 1 | import { ItemsStore } from '@/examples/class-store/global/ItemsStore' 2 | 3 | declare module 'vue/types/vue' { 4 | interface Vue { 5 | $items: ItemsStore 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/inherit/Square.ts: -------------------------------------------------------------------------------- 1 | import { Rectangle } from '../basic/Rectangle' 2 | 3 | export class Square extends Rectangle { 4 | constructor (size: number) { 5 | super(size, size) 6 | this.log('Square constructor called!') 7 | } 8 | 9 | 'on:width' = 'update' 10 | 11 | 'on:height' = 'update' 12 | 13 | randomize () { 14 | this.width = this.height = Math.random() * 20 15 | } 16 | 17 | update (value: number) { 18 | this.width = value 19 | this.height = value 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/inherit/SquareStore.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | import { Square } from './Square' 3 | 4 | @VueStore 5 | export class SquareStore extends Square { 6 | // there's no need to provide a constructor here, this is just to log some output 7 | constructor (size: number) { 8 | super(size) 9 | this.log('SquareStore constructor called!') 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/inherit/index.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 35 | -------------------------------------------------------------------------------- /vue-2/src/examples/class-store/inline/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 33 | -------------------------------------------------------------------------------- /vue-2/src/examples/index.js: -------------------------------------------------------------------------------- 1 | import store from './class-store/basic/index.vue' 2 | import inline from './class-store/inline/index.vue' 3 | import inheritance from './class-store/inherit/index.vue' 4 | import global from './class-store/global/index.vue' 5 | import component from './other/vue-component/index.vue' 6 | import model from './other/vue-model/index.vue' 7 | import vuex from './other/vuex/index.vue' 8 | 9 | export { 10 | store, 11 | inline, 12 | inheritance, 13 | global, 14 | component, 15 | model, 16 | vuex 17 | } 18 | -------------------------------------------------------------------------------- /vue-2/src/examples/other/vue-component/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 58 | -------------------------------------------------------------------------------- /vue-2/src/examples/other/vue-model/Rectangle.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | export function makeRectangle (width, height) { 4 | return new Vue({ 5 | data () { 6 | return { 7 | width: width, 8 | height: height, 9 | logs: [] 10 | } 11 | }, 12 | 13 | computed: { 14 | area () { 15 | return this.width * this.height 16 | } 17 | }, 18 | 19 | watch: { 20 | area (value) { 21 | this.log(`Area is ${value}`) 22 | } 23 | }, 24 | 25 | created () { 26 | this.log('Vue Model created!') 27 | }, 28 | 29 | methods: { 30 | randomize () { 31 | this.width = Math.random() * 20 32 | this.height = Math.random() * 10 33 | }, 34 | 35 | log (message) { 36 | this.logs.push(`${new Date().toISOString().match(/\d{2}:\d{2}:\d{2}/)}: ${message}`) 37 | } 38 | } 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /vue-2/src/examples/other/vue-model/RectangleService.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | export function makeRectangle (width, height) { 4 | return new Vue({ 5 | data () { 6 | return { 7 | width: width, 8 | height: height, 9 | logs: [] 10 | } 11 | }, 12 | 13 | computed: { 14 | area () { 15 | return this.width * this.height 16 | } 17 | }, 18 | 19 | watch: { 20 | area (value) { 21 | this.log(`Area is ${value}`) 22 | } 23 | }, 24 | 25 | created () { 26 | this.log('Vue Model created!') 27 | }, 28 | 29 | methods: { 30 | randomize () { 31 | this.width = Math.random() * 20 32 | this.height = Math.random() * 10 33 | }, 34 | 35 | log (message) { 36 | this.logs.push(`${new Date().toISOString().match(/\d{2}:\d{2}:\d{2}/)}: ${message}`) 37 | } 38 | } 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /vue-2/src/examples/other/vue-model/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 32 | -------------------------------------------------------------------------------- /vue-2/src/examples/other/vuex/index.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 67 | -------------------------------------------------------------------------------- /vue-2/src/examples/other/vuex/store/index.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import rectangle from './modules/rectangle' 4 | 5 | Vue.use(Vuex) 6 | 7 | const store = new Vuex.Store({ 8 | modules: { 9 | rectangle 10 | } 11 | }) 12 | 13 | function updateLog () { 14 | store.dispatch('rectangle/log', `Area is ${store.getters['rectangle/area']}`) 15 | } 16 | 17 | /* eslint-disable */ 18 | store.watch((state) => (state as any).rectangle.width, updateLog) 19 | 20 | export default store 21 | -------------------------------------------------------------------------------- /vue-2/src/examples/other/vuex/store/modules/rectangle.ts: -------------------------------------------------------------------------------- 1 | const state = function () { 2 | return { 3 | width: 2, 4 | height: 2, 5 | logs: [] 6 | } 7 | } 8 | 9 | const actions = { 10 | randomize ({ commit }, [width, height]) { 11 | commit('width', Math.random() * width) 12 | commit('height', Math.random() * height) 13 | }, 14 | 15 | log ({ commit }, value: string) { 16 | commit('logs', value) 17 | } 18 | } 19 | 20 | const getters = { 21 | area (state) { 22 | return state.width * state.height 23 | } 24 | } 25 | 26 | const mutations = { 27 | width (state, value) { 28 | state.width = value 29 | }, 30 | 31 | height (state, value) { 32 | state.height = value 33 | }, 34 | 35 | logs (state, message) { 36 | state.logs.push(`${new Date().toISOString().match(/\d{2}:\d{2}:\d{2}/)}: ${message}`) 37 | } 38 | } 39 | 40 | export default { 41 | namespaced: true, 42 | state, 43 | actions, 44 | getters, 45 | mutations 46 | } 47 | -------------------------------------------------------------------------------- /vue-2/src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import router from './router' 3 | import App from './components/App.vue' 4 | import RectangleView from './components/RectangleView.vue' 5 | import CodeView from './components/CodeView.vue' 6 | import store from './examples/other/vuex/store' 7 | import './styles/index.css' 8 | 9 | // global components 10 | Vue.component('RectangleView', RectangleView) 11 | Vue.component('CodeView', CodeView) 12 | 13 | // setup and mount 14 | Vue.config.productionTip = false 15 | new Vue({ 16 | router, 17 | store, 18 | render: h => h(App) 19 | }).$mount('#app') 20 | -------------------------------------------------------------------------------- /vue-2/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | 4 | import Home from '../components/Home.vue' 5 | import * as examples from '../examples' 6 | 7 | Vue.use(VueRouter) 8 | 9 | function route (path: string, component: any, folder = '') { 10 | const title = (component.name || '').replace(/([a-z])([A-Z])/g, '$1 $2') 11 | return { path, component, title, meta: { folder, title } } 12 | } 13 | 14 | function example (path: string, component: any) { 15 | const [, , folder] = component.__file.split('/') 16 | return route(`/${folder + path}`, component, folder) 17 | } 18 | 19 | export function getRoutes () { 20 | return Object.keys(examples).map(key => { 21 | const component = examples[key] 22 | return example('/' + key, component) 23 | }) 24 | } 25 | 26 | const routes = [ 27 | route('/', Home), 28 | ...getRoutes() 29 | ] 30 | 31 | const router = new VueRouter({ 32 | mode: 'history', 33 | base: process.env.BASE_URL, 34 | routes 35 | }) 36 | 37 | router.beforeEach((to, from, next) => { 38 | const { title } = to.meta 39 | if (title) { 40 | document.title = title 41 | } 42 | next() 43 | }) 44 | 45 | export default router 46 | -------------------------------------------------------------------------------- /vue-2/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | export default Vue 4 | } 5 | -------------------------------------------------------------------------------- /vue-2/src/styles/index.css: -------------------------------------------------------------------------------- 1 | @import './normalize.css'; 2 | @import './skeleton.css'; 3 | 4 | body { 5 | padding: 3rem; 6 | } 7 | 8 | pre { 9 | font-family: unset; 10 | } 11 | 12 | p { 13 | margin-bottom: 1em; 14 | } 15 | 16 | ul { 17 | margin-left: 3rem; 18 | } 19 | 20 | li { 21 | margin-bottom: .2em; 22 | } 23 | 24 | input, button { 25 | margin-right: .5em; 26 | } 27 | -------------------------------------------------------------------------------- /vue-2/src/styles/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | -moz-box-sizing: content-box; 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-appearance: textfield; /* 1 */ 359 | -moz-box-sizing: content-box; 360 | -webkit-box-sizing: content-box; /* 2 */ 361 | box-sizing: content-box; 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | border: 1px solid #c0c0c0; 381 | margin: 0 2px; 382 | padding: 0.35em 0.625em 0.75em; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | border: 0; /* 1 */ 392 | padding: 0; /* 2 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-collapse: collapse; 421 | border-spacing: 0; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } -------------------------------------------------------------------------------- /vue-2/src/styles/skeleton.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V2.0.4 3 | * Copyright 2014, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 12/29/2014 8 | */ 9 | 10 | 11 | /* Table of contents 12 | –––––––––––––––––––––––––––––––––––––––––––––––––– 13 | - Grid 14 | - Base Styles 15 | - Typography 16 | - Links 17 | - Buttons 18 | - Forms 19 | - Lists 20 | - Code 21 | - Tables 22 | - Spacing 23 | - Utilities 24 | - Clearing 25 | - Media Queries 26 | */ 27 | 28 | 29 | /* Grid 30 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 31 | .container { 32 | position: relative; 33 | width: 100%; 34 | max-width: 960px; 35 | margin: 0 auto; 36 | padding: 0 20px; 37 | box-sizing: border-box; } 38 | .column, 39 | .columns { 40 | width: 100%; 41 | float: left; 42 | box-sizing: border-box; } 43 | 44 | /* For devices larger than 400px */ 45 | @media (min-width: 400px) { 46 | .container { 47 | width: 85%; 48 | padding: 0; } 49 | } 50 | 51 | /* For devices larger than 550px */ 52 | @media (min-width: 550px) { 53 | .container { 54 | width: 80%; } 55 | .column, 56 | .columns { 57 | margin-left: 4%; } 58 | .column:first-child, 59 | .columns:first-child { 60 | margin-left: 0; } 61 | 62 | .one.column, 63 | .one.columns { width: 4.66666666667%; } 64 | .two.columns { width: 13.3333333333%; } 65 | .three.columns { width: 22%; } 66 | .four.columns { width: 30.6666666667%; } 67 | .five.columns { width: 39.3333333333%; } 68 | .six.columns { width: 48%; } 69 | .seven.columns { width: 56.6666666667%; } 70 | .eight.columns { width: 65.3333333333%; } 71 | .nine.columns { width: 74.0%; } 72 | .ten.columns { width: 82.6666666667%; } 73 | .eleven.columns { width: 91.3333333333%; } 74 | .twelve.columns { width: 100%; margin-left: 0; } 75 | 76 | .one-third.column { width: 30.6666666667%; } 77 | .two-thirds.column { width: 65.3333333333%; } 78 | 79 | .one-half.column { width: 48%; } 80 | 81 | /* Offsets */ 82 | .offset-by-one.column, 83 | .offset-by-one.columns { margin-left: 8.66666666667%; } 84 | .offset-by-two.column, 85 | .offset-by-two.columns { margin-left: 17.3333333333%; } 86 | .offset-by-three.column, 87 | .offset-by-three.columns { margin-left: 26%; } 88 | .offset-by-four.column, 89 | .offset-by-four.columns { margin-left: 34.6666666667%; } 90 | .offset-by-five.column, 91 | .offset-by-five.columns { margin-left: 43.3333333333%; } 92 | .offset-by-six.column, 93 | .offset-by-six.columns { margin-left: 52%; } 94 | .offset-by-seven.column, 95 | .offset-by-seven.columns { margin-left: 60.6666666667%; } 96 | .offset-by-eight.column, 97 | .offset-by-eight.columns { margin-left: 69.3333333333%; } 98 | .offset-by-nine.column, 99 | .offset-by-nine.columns { margin-left: 78.0%; } 100 | .offset-by-ten.column, 101 | .offset-by-ten.columns { margin-left: 86.6666666667%; } 102 | .offset-by-eleven.column, 103 | .offset-by-eleven.columns { margin-left: 95.3333333333%; } 104 | 105 | .offset-by-one-third.column, 106 | .offset-by-one-third.columns { margin-left: 34.6666666667%; } 107 | .offset-by-two-thirds.column, 108 | .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } 109 | 110 | .offset-by-one-half.column, 111 | .offset-by-one-half.columns { margin-left: 52%; } 112 | 113 | } 114 | 115 | 116 | /* Base Styles 117 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 118 | /* NOTE 119 | html is set to 62.5% so that all the REM measurements throughout Skeleton 120 | are based on 10px sizing. So basically 1.5rem = 15px :) */ 121 | html { 122 | font-size: 62.5%; } 123 | body { 124 | font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ 125 | line-height: 1.6; 126 | font-weight: 400; 127 | font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; 128 | color: #222; } 129 | 130 | 131 | /* Typography 132 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 133 | h1, h2, h3, h4, h5, h6 { 134 | margin-top: 0; 135 | margin-bottom: 2rem; 136 | font-weight: 300; } 137 | h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} 138 | h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } 139 | h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } 140 | h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } 141 | h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } 142 | h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } 143 | 144 | /* Larger than phablet */ 145 | @media (min-width: 550px) { 146 | h1 { font-size: 5.0rem; } 147 | h2 { font-size: 4.2rem; } 148 | h3 { font-size: 3.6rem; } 149 | h4 { font-size: 3.0rem; } 150 | h5 { font-size: 2.4rem; } 151 | h6 { font-size: 1.5rem; } 152 | } 153 | 154 | p { 155 | margin-top: 0; } 156 | 157 | 158 | /* Links 159 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 160 | a { 161 | color: #1EAEDB; } 162 | a:hover { 163 | color: #0FA0CE; } 164 | 165 | 166 | /* Buttons 167 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 168 | .button, 169 | button, 170 | input[type="submit"], 171 | input[type="reset"], 172 | input[type="button"] { 173 | display: inline-block; 174 | height: 38px; 175 | padding: 0 30px; 176 | color: #555; 177 | text-align: center; 178 | font-size: 11px; 179 | font-weight: 600; 180 | line-height: 38px; 181 | letter-spacing: .1rem; 182 | text-transform: uppercase; 183 | text-decoration: none; 184 | white-space: nowrap; 185 | background-color: transparent; 186 | border-radius: 4px; 187 | border: 1px solid #bbb; 188 | cursor: pointer; 189 | box-sizing: border-box; } 190 | .button:hover, 191 | button:hover, 192 | input[type="submit"]:hover, 193 | input[type="reset"]:hover, 194 | input[type="button"]:hover, 195 | .button:focus, 196 | button:focus, 197 | input[type="submit"]:focus, 198 | input[type="reset"]:focus, 199 | input[type="button"]:focus { 200 | color: #333; 201 | border-color: #888; 202 | outline: 0; } 203 | .button.button-primary, 204 | button.button-primary, 205 | input[type="submit"].button-primary, 206 | input[type="reset"].button-primary, 207 | input[type="button"].button-primary { 208 | color: #FFF; 209 | background-color: #33C3F0; 210 | border-color: #33C3F0; } 211 | .button.button-primary:hover, 212 | button.button-primary:hover, 213 | input[type="submit"].button-primary:hover, 214 | input[type="reset"].button-primary:hover, 215 | input[type="button"].button-primary:hover, 216 | .button.button-primary:focus, 217 | button.button-primary:focus, 218 | input[type="submit"].button-primary:focus, 219 | input[type="reset"].button-primary:focus, 220 | input[type="button"].button-primary:focus { 221 | color: #FFF; 222 | background-color: #1EAEDB; 223 | border-color: #1EAEDB; } 224 | 225 | 226 | /* Forms 227 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 228 | input[type="email"], 229 | input[type="number"], 230 | input[type="search"], 231 | input[type="text"], 232 | input[type="tel"], 233 | input[type="url"], 234 | input[type="password"], 235 | textarea, 236 | select { 237 | height: 38px; 238 | padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ 239 | background-color: #fff; 240 | border: 1px solid #D1D1D1; 241 | border-radius: 4px; 242 | box-shadow: none; 243 | box-sizing: border-box; } 244 | /* Removes awkward default styles on some inputs for iOS */ 245 | input[type="email"], 246 | input[type="number"], 247 | input[type="search"], 248 | input[type="text"], 249 | input[type="tel"], 250 | input[type="url"], 251 | input[type="password"], 252 | textarea { 253 | -webkit-appearance: none; 254 | -moz-appearance: none; 255 | appearance: none; } 256 | textarea { 257 | min-height: 65px; 258 | padding-top: 6px; 259 | padding-bottom: 6px; } 260 | input[type="email"]:focus, 261 | input[type="number"]:focus, 262 | input[type="search"]:focus, 263 | input[type="text"]:focus, 264 | input[type="tel"]:focus, 265 | input[type="url"]:focus, 266 | input[type="password"]:focus, 267 | textarea:focus, 268 | select:focus { 269 | border: 1px solid #33C3F0; 270 | outline: 0; } 271 | label, 272 | legend { 273 | display: block; 274 | margin-bottom: .5rem; 275 | font-weight: 600; } 276 | fieldset { 277 | padding: 0; 278 | border-width: 0; } 279 | input[type="checkbox"], 280 | input[type="radio"] { 281 | display: inline; } 282 | label > .label-body { 283 | display: inline-block; 284 | margin-left: .5rem; 285 | font-weight: normal; } 286 | 287 | 288 | /* Lists 289 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 290 | ul { 291 | list-style: circle inside; } 292 | ol { 293 | list-style: decimal inside; } 294 | ol, ul { 295 | padding-left: 0; 296 | margin-top: 0; } 297 | ul ul, 298 | ul ol, 299 | ol ol, 300 | ol ul { 301 | margin: 1.5rem 0 1.5rem 3rem; 302 | font-size: 90%; } 303 | li { 304 | margin-bottom: 1rem; } 305 | 306 | 307 | /* Code 308 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 309 | code { 310 | padding: .2rem .5rem; 311 | margin: 0 .2rem; 312 | font-size: 90%; 313 | white-space: nowrap; 314 | background: #F1F1F1; 315 | border: 1px solid #E1E1E1; 316 | border-radius: 4px; } 317 | pre > code { 318 | display: block; 319 | padding: 1rem 1.5rem; 320 | white-space: pre; } 321 | 322 | 323 | /* Tables 324 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 325 | th, 326 | td { 327 | padding: 12px 15px; 328 | text-align: left; 329 | border-bottom: 1px solid #E1E1E1; } 330 | th:first-child, 331 | td:first-child { 332 | padding-left: 0; } 333 | th:last-child, 334 | td:last-child { 335 | padding-right: 0; } 336 | 337 | 338 | /* Spacing 339 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 340 | button, 341 | .button { 342 | margin-bottom: 1rem; } 343 | input, 344 | textarea, 345 | select, 346 | fieldset { 347 | margin-bottom: 1.5rem; } 348 | pre, 349 | blockquote, 350 | dl, 351 | figure, 352 | table, 353 | p, 354 | ul, 355 | ol, 356 | form { 357 | margin-bottom: 2.5rem; } 358 | 359 | 360 | /* Utilities 361 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 362 | .u-full-width { 363 | width: 100%; 364 | box-sizing: border-box; } 365 | .u-max-full-width { 366 | max-width: 100%; 367 | box-sizing: border-box; } 368 | .u-pull-right { 369 | float: right; } 370 | .u-pull-left { 371 | float: left; } 372 | 373 | 374 | /* Misc 375 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 376 | hr { 377 | margin-top: 3rem; 378 | margin-bottom: 3.5rem; 379 | border-width: 0; 380 | border-top: 1px solid #E1E1E1; } 381 | 382 | 383 | /* Clearing 384 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 385 | 386 | /* Self Clearing Goodness */ 387 | .container:after, 388 | .row:after, 389 | .u-cf { 390 | content: ""; 391 | display: table; 392 | clear: both; } 393 | 394 | 395 | /* Media Queries 396 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 397 | /* 398 | Note: The best way to structure the use of media queries is to create the queries 399 | near the relevant code. For example, if you wanted to change the styles for buttons 400 | on small devices, paste the mobile query code up in the buttons section and style it 401 | there. 402 | */ 403 | 404 | 405 | /* Larger than mobile */ 406 | @media (min-width: 400px) {} 407 | 408 | /* Larger than phablet (also point when grid becomes active) */ 409 | @media (min-width: 550px) {} 410 | 411 | /* Larger than tablet */ 412 | @media (min-width: 750px) {} 413 | 414 | /* Larger than desktop */ 415 | @media (min-width: 1000px) {} 416 | 417 | /* Larger than Desktop HD */ 418 | @media (min-width: 1200px) {} 419 | -------------------------------------------------------------------------------- /vue-2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "esModuleInterop": true, 10 | "allowSyntheticDefaultImports": true, 11 | "experimentalDecorators": true, 12 | "noImplicitAny": false, 13 | "sourceMap": true, 14 | "baseUrl": ".", 15 | "types": [ 16 | "webpack-env" 17 | ], 18 | "paths": { 19 | "@/*": [ 20 | "src/*" 21 | ] 22 | }, 23 | "lib": [ 24 | "esnext", 25 | "dom", 26 | "dom.iterable", 27 | "scripthost" 28 | ] 29 | }, 30 | "include": [ 31 | "src/**/*.ts", 32 | "src/**/*.tsx", 33 | "src/**/*.vue", 34 | "tests/**/*.ts", 35 | "tests/**/*.tsx" 36 | ], 37 | "exclude": [ 38 | "node_modules" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /vue-2/vue.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | const path = require('path') 3 | 4 | module.exports = { 5 | configureWebpack (config) { 6 | config.devtool = 'source-map' 7 | }, 8 | 9 | chainWebpack: (config) => { 10 | config.resolve.symlinks(false) 11 | config.resolve.alias.set('vue$', path.resolve(__dirname, 'node_modules/vue/')) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /vue-3/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /vue-3/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /vue-3/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | extends: [ 7 | 'plugin:vue/vue3-essential', 8 | '@vue/standard', 9 | '@vue/typescript/recommended', 10 | ], 11 | parserOptions: { 12 | ecmaVersion: 2020, 13 | }, 14 | rules: { 15 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 16 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 17 | 'comma-dangle': ['error', 'only-multiline'], 18 | 'brace-style': ['error', 'stroustrup'], 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /vue-3/.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 | -------------------------------------------------------------------------------- /vue-3/README.md: -------------------------------------------------------------------------------- 1 | # vue-composition-store 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /vue-3/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vue-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-class-store-demo-vue-3", 3 | "description": "Vue 3 demo of Vue Class Store", 4 | "version": "1.0.0", 5 | "private": true, 6 | "scripts": { 7 | "serve": "vue-cli-service serve", 8 | "build": "vue-cli-service build", 9 | "lint": "vue-cli-service lint" 10 | }, 11 | "dependencies": { 12 | "core-js": "^3.6.4", 13 | "vue": "^3.0.0-beta.14", 14 | "vue-class-store": "^3.0.0", 15 | "vue-router": "^4.0.0-alpha.11" 16 | }, 17 | "devDependencies": { 18 | "@typescript-eslint/eslint-plugin": "^2.26.0", 19 | "@typescript-eslint/parser": "^2.26.0", 20 | "@vue/cli-plugin-babel": "~4.3.0", 21 | "@vue/cli-plugin-eslint": "~4.3.0", 22 | "@vue/cli-plugin-router": "~4.3.0", 23 | "@vue/cli-plugin-typescript": "~4.3.0", 24 | "@vue/cli-service": "~4.3.0", 25 | "@vue/compiler-sfc": "^3.0.0-beta.1", 26 | "@vue/eslint-config-standard": "^5.1.2", 27 | "@vue/eslint-config-typescript": "^5.0.2", 28 | "eslint": "^6.7.2", 29 | "eslint-plugin-import": "^2.20.2", 30 | "eslint-plugin-node": "^11.1.0", 31 | "eslint-plugin-promise": "^4.2.1", 32 | "eslint-plugin-standard": "^4.0.0", 33 | "eslint-plugin-vue": "^7.0.0-alpha.0", 34 | "lint-staged": "^9.5.0", 35 | "typescript": "~3.8.3", 36 | "vue-cli-plugin-vue-next": "~0.1.2" 37 | }, 38 | "gitHooks": { 39 | "pre-commit": "lint-staged" 40 | }, 41 | "lint-staged": { 42 | "*.{js,jsx,vue,ts,tsx}": [ 43 | "vue-cli-service lint", 44 | "git add" 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /vue-3/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davestewart/vue-class-store-demos/64d1987b2e284a65cf3cc25f0007a0cf00cd5394/vue-3/public/favicon.ico -------------------------------------------------------------------------------- /vue-3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vue-3/src/components/App.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /vue-3/src/components/CodeView.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 37 | -------------------------------------------------------------------------------- /vue-3/src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 41 | -------------------------------------------------------------------------------- /vue-3/src/components/RectangleView.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 25 | -------------------------------------------------------------------------------- /vue-3/src/examples/class-store/basic/Rectangle.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | 3 | export class Rectangle { 4 | public width: number 5 | 6 | public height: number 7 | 8 | public logs: string[] = [] 9 | 10 | constructor (width = 2, height = 2) { 11 | this.width = width 12 | this.height = height 13 | this.log('Rectangle constructor called!') 14 | } 15 | 16 | get area () { 17 | return this.width * this.height 18 | } 19 | 20 | 'on:area' (value) { 21 | this.log(`Area is ${value}`) 22 | } 23 | 24 | randomize () { 25 | this.width = Math.random() * 20 26 | this.height = Math.random() * 10 27 | } 28 | 29 | log (message) { 30 | this.logs.push(`${new Date().toISOString().match(/\d{2}:\d{2}:\d{2}/)}: ${message}`) 31 | } 32 | } 33 | 34 | @VueStore 35 | export class RectangleStore extends Rectangle { 36 | // there's no need to provide a constructor here, this is just to log some output 37 | constructor (width, height) { 38 | super(width, height) 39 | this.log('RectangleStore constructor called!') 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /vue-3/src/examples/class-store/basic/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 32 | -------------------------------------------------------------------------------- /vue-3/src/examples/class-store/global/Item.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 41 | 42 | 62 | -------------------------------------------------------------------------------- /vue-3/src/examples/class-store/global/ItemsStore.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | 3 | let id = 1 4 | 5 | export class ItemModel { 6 | public id: number 7 | public title: string 8 | 9 | constructor () { 10 | this.id = id++ 11 | this.title = `Item ${this.id}` 12 | } 13 | } 14 | 15 | @VueStore 16 | export class ItemsStore { 17 | public items: ItemModel[] = [] 18 | 19 | public selectedIds: number[] = [] 20 | 21 | constructor (numItems = 0) { 22 | for (let i = 0; i < numItems; i++) { 23 | this.addItem() 24 | } 25 | } 26 | 27 | get numSelected () { 28 | return this.selectedIds.length 29 | } 30 | 31 | addItem () { 32 | this.items.push(new ItemModel()) 33 | } 34 | 35 | toggleRandom () { 36 | const item = this.items[Math.floor(Math.random() * this.items.length)] 37 | this.toggleItem(item.id) 38 | } 39 | 40 | toggleItem (id: number) { 41 | const index = this.selectedIds.indexOf(id) 42 | index === -1 43 | ? this.selectedIds.push(id) 44 | : this.selectedIds.splice(index, 1) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vue-3/src/examples/class-store/global/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 43 | 44 | 49 | -------------------------------------------------------------------------------- /vue-3/src/examples/class-store/inherit/Square.ts: -------------------------------------------------------------------------------- 1 | import VueStore from 'vue-class-store' 2 | import { Rectangle } from '../basic/Rectangle' 3 | 4 | export class Square extends Rectangle { 5 | constructor (size) { 6 | super(size, size) 7 | this.log('Square constructor called!') 8 | } 9 | 10 | 'on:width' = 'update' 11 | 12 | 'on:height' = 'update' 13 | 14 | randomize () { 15 | this.width = this.height = Math.random() * 20 16 | } 17 | 18 | update (value) { 19 | this.width = value 20 | this.height = value 21 | } 22 | } 23 | 24 | @VueStore 25 | export class SquareStore extends Square { 26 | // there's no need to provide a constructor here, this is just to log some output 27 | constructor (size) { 28 | super(size) 29 | this.log('SquareStore constructor called!') 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /vue-3/src/examples/class-store/inherit/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 34 | -------------------------------------------------------------------------------- /vue-3/src/examples/class-store/inline/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 32 | -------------------------------------------------------------------------------- /vue-3/src/examples/index.js: -------------------------------------------------------------------------------- 1 | import store from './class-store/basic/index.vue' 2 | import inline from './class-store/inline/index.vue' 3 | import inheritance from './class-store/inherit/index.vue' 4 | import global from './class-store/global/index.vue' 5 | import computed from './vue/setup-function/index.vue' 6 | import reatciveModel from './vue/reactive-model/index.vue' 7 | import reactiveHelper from './vue/reactive-helper/index.vue' 8 | 9 | export { 10 | store, 11 | inline, 12 | inheritance, 13 | global, 14 | computed, 15 | reatciveModel, 16 | reactiveHelper, 17 | } 18 | -------------------------------------------------------------------------------- /vue-3/src/examples/vue/reactive-helper/factory.ts: -------------------------------------------------------------------------------- 1 | import { ref, watch, computed, reactive } from 'vue' 2 | 3 | export default function (w = 2, h = 2) { 4 | const data = reactive({ 5 | width: ref(w), 6 | height: ref(h), 7 | logs: ref([] as string[]), 8 | area: computed(() => data.width.value * data.height.value), 9 | randomize () { 10 | data.width.value = Math.random() * 20 11 | data.height.value = Math.random() * 10 12 | }, 13 | log (message) { 14 | data.logs.value.push(`${new Date().toISOString().match(/\d{2}:\d{2}:\d{2}/)}: ${message}`) 15 | } 16 | }) 17 | 18 | watch(data.area, function (value) { 19 | // how do you get access to this? 20 | // this.log(`Area is ${value}`) 21 | console.log('value', value) 22 | }) 23 | 24 | data.log('Vue Component created!') 25 | 26 | return data 27 | } 28 | -------------------------------------------------------------------------------- /vue-3/src/examples/vue/reactive-helper/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 30 | -------------------------------------------------------------------------------- /vue-3/src/examples/vue/reactive-model/factory.ts: -------------------------------------------------------------------------------- 1 | import { ref, watch, computed } from 'vue' 2 | 3 | export default function (w = 2, h = 2) { 4 | const width = ref(w) 5 | const height = ref(h) 6 | const logs = ref([] as string[]) 7 | const area = computed(() => width.value * height.value) 8 | 9 | function randomize () { 10 | width.value = Math.random() * 20 11 | height.value = Math.random() * 10 12 | } 13 | 14 | function log (message) { 15 | logs.value.push(`${new Date().toISOString().match(/\d{2}:\d{2}:\d{2}/)}: ${message}`) 16 | } 17 | 18 | watch(area, function (value) { 19 | log(`Area is ${value}`) 20 | }) 21 | 22 | log('Vue Component created!') 23 | 24 | return { 25 | width, 26 | height, 27 | logs, 28 | area, 29 | randomize, 30 | log 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /vue-3/src/examples/vue/reactive-model/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 30 | -------------------------------------------------------------------------------- /vue-3/src/examples/vue/setup-function/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 60 | -------------------------------------------------------------------------------- /vue-3/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import router from './router' 3 | import App from './components/App.vue' 4 | import RectangleView from './components/RectangleView.vue' 5 | import CodeView from './components/CodeView.vue' 6 | import './styles/index.css' 7 | 8 | // setup and mount 9 | createApp(App) 10 | .component('RectangleView', RectangleView) 11 | .component('CodeView', CodeView) 12 | .use(router) 13 | .mount('#app') 14 | -------------------------------------------------------------------------------- /vue-3/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router' 2 | 3 | import Home from '../components/Home.vue' 4 | import * as examples from '../examples' 5 | 6 | function route (path, component, folder = '') { 7 | const title = (component.name || '').replace(/([a-z])([A-Z])/g, '$1 $2') 8 | return { path, component, title, meta: { folder, title } } 9 | } 10 | 11 | function example (path, component) { 12 | const parts = component.__file.split('/') 13 | return route(`/${parts[2] + path}`, component, parts[2]) 14 | } 15 | 16 | export function getRoutes () { 17 | return Object.keys(examples).map((key) => { 18 | const component = examples[key] 19 | return example('/' + key, component) 20 | }) 21 | } 22 | 23 | const routes = [ 24 | route('/', Home), 25 | ...getRoutes() 26 | ] 27 | 28 | const router = createRouter({ 29 | history: createWebHistory(process.env.BASE_URL), 30 | routes 31 | }) 32 | 33 | export default router 34 | -------------------------------------------------------------------------------- /vue-3/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | export default Vue 4 | } 5 | -------------------------------------------------------------------------------- /vue-3/src/styles/index.css: -------------------------------------------------------------------------------- 1 | @import './normalize.css'; 2 | @import './skeleton.css'; 3 | 4 | body { 5 | padding: 3rem; 6 | } 7 | 8 | pre { 9 | font-family: unset; 10 | } 11 | 12 | p { 13 | margin-bottom: 1em; 14 | } 15 | 16 | ul { 17 | margin-left: 3rem; 18 | } 19 | 20 | li { 21 | margin-bottom: .2em; 22 | } 23 | 24 | input, button { 25 | margin-right: .5em; 26 | } 27 | -------------------------------------------------------------------------------- /vue-3/src/styles/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | -moz-box-sizing: content-box; 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-appearance: textfield; /* 1 */ 359 | -moz-box-sizing: content-box; 360 | -webkit-box-sizing: content-box; /* 2 */ 361 | box-sizing: content-box; 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | border: 1px solid #c0c0c0; 381 | margin: 0 2px; 382 | padding: 0.35em 0.625em 0.75em; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | border: 0; /* 1 */ 392 | padding: 0; /* 2 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-collapse: collapse; 421 | border-spacing: 0; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } -------------------------------------------------------------------------------- /vue-3/src/styles/skeleton.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V2.0.4 3 | * Copyright 2014, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 12/29/2014 8 | */ 9 | 10 | 11 | /* Table of contents 12 | –––––––––––––––––––––––––––––––––––––––––––––––––– 13 | - Grid 14 | - Base Styles 15 | - Typography 16 | - Links 17 | - Buttons 18 | - Forms 19 | - Lists 20 | - Code 21 | - Tables 22 | - Spacing 23 | - Utilities 24 | - Clearing 25 | - Media Queries 26 | */ 27 | 28 | 29 | /* Grid 30 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 31 | .container { 32 | position: relative; 33 | width: 100%; 34 | max-width: 960px; 35 | margin: 0 auto; 36 | padding: 0 20px; 37 | box-sizing: border-box; } 38 | .column, 39 | .columns { 40 | width: 100%; 41 | float: left; 42 | box-sizing: border-box; } 43 | 44 | /* For devices larger than 400px */ 45 | @media (min-width: 400px) { 46 | .container { 47 | width: 85%; 48 | padding: 0; } 49 | } 50 | 51 | /* For devices larger than 550px */ 52 | @media (min-width: 550px) { 53 | .container { 54 | width: 80%; } 55 | .column, 56 | .columns { 57 | margin-left: 4%; } 58 | .column:first-child, 59 | .columns:first-child { 60 | margin-left: 0; } 61 | 62 | .one.column, 63 | .one.columns { width: 4.66666666667%; } 64 | .two.columns { width: 13.3333333333%; } 65 | .three.columns { width: 22%; } 66 | .four.columns { width: 30.6666666667%; } 67 | .five.columns { width: 39.3333333333%; } 68 | .six.columns { width: 48%; } 69 | .seven.columns { width: 56.6666666667%; } 70 | .eight.columns { width: 65.3333333333%; } 71 | .nine.columns { width: 74.0%; } 72 | .ten.columns { width: 82.6666666667%; } 73 | .eleven.columns { width: 91.3333333333%; } 74 | .twelve.columns { width: 100%; margin-left: 0; } 75 | 76 | .one-third.column { width: 30.6666666667%; } 77 | .two-thirds.column { width: 65.3333333333%; } 78 | 79 | .one-half.column { width: 48%; } 80 | 81 | /* Offsets */ 82 | .offset-by-one.column, 83 | .offset-by-one.columns { margin-left: 8.66666666667%; } 84 | .offset-by-two.column, 85 | .offset-by-two.columns { margin-left: 17.3333333333%; } 86 | .offset-by-three.column, 87 | .offset-by-three.columns { margin-left: 26%; } 88 | .offset-by-four.column, 89 | .offset-by-four.columns { margin-left: 34.6666666667%; } 90 | .offset-by-five.column, 91 | .offset-by-five.columns { margin-left: 43.3333333333%; } 92 | .offset-by-six.column, 93 | .offset-by-six.columns { margin-left: 52%; } 94 | .offset-by-seven.column, 95 | .offset-by-seven.columns { margin-left: 60.6666666667%; } 96 | .offset-by-eight.column, 97 | .offset-by-eight.columns { margin-left: 69.3333333333%; } 98 | .offset-by-nine.column, 99 | .offset-by-nine.columns { margin-left: 78.0%; } 100 | .offset-by-ten.column, 101 | .offset-by-ten.columns { margin-left: 86.6666666667%; } 102 | .offset-by-eleven.column, 103 | .offset-by-eleven.columns { margin-left: 95.3333333333%; } 104 | 105 | .offset-by-one-third.column, 106 | .offset-by-one-third.columns { margin-left: 34.6666666667%; } 107 | .offset-by-two-thirds.column, 108 | .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } 109 | 110 | .offset-by-one-half.column, 111 | .offset-by-one-half.columns { margin-left: 52%; } 112 | 113 | } 114 | 115 | 116 | /* Base Styles 117 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 118 | /* NOTE 119 | html is set to 62.5% so that all the REM measurements throughout Skeleton 120 | are based on 10px sizing. So basically 1.5rem = 15px :) */ 121 | html { 122 | font-size: 62.5%; } 123 | body { 124 | font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ 125 | line-height: 1.6; 126 | font-weight: 400; 127 | font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; 128 | color: #222; } 129 | 130 | 131 | /* Typography 132 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 133 | h1, h2, h3, h4, h5, h6 { 134 | margin-top: 0; 135 | margin-bottom: 2rem; 136 | font-weight: 300; } 137 | h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} 138 | h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } 139 | h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } 140 | h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } 141 | h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } 142 | h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } 143 | 144 | /* Larger than phablet */ 145 | @media (min-width: 550px) { 146 | h1 { font-size: 5.0rem; } 147 | h2 { font-size: 4.2rem; } 148 | h3 { font-size: 3.6rem; } 149 | h4 { font-size: 3.0rem; } 150 | h5 { font-size: 2.4rem; } 151 | h6 { font-size: 1.5rem; } 152 | } 153 | 154 | p { 155 | margin-top: 0; } 156 | 157 | 158 | /* Links 159 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 160 | a { 161 | color: #1EAEDB; } 162 | a:hover { 163 | color: #0FA0CE; } 164 | 165 | 166 | /* Buttons 167 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 168 | .button, 169 | button, 170 | input[type="submit"], 171 | input[type="reset"], 172 | input[type="button"] { 173 | display: inline-block; 174 | height: 38px; 175 | padding: 0 30px; 176 | color: #555; 177 | text-align: center; 178 | font-size: 11px; 179 | font-weight: 600; 180 | line-height: 38px; 181 | letter-spacing: .1rem; 182 | text-transform: uppercase; 183 | text-decoration: none; 184 | white-space: nowrap; 185 | background-color: transparent; 186 | border-radius: 4px; 187 | border: 1px solid #bbb; 188 | cursor: pointer; 189 | box-sizing: border-box; } 190 | .button:hover, 191 | button:hover, 192 | input[type="submit"]:hover, 193 | input[type="reset"]:hover, 194 | input[type="button"]:hover, 195 | .button:focus, 196 | button:focus, 197 | input[type="submit"]:focus, 198 | input[type="reset"]:focus, 199 | input[type="button"]:focus { 200 | color: #333; 201 | border-color: #888; 202 | outline: 0; } 203 | .button.button-primary, 204 | button.button-primary, 205 | input[type="submit"].button-primary, 206 | input[type="reset"].button-primary, 207 | input[type="button"].button-primary { 208 | color: #FFF; 209 | background-color: #33C3F0; 210 | border-color: #33C3F0; } 211 | .button.button-primary:hover, 212 | button.button-primary:hover, 213 | input[type="submit"].button-primary:hover, 214 | input[type="reset"].button-primary:hover, 215 | input[type="button"].button-primary:hover, 216 | .button.button-primary:focus, 217 | button.button-primary:focus, 218 | input[type="submit"].button-primary:focus, 219 | input[type="reset"].button-primary:focus, 220 | input[type="button"].button-primary:focus { 221 | color: #FFF; 222 | background-color: #1EAEDB; 223 | border-color: #1EAEDB; } 224 | 225 | 226 | /* Forms 227 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 228 | input[type="email"], 229 | input[type="number"], 230 | input[type="search"], 231 | input[type="text"], 232 | input[type="tel"], 233 | input[type="url"], 234 | input[type="password"], 235 | textarea, 236 | select { 237 | height: 38px; 238 | padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ 239 | background-color: #fff; 240 | border: 1px solid #D1D1D1; 241 | border-radius: 4px; 242 | box-shadow: none; 243 | box-sizing: border-box; } 244 | /* Removes awkward default styles on some inputs for iOS */ 245 | input[type="email"], 246 | input[type="number"], 247 | input[type="search"], 248 | input[type="text"], 249 | input[type="tel"], 250 | input[type="url"], 251 | input[type="password"], 252 | textarea { 253 | -webkit-appearance: none; 254 | -moz-appearance: none; 255 | appearance: none; } 256 | textarea { 257 | min-height: 65px; 258 | padding-top: 6px; 259 | padding-bottom: 6px; } 260 | input[type="email"]:focus, 261 | input[type="number"]:focus, 262 | input[type="search"]:focus, 263 | input[type="text"]:focus, 264 | input[type="tel"]:focus, 265 | input[type="url"]:focus, 266 | input[type="password"]:focus, 267 | textarea:focus, 268 | select:focus { 269 | border: 1px solid #33C3F0; 270 | outline: 0; } 271 | label, 272 | legend { 273 | display: block; 274 | margin-bottom: .5rem; 275 | font-weight: 600; } 276 | fieldset { 277 | padding: 0; 278 | border-width: 0; } 279 | input[type="checkbox"], 280 | input[type="radio"] { 281 | display: inline; } 282 | label > .label-body { 283 | display: inline-block; 284 | margin-left: .5rem; 285 | font-weight: normal; } 286 | 287 | 288 | /* Lists 289 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 290 | ul { 291 | list-style: circle inside; } 292 | ol { 293 | list-style: decimal inside; } 294 | ol, ul { 295 | padding-left: 0; 296 | margin-top: 0; } 297 | ul ul, 298 | ul ol, 299 | ol ol, 300 | ol ul { 301 | margin: 1.5rem 0 1.5rem 3rem; 302 | font-size: 90%; } 303 | li { 304 | margin-bottom: 1rem; } 305 | 306 | 307 | /* Code 308 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 309 | code { 310 | padding: .2rem .5rem; 311 | margin: 0 .2rem; 312 | font-size: 90%; 313 | white-space: nowrap; 314 | background: #F1F1F1; 315 | border: 1px solid #E1E1E1; 316 | border-radius: 4px; } 317 | pre > code { 318 | display: block; 319 | padding: 1rem 1.5rem; 320 | white-space: pre; } 321 | 322 | 323 | /* Tables 324 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 325 | th, 326 | td { 327 | padding: 12px 15px; 328 | text-align: left; 329 | border-bottom: 1px solid #E1E1E1; } 330 | th:first-child, 331 | td:first-child { 332 | padding-left: 0; } 333 | th:last-child, 334 | td:last-child { 335 | padding-right: 0; } 336 | 337 | 338 | /* Spacing 339 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 340 | button, 341 | .button { 342 | margin-bottom: 1rem; } 343 | input, 344 | textarea, 345 | select, 346 | fieldset { 347 | margin-bottom: 1.5rem; } 348 | pre, 349 | blockquote, 350 | dl, 351 | figure, 352 | table, 353 | p, 354 | ul, 355 | ol, 356 | form { 357 | margin-bottom: 2.5rem; } 358 | 359 | 360 | /* Utilities 361 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 362 | .u-full-width { 363 | width: 100%; 364 | box-sizing: border-box; } 365 | .u-max-full-width { 366 | max-width: 100%; 367 | box-sizing: border-box; } 368 | .u-pull-right { 369 | float: right; } 370 | .u-pull-left { 371 | float: left; } 372 | 373 | 374 | /* Misc 375 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 376 | hr { 377 | margin-top: 3rem; 378 | margin-bottom: 3.5rem; 379 | border-width: 0; 380 | border-top: 1px solid #E1E1E1; } 381 | 382 | 383 | /* Clearing 384 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 385 | 386 | /* Self Clearing Goodness */ 387 | .container:after, 388 | .row:after, 389 | .u-cf { 390 | content: ""; 391 | display: table; 392 | clear: both; } 393 | 394 | 395 | /* Media Queries 396 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 397 | /* 398 | Note: The best way to structure the use of media queries is to create the queries 399 | near the relevant code. For example, if you wanted to change the styles for buttons 400 | on small devices, paste the mobile query code up in the buttons section and style it 401 | there. 402 | */ 403 | 404 | 405 | /* Larger than mobile */ 406 | @media (min-width: 400px) {} 407 | 408 | /* Larger than phablet (also point when grid becomes active) */ 409 | @media (min-width: 550px) {} 410 | 411 | /* Larger than tablet */ 412 | @media (min-width: 750px) {} 413 | 414 | /* Larger than desktop */ 415 | @media (min-width: 1000px) {} 416 | 417 | /* Larger than Desktop HD */ 418 | @media (min-width: 1200px) {} 419 | -------------------------------------------------------------------------------- /vue-3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "noImplicitAny": false, 8 | "importHelpers": true, 9 | "moduleResolution": "node", 10 | "esModuleInterop": true, 11 | "experimentalDecorators": true, 12 | "allowSyntheticDefaultImports": true, 13 | "sourceMap": true, 14 | "baseUrl": ".", 15 | "types": [ 16 | "node", 17 | "webpack-env" 18 | ], 19 | "paths": { 20 | "@/*": [ 21 | "src/*" 22 | ] 23 | }, 24 | "lib": [ 25 | "esnext", 26 | "dom", 27 | "dom.iterable", 28 | "scripthost" 29 | ] 30 | }, 31 | "include": [ 32 | "src/**/*.ts", 33 | "src/**/*.tsx", 34 | "src/**/*.vue", 35 | "tests/**/*.ts", 36 | "tests/**/*.tsx" 37 | ], 38 | "exclude": [ 39 | "node_modules" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /vue-3/vue.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | const path = require('path') 3 | 4 | module.exports = { 5 | chainWebpack: (config) => { 6 | config.resolve.symlinks(false) 7 | config.resolve.alias.set('vue$', path.resolve(__dirname, 'node_modules/vue/')) 8 | }, 9 | } 10 | --------------------------------------------------------------------------------