├── .gitignore ├── README.md ├── lerna.json ├── package.json ├── packages ├── vue-book-nuxt-example │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── assets │ │ └── README.md │ ├── components │ │ ├── Logo.vue │ │ ├── README.md │ │ ├── some.demo.vue │ │ └── someOther.demo.vue │ ├── layouts │ │ ├── README.md │ │ └── default.vue │ ├── middleware │ │ └── README.md │ ├── nuxt.config.js │ ├── package.json │ ├── pages │ │ ├── README.md │ │ ├── book │ │ │ └── _.vue │ │ └── index.vue │ ├── plugins │ │ ├── README.md │ │ └── vue-book.js │ ├── static │ │ ├── README.md │ │ └── favicon.ico │ ├── store │ │ └── README.md │ ├── tsconfig.json │ └── yarn.lock └── vue-book │ ├── .browserslistrc │ ├── .circleci │ └── config.yml │ ├── .editorconfig │ ├── .eslintignore │ ├── .eslintrc.js │ ├── .gitignore │ ├── .npmignore │ ├── .postcssrc.js │ ├── babel.config.js │ ├── circle.yml │ ├── demo │ ├── App.vue │ ├── SeveralInstances.vue │ ├── components │ │ ├── Child1.vue │ │ ├── Child2.vue │ │ ├── ChildWithoutDemo1.vue │ │ ├── ChildWithoutDemo2.vue │ │ ├── Grandparent.vue │ │ ├── Parent.vue │ │ └── ParentWithoutDemo.vue │ ├── index.html │ ├── main.ts │ ├── routes.ts │ └── tree │ │ ├── Children │ │ ├── ChildOne.vue │ │ ├── ChildTwo.vue │ │ └── Grandchildren │ │ │ ├── GrandchildOne.vue │ │ │ └── GrandchildTwo.vue │ │ ├── ContactComponent.vue │ │ ├── Layout │ │ └── LargeBlueSquare.vue │ │ ├── ManyComponents │ │ ├── Component10.vue │ │ ├── Component10000000000000000.vue │ │ ├── Component11.vue │ │ ├── Component12.vue │ │ ├── Component13.vue │ │ ├── Component14.vue │ │ ├── Component15.vue │ │ ├── Component16.vue │ │ ├── Component17.vue │ │ ├── Component18.vue │ │ ├── Component19.vue │ │ ├── Component2.vue │ │ ├── Component20.vue │ │ ├── Component21.vue │ │ ├── Component22.vue │ │ ├── Component23.vue │ │ ├── Component24.vue │ │ ├── Component25.vue │ │ ├── Component26.vue │ │ ├── Component27.vue │ │ ├── Component28.vue │ │ ├── Component29.vue │ │ ├── Component3.vue │ │ ├── Component30.vue │ │ ├── Component4.vue │ │ ├── Component5.vue │ │ ├── Component6.vue │ │ ├── Component7.vue │ │ ├── Component8.vue │ │ ├── Component9.vue │ │ └── ManyComponent1.vue │ │ └── Relations │ │ ├── Child1Demo.vue │ │ ├── Child2Demo.vue │ │ ├── GrandarentDemo.vue │ │ └── ParentDemo.vue │ ├── dev │ └── index.html │ ├── docs │ ├── deploy.md │ └── main.gif │ ├── jest.config.js │ ├── package.json │ ├── src │ ├── VbPageFactory.ts │ ├── app.ts │ ├── build │ │ └── webpack.config.dist.js │ ├── classes │ │ ├── Factory │ │ │ ├── DemoFolderFactory.ts │ │ │ └── TreeFileFactory.ts │ │ ├── Main │ │ │ ├── TreeFile.ts │ │ │ ├── TreeFileCollection.ts │ │ │ ├── TreeFolder.ts │ │ │ └── VueBookConfig.ts │ │ └── Mapper │ │ │ ├── DemoFolderMapper.ts │ │ │ └── TreeFileMapper.ts │ ├── components │ │ ├── DemoPage │ │ │ ├── ComButtonIcon │ │ │ │ ├── ComButtonIcon.demo.vue │ │ │ │ └── ComButtonIcon.vue │ │ │ ├── ComInput │ │ │ │ ├── VbInput.demo.vue │ │ │ │ └── VbInput.vue │ │ │ ├── DemoPageConfig.ts │ │ │ ├── DemoPageMenu.demo.vue │ │ │ ├── VbMenu.vue │ │ │ ├── VbNotFound.vue │ │ │ ├── VbPage.vue │ │ │ ├── VueBookTreeOptions.ts │ │ │ └── demo-file.md │ │ ├── Exposed │ │ │ ├── ContainerFocusService.ts │ │ │ ├── VbCard-focus.demo.vue │ │ │ ├── VbCard.demo.vue │ │ │ ├── VbCard.vue │ │ │ ├── VbDemo.vue │ │ │ └── __demo__ │ │ │ │ └── RefreshCounter.vue │ │ ├── FileTree │ │ │ ├── BookComponentListFolder.demo.vue │ │ │ ├── BookComponentListFolder.vue │ │ │ ├── BookComponentListItem.demo.vue │ │ │ ├── BookComponentListItem.vue │ │ │ ├── DemoFileList.demo.vue │ │ │ ├── DemoFileList.vue │ │ │ ├── ListCursor.ts │ │ │ └── TreeDemoFileList.vue │ │ └── Service │ │ │ └── VueBookResizeLine.vue │ ├── plugins │ │ └── font-awesome-config.ts │ ├── scss │ │ ├── app.scss │ │ ├── mixins │ │ │ └── mixins.scss │ │ ├── reset.scss │ │ ├── resources.scss │ │ ├── smart-grid │ │ │ ├── smart-grid-config.js │ │ │ └── smart-grid.scss │ │ └── variables │ │ │ ├── colors.scss │ │ │ └── variables.scss │ ├── services │ │ └── ScreenSizeService.ts │ ├── shims-tsx.d.ts │ ├── shims-vue.d.ts │ └── store │ │ ├── FoldersStore.ts │ │ ├── configStore.ts │ │ └── storage.ts │ ├── tests │ └── unit │ │ ├── DemoFolder.spec.ts │ │ └── DemoNode.spec.ts │ ├── tsconfig.json │ ├── vue-book.d.ts │ └── vue.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | # local env files 5 | .env.local 6 | .env.*.local 7 | 8 | # Log files 9 | inspect-result.js 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-book 2 | 3 | Tree view for your demo components. [Demo](http://vue-book.asva.by/#/Demo/ContactComponent.vue). 4 | 5 | ![Interface](packages/vue-book/docs/main.gif) 6 | 7 | ## Install 8 | 9 | * **npm**: `npm install -D vue-book` 10 | * **yarn**: `yarn add -D vue-book` 11 | 12 | ## Versions 13 | 14 | * Lastest build is a bit outdated and is not recommended (the one you get by `npm install -D vue-book`). 15 | * Recent vue 2 version is `0.1.0-alpha.42`. 16 | * Recent vue 3 version is `0.2.0-alpha.0`. 17 | 18 | You shouldn't worry about sitting on alpha version as vue-book doesn't have dependencies and will work for a very long time without issues. 19 | 20 | ## Features 21 | * Display your components as a tree or flat list. 22 | * Preview components on the page. 23 | * Text search. 24 | * Routing support. 25 | * Saves on page reload. 26 | 27 | ## The gist 28 | 29 | I'll talk a bit about demo based workflow I employ in my projects. 30 | 31 | Before doing any work on component I create a demo. Demo allows me to define an interface, like this: 32 | ```html 33 | 34 | ``` 35 | Only then I start to work on component. 36 | 37 | You can think of demo as of semi-manual unit tests. But why not use actual unit tests, you'll ask. Let me explain. 38 | * Demos are cheap. And you don't have to be a senior unit tester to create them. 39 | * Demos are visual. In many cases you can *see* if something goes wrong. But unit tests won't show any of your styling mistakes. 40 | * Demos are developer friendly. You can instantly find usage examples or just glance over existing components. Which is crucial for teamwork. 41 | 42 | Of course, this doesn't mean that you have to dump unit tests. Just keep them for appropriate tasks. Like logic heavy classes. 43 | 44 | So, back to the library. The main intent behind is simplifying demo workflow as much as possible. Just toss your demos into folder and enjoy tree generation. 45 | 46 | ## Config 47 | 48 | Attach VueComponentTree to your router. And yes, [vue-router](https://github.com/vuejs/vue-router) is required. 49 | ```js 50 | import Router from 'vue-router' 51 | import { createRoute } from 'vue-book' 52 | 53 | const router = new Router({ 54 | routes: [ 55 | createRoute({ 56 | requireContext: require.context('./..', true, /.demo.vue$/), 57 | path: '/demo', 58 | hideFileExtensions: true, // optional, hides file extensions in list. 59 | hideNavigation: true, // optional, hides navigation panel. Intended to be used with visual recognition library. 60 | }), 61 | ] 62 | }) 63 | ``` 64 | So, about arguments. 65 | 66 | `require.context('./../tree', true, /.vue$/), '/demo'` 67 | * `./../tree` is path to your demo folder. Works the same as require/import. 68 | * `/demo` is root route for vue-router. 69 | 70 | Here's the vue-cli3 [demo project](https://github.com/asvae/vue-book-demo) if something doesn't work for you. 71 | 72 | ### Production 73 | 74 | You don't have to keep demos in production. Use webpack [define-plugin](https://webpack.js.org/plugins/define-plugin/) and exclude them from bundle. 75 | 76 | ```javascript 77 | if (process.env.NODE_ENV !== 'production') { 78 | const createRoute = require('vue-book').createRoute 79 | 80 | routes.push([ 81 | createRoute({ 82 | requireContext: require.context('./..', true, /.demo.vue$/), 83 | path: '/demo', 84 | }), 85 | ]) 86 | } 87 | ``` 88 | 89 | ### Deploy 90 | 91 | * `yarn serve` - run dev server; 92 | * `yarn demo` - compile assets; 93 | * `yarn dist` - compile assets; 94 | * `npm publish` - publish to npm. 95 | 96 | 97 | ### Use as component 98 | 99 | You can use `vue-book` without router if you don't need it. 100 | 101 | ```javascript 102 | const getComponent = require('vue-book').getComponent 103 | 104 | const DemoView = getComponent({ 105 | requireContext: require.context('./..', true, /.demo.vue$/), 106 | }) 107 | ```` 108 | 109 | You can handle resulting `DemoView` the same as any other vue component. 110 | 111 | ## Feedback | Support 112 | Leave an issue if something doesn't work for you. 113 | 114 | Also remember: Stars fuel package development! 115 | 116 | ## Hooks 117 | In component you can use [`beforeRouteUpdate`](https://router.vuejs.org/guide/advanced/navigation-guards.html#in-component-guards). Common case is to reset some global service. 118 | 119 | ## Helper components [WIP] 120 | 121 | Vue book provides a bunch of helper components to simplify demo-building. 122 | 123 | ### VbDemo 124 | 125 | Root level container. 126 | 127 | ### VbCard 128 | 129 | You can consider this component as both 'card' and 'test-case'. 130 | 131 | **Props** 132 | 133 | * `title` - `string`. Title of the card. 134 | * `noPadding` - `boolean`. Removes padding of `VbCard` content 135 | * `dashed` - `boolean`. Makes card border dashed, which makes it easier to see in some cases. 136 | * `refresh` - `boolean`. Shows on card header a refresh button that redraws card content. Useful for testing reactivity. 137 | * `width` - `string`. Card width. 138 | * `height` - `string`. Card height. 139 | * `color` - `string`. Card color. 140 | * `dark` - `boolean`. Dark color theme. 141 | * `state` - `any`. Allows to pass a state which will be accessible in a scoped slot. For details - see below. 142 | * `focus` - `boolean`. If any `VbCard` is focused - only focused cards will be shown in demo. This is useful when you want to work on specific case and hide unneeded ones. 143 | * `error` - `boolean`. Shows red border for card. Intended purpose is to help PR reviewer to mark buggy cases. In merged codebase better idea is to create issues. 144 | 145 | #### State 146 | `state` prop creates a scoped state for single card. That means you can create multiple cards, that use the same values, but they won't conflict. Intended as a substitute for declaring every prop in `data`. 147 | 148 | ```vue 149 | 154 | 155 | 156 | ``` 157 | 158 | ### Install 159 | 160 | ```js 161 | import { VueBookComponents } from '../src/app' 162 | 163 | Vue.use(VueBookComponents) 164 | ``` 165 | 166 | Component helpers 167 | 168 | ```vue 169 | 170 | 171 | 172 | 173 | 174 | ``` 175 | 176 | Functional helpers: 177 | 178 | ```vue 179 | 180 | 181 |
Lorem text: {{ $vb.lorem() }}
182 |
Lorem text of length: {{ $vb.lorem(5) }}
183 | ``` 184 | 185 | ## Licence 186 | MIT 187 | 188 | [circleci-badge]: https://img.shields.io/circleci/project/github/asvae/vue-book/master.svg?style=flat-square 189 | [circleci-url]: https://circleci.com/gh/asvae/vue-book 190 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "useWorkspaces": true, 4 | "version": "1.0.0", 5 | "packages": [ 6 | "packages/*" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-book-root", 3 | "private": true, 4 | "devDependencies": { 5 | "lerna": "^3.16.4" 6 | }, 7 | "workspaces": [ 8 | "packages/*" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/.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 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/README.md: -------------------------------------------------------------------------------- 1 | # vue-book-nuxt-example 2 | 3 | ## Build Setup 4 | 5 | ```bash 6 | # install dependencies 7 | $ yarn install 8 | 9 | # serve with hot reload at localhost:3000 10 | $ yarn dev 11 | 12 | # build for production and launch server 13 | $ yarn build 14 | $ yarn start 15 | 16 | # generate static project 17 | $ yarn generate 18 | ``` 19 | 20 | For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org). 21 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked). 8 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 30 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/components/README.md: -------------------------------------------------------------------------------- 1 | # COMPONENTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | The components directory contains your Vue.js Components. 6 | 7 | _Nuxt.js doesn't supercharge these components._ 8 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/components/some.demo.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/components/someOther.demo.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/layouts/README.md: -------------------------------------------------------------------------------- 1 | # LAYOUTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Application Layouts. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts). 8 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 63 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your application middleware. 6 | Middleware let you define custom functions that can be run before rendering either a page or a group of pages. 7 | 8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). 9 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/nuxt.config.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | /* 4 | ** Nuxt rendering mode 5 | ** See https://nuxtjs.org/api/configuration-mode 6 | */ 7 | mode: 'universal', 8 | /* 9 | ** Nuxt target 10 | ** See https://nuxtjs.org/api/configuration-target 11 | */ 12 | target: 'server', 13 | /* 14 | ** Headers of the page 15 | ** See https://nuxtjs.org/api/configuration-head 16 | */ 17 | head: { 18 | title: process.env.npm_package_name || '', 19 | meta: [ 20 | { charset: 'utf-8' }, 21 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 22 | { hid: 'description', name: 'description', content: process.env.npm_package_description || '' } 23 | ], 24 | link: [ 25 | { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } 26 | ] 27 | }, 28 | /* 29 | ** Global CSS 30 | */ 31 | css: [ 32 | ], 33 | /* 34 | ** Plugins to load before mounting the App 35 | ** https://nuxtjs.org/guide/plugins 36 | */ 37 | plugins: [ 38 | { src: '~/plugins/vue-book.js', mode: 'client' }, 39 | ], 40 | /* 41 | ** Auto import components 42 | ** See https://nuxtjs.org/api/configuration-components 43 | */ 44 | components: true, 45 | /* 46 | ** Nuxt.js dev-modules 47 | */ 48 | buildModules: [ 49 | '@nuxt/typescript-build', 50 | ], 51 | /* 52 | ** Nuxt.js modules 53 | */ 54 | modules: [ 55 | ], 56 | /* 57 | ** Build configuration 58 | ** See https://nuxtjs.org/api/configuration-build/ 59 | */ 60 | build: { 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-book-nuxt-example", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "nuxt", 7 | "build": "nuxt-ts build", 8 | "start": "nuxt-ts start", 9 | "export": "nuxt-ts export", 10 | "serve": "nuxt-ts serve" 11 | }, 12 | "dependencies": { 13 | "@nuxt/typescript-runtime": "^2.0.0", 14 | "nuxt": "^2.14.7", 15 | "vue-book": "0.2.0-alpha.0" 16 | }, 17 | "devDependencies": { 18 | "@nuxt/typescript-build": "^2.0.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/pages/README.md: -------------------------------------------------------------------------------- 1 | # PAGES 2 | 3 | This directory contains your Application Views and Routes. 4 | The framework reads all the `*.vue` files inside this directory and creates the router of your application. 5 | 6 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing). 7 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/pages/book/_.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 32 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/pages/index.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 35 | 36 | 76 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). 8 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/plugins/vue-book.js: -------------------------------------------------------------------------------- 1 | import { VueBookComponents } from 'vue-book' 2 | import Vue from 'vue' 3 | 4 | Vue.use(VueBookComponents) 5 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your static files. 6 | Each file inside this directory is mapped to `/`. 7 | Thus you'd want to delete this README.md before deploying to production. 8 | 9 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 10 | 11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). 12 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvae/vue-book/93aeb6326dc1c8922c9196166a2154f54b35b5bd/packages/vue-book-nuxt-example/static/favicon.ico -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Vuex Store files. 6 | Vuex Store option is implemented in the Nuxt.js framework. 7 | 8 | Creating a file in this directory automatically activates the option in the framework. 9 | 10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). 11 | -------------------------------------------------------------------------------- /packages/vue-book-nuxt-example/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 | -------------------------------------------------------------------------------- /packages/vue-book/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /packages/vue-book/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | deploy: 8 | docker: 9 | - image: circleci/node:10.12.0 10 | parallelism: 1 11 | working_directory: ~/repo 12 | steps: 13 | - checkout 14 | - restore_cache: 15 | keys: 16 | - yarn-packages-{{ checksum "yarn.lock" }} 17 | - run: yarn install 18 | - save_cache: 19 | paths: 20 | - node_modules 21 | key: yarn-packages-{{ checksum "yarn.lock" }} 22 | - run: yarn build 23 | 24 | workflows: 25 | version: 2 26 | build-and-deploy: 27 | jobs: 28 | - deploy 29 | -------------------------------------------------------------------------------- /packages/vue-book/.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 | -------------------------------------------------------------------------------- /packages/vue-book/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /packages/vue-book/.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', 10 | 'plugin:vue/strongly-recommended', 11 | ], 12 | rules: { 13 | 'no-console': process.env.NODE_ENV === 'development' ? 'off' : 'error', 14 | 'no-debugger': process.env.NODE_ENV === 'development' ? 'off' : 'error', 15 | 'comma-dangle': ['error', 'always-multiline'], // simplifies merge requests 16 | 'curly': 'error', // for consistent if's 17 | 'camelcase': 'off', // to support generated types 18 | }, 19 | parserOptions: { 20 | parser: '@typescript-eslint/parser', 21 | }, 22 | 23 | // required to lint *.vue files 24 | plugins: [ 25 | 'vue', 26 | '@typescript-eslint', 27 | ], 28 | overrides: [ 29 | { 30 | files: [ 31 | '**/__tests__/*.{j,t}s?(x)', 32 | '**/tests/unit/**/*.spec.{j,t}s?(x)', 33 | ], 34 | env: { 35 | jest: true, 36 | }, 37 | }, 38 | ], 39 | } 40 | -------------------------------------------------------------------------------- /packages/vue-book/.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /public 3 | /coverage 4 | 5 | -------------------------------------------------------------------------------- /packages/vue-book/.npmignore: -------------------------------------------------------------------------------- 1 | !/dist 2 | /docs 3 | /demo 4 | /tests 5 | /src 6 | 7 | .circleci 8 | .idea 9 | .vscode 10 | 11 | -------------------------------------------------------------------------------- /packages/vue-book/.postcssrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | }, 5 | } -------------------------------------------------------------------------------- /packages/vue-book/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset', 4 | ], 5 | } 6 | -------------------------------------------------------------------------------- /packages/vue-book/circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 8.11.1 4 | 5 | dependencies: 6 | override: 7 | - yarn 8 | -------------------------------------------------------------------------------- /packages/vue-book/demo/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /packages/vue-book/demo/SeveralInstances.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 24 | 25 | 36 | -------------------------------------------------------------------------------- /packages/vue-book/demo/components/Child1.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /packages/vue-book/demo/components/Child2.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /packages/vue-book/demo/components/ChildWithoutDemo1.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /packages/vue-book/demo/components/ChildWithoutDemo2.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /packages/vue-book/demo/components/Grandparent.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | -------------------------------------------------------------------------------- /packages/vue-book/demo/components/Parent.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | -------------------------------------------------------------------------------- /packages/vue-book/demo/components/ParentWithoutDemo.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | 28 | -------------------------------------------------------------------------------- /packages/vue-book/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Webpack App 6 | 7 | 8 |
9 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import { VueBookComponents } from '../src/app' 3 | import App from './App.vue' 4 | import router from './routes' 5 | 6 | 7 | const app = createApp(App) 8 | app.use(VueBookComponents) 9 | app.use(router) 10 | // Vue.config.productionTip = false 11 | app.mount('#app') 12 | -------------------------------------------------------------------------------- /packages/vue-book/demo/routes.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router' 2 | 3 | import { createComponent, createRoute, VueBookComponents } from '../src/app' 4 | import SeveralInstances from './SeveralInstances.vue' 5 | 6 | const routes = [ 7 | createRoute({ 8 | requireContext: require.context('./tree', true, /.vue$/), 9 | path: '/demo', 10 | hideFileExtensions: true, 11 | // hideNavigation: true,TreeFileFactory 12 | }), 13 | // vue-book component mode testing 14 | { 15 | path: '/component-mode/:pathMatch(.*)*', 16 | component: createComponent({ 17 | path: '/component-mode', 18 | requireContext: require.context('./tree', true, /.vue$/), 19 | hideFileExtensions: true, 20 | }), 21 | }, 22 | // Test several vue-book instances in one page. 23 | { 24 | path: '/several-instances', 25 | component: SeveralInstances, 26 | }, 27 | // Internal components 28 | createRoute({ 29 | requireContext: require.context('./../src', true, /.demo.vue$/), 30 | path: '/src', 31 | hideFileExtensions: true, 32 | }), 33 | // Test case where no demo files exist. 34 | createRoute({ 35 | requireContext: require.context('./../src', true, /.test-empty.vue$/), 36 | path: '/empty', 37 | hideFileExtensions: true, 38 | }), 39 | { 40 | path: '/:pathMatch(.*)*', 41 | redirect: '/demo', 42 | }, 43 | ] 44 | 45 | const router = createRouter({ 46 | history: createWebHashHistory(), 47 | routes, 48 | }) 49 | 50 | export default router 51 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Children/ChildOne.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Children/ChildTwo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Children/Grandchildren/GrandchildOne.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Children/Grandchildren/GrandchildTwo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ContactComponent.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Layout/LargeBlueSquare.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component10.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component10000000000000000.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component11.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component12.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component13.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component14.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component15.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component16.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component17.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component18.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component19.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component2.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component20.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component21.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component22.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component23.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component24.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component25.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component26.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component27.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component28.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component29.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component3.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component30.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component4.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component5.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component6.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component7.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component8.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/Component9.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/ManyComponents/ManyComponent1.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Relations/Child1Demo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Relations/Child2Demo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Relations/GrandarentDemo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 18 | 19 | -------------------------------------------------------------------------------- /packages/vue-book/demo/tree/Relations/ParentDemo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 18 | 19 | -------------------------------------------------------------------------------- /packages/vue-book/dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Webpack App 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/vue-book/docs/deploy.md: -------------------------------------------------------------------------------- 1 | # Deploy documentation 2 | 3 | * Before deploy you have to manually change version in `packages/vue-book/package.json` 4 | 5 | * `npm publish --tag latest` to publish to latest (what majority of users will get). 6 | * `npm publish --tag next` to publish to alpha. Alpha versions look like this: `0.1.0-alpha.18`. 7 | 8 | -------------------------------------------------------------------------------- /packages/vue-book/docs/main.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvae/vue-book/93aeb6326dc1c8922c9196166a2154f54b35b5bd/packages/vue-book/docs/main.gif -------------------------------------------------------------------------------- /packages/vue-book/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel', 3 | 4 | // moduleFileExtensions: [ 5 | // 'ts', 6 | // 'tsx', 7 | // 'js', 8 | // 'jsx', 9 | // 'json', 10 | // 'vue', 11 | // ], 12 | // transform: { 13 | // '^.+\\.vue$': 'vue-jest', 14 | // '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 15 | // '^.+\\.tsx?$': 'ts-jest', 16 | // }, 17 | // moduleNameMapper: { 18 | // '^@/(.*)$': '/src/$1', 19 | // }, 20 | // snapshotSerializers: [ 21 | // 'jest-serializer-vue', 22 | // ], 23 | // testMatch: [ 24 | // '/(tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))', 25 | // ], 26 | } 27 | -------------------------------------------------------------------------------- /packages/vue-book/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-book", 3 | "version": "0.2.0-alpha.0", 4 | "description": "Tree view for your demo components", 5 | "main": "dist/js/app.js", 6 | "types": "vue-book.d.ts", 7 | "private": false, 8 | "author": "Yauheni Prakopchyk", 9 | "license": "MIT", 10 | "scripts": { 11 | "dist": "webpack --progress --hide-modules --config src/build/webpack.config.dist.js", 12 | "serve": "vue-cli-service serve --port 8093", 13 | "lint": "vue-cli-service lint", 14 | "test:unit": "vue-cli-service test:unit", 15 | "inspect": "vue inspect > inspect-result.js", 16 | "push": "yarn dist & npm publish --tag=next", 17 | "push-production": "yarn dist & npm publish --tag=latest" 18 | }, 19 | "keywords": [ 20 | "vue", 21 | "tree", 22 | "demo" 23 | ], 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/asvae/vue-book.git" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/asvae/vue-book/issues" 30 | }, 31 | "homepage": "https://github.com/asvae/vue-book#readme", 32 | "peerDependencies": { 33 | "vue": "^3.0.0" 34 | }, 35 | "dependencies": { 36 | "tslib": "^2.0.3" 37 | }, 38 | "devDependencies": { 39 | "@fortawesome/fontawesome-svg-core": "^1.2.32", 40 | "@fortawesome/free-solid-svg-icons": "^5.15.1", 41 | "@fortawesome/vue-fontawesome": "^3.0.0-2", 42 | "@types/jest": "^26.0.15", 43 | "@types/node": "^14.14.2", 44 | "@vue/cli-plugin-babel": "^4.5.8", 45 | "@vue/cli-plugin-eslint": "^4.5.8", 46 | "@vue/cli-plugin-router": "^4.5.8", 47 | "@vue/cli-plugin-typescript": "^4.5.8", 48 | "@vue/cli-plugin-unit-jest": "^4.5.8", 49 | "@vue/cli-service": "^4.5.8", 50 | "@vue/compiler-sfc": "^3.0.2", 51 | "@vue/eslint-config-standard": "^5.1.2", 52 | "@vue/eslint-config-typescript": "^7.0.0", 53 | "@vue/test-utils": "^1.1.0", 54 | "asva-executors": "^0.1.23", 55 | "asva-helpers": "^0.1.5", 56 | "clean-webpack-plugin": "^3.0.0", 57 | "core-js": "^3.6.5", 58 | "eslint": "^7.11.0", 59 | "eslint-plugin-vue": "^7.0.1", 60 | "lerna": "^3.22.1", 61 | "lint-staged": "^10.4.2", 62 | "sass": "^1.27.0", 63 | "sass-loader": "^10.0.3", 64 | "style-loader": "^2.0.0", 65 | "ts-jest": "^26.4.1", 66 | "ts-loader": "^8.0.6", 67 | "typescript": "~4.0.3", 68 | "vue": "^3.0.0", 69 | "vue-class-component": "^8.0.0-beta.4", 70 | "vue-loader-v16": "^16.0.0-beta.5.4", 71 | "vue-property-decorator": "^9.0.2", 72 | "vue-router": "^4.0.0-beta.13", 73 | "webpack": "^4.43.0", 74 | "webpack-bundle-analyzer": "^3.8.0", 75 | "webpack-cli": "^3.3.12" 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /packages/vue-book/src/VbPageFactory.ts: -------------------------------------------------------------------------------- 1 | import { VueBookConfig } from './classes/Main/VueBookConfig' 2 | import { TreeFileCollection } from './classes/Main/TreeFileCollection' 3 | import { TreeFile } from './classes/Main/TreeFile' 4 | import VbPage from './components/DemoPage/VbPage.vue' 5 | import { TreeFolder } from './classes/Main/TreeFolder' 6 | import { h, resolveComponent, resolveDynamicComponent } from 'vue' 7 | import { RouteRecordRaw } from 'vue-router' 8 | import { Vue } from 'vue-class-component' 9 | 10 | export const createVueBookComponent = (config: Partial) => { 11 | const configFull = new VueBookConfig(config) 12 | const requireContext = configFull.requireContext 13 | const path = configFull.path 14 | 15 | const treeFileCollection = new TreeFileCollection({ 16 | treeFiles: requireContext.keys().map((key: string) => { 17 | // requireContext(key).default - webpack 4 18 | // requireContext(key) - webpack 2 19 | const component = requireContext(key).default || requireContext(key) 20 | 21 | return new TreeFile({ 22 | path: path + key.substr(1), 23 | component, 24 | }) 25 | }), 26 | }) 27 | class VbPageWrapper extends Vue { 28 | render () { 29 | return h( 30 | resolveComponent('VbPage') as any, 31 | { 32 | treeFolder: TreeFolder.createFromDemoFileCollection(treeFileCollection), 33 | treeFileCollection: treeFileCollection, 34 | hideFileExtensions: configFull.hideFileExtensions, 35 | hideNavigation: configFull.hideNavigation, 36 | }, 37 | ) 38 | } 39 | } 40 | 41 | return VbPageWrapper 42 | } 43 | 44 | export const createVueBookRoute = (config: Partial): RouteRecordRaw => { 45 | const configFull = new VueBookConfig(config) 46 | return { 47 | path: configFull.path + ':pathMatch(.*)*', 48 | component: createVueBookComponent(configFull), 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/vue-book/src/app.ts: -------------------------------------------------------------------------------- 1 | import './scss/app.scss' 2 | import './plugins/font-awesome-config' 3 | import VbDemo from './components/Exposed/VbDemo.vue' 4 | import VbCard from './components/Exposed/VbCard.vue' 5 | import VbPage from './components/DemoPage/VbPage.vue' 6 | 7 | const loremString = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' 8 | 9 | export const VueBookComponents = { 10 | install: (app: any) => { 11 | // Register global components 12 | app.component('VbDemo', VbDemo) 13 | app.component('VbCard', VbCard) 14 | app.component('VbPage', VbPage) 15 | 16 | // Register global helpers 17 | app.config.globalProperties.$vb = { 18 | log: (message?: any, ...optionalParams: any[]): void => { 19 | // eslint-disable-next-line no-console 20 | console.log(message, ...optionalParams) 21 | }, 22 | alert: (message?: any): void => { 23 | alert(message) 24 | }, 25 | lorem: (length = loremString.length): string => { 26 | return [ 27 | ...Array(Math.floor(length / loremString.length)).fill(loremString), 28 | loremString.slice(0, (length % loremString.length)), 29 | ].join(' ') 30 | }, 31 | } 32 | }, 33 | } 34 | 35 | export { createVueBookRoute as createRoute, createVueBookComponent as createComponent } from './VbPageFactory' 36 | -------------------------------------------------------------------------------- /packages/vue-book/src/build/webpack.config.dist.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const { CleanWebpackPlugin } = require('clean-webpack-plugin') 3 | const VueLoader = require('vue-loader-v16') 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 5 | 6 | module.exports = { 7 | mode: 'production', 8 | resolve: { 9 | extensions: ['.ts', '.js'], 10 | alias: { 11 | 'vue$': 'vue/dist/vue.common.js', 12 | }, 13 | }, 14 | performance: { 15 | hints: false, 16 | }, 17 | optimization: { 18 | minimize: true, 19 | }, 20 | entry: './src/app.ts', 21 | output: { 22 | path: path.resolve(__dirname, '../../dist/js'), 23 | publicPath: '/', 24 | filename: 'app.js', 25 | library: 'VueBook', 26 | libraryTarget: 'umd', 27 | }, 28 | externals: { 29 | vue: 'vue', 30 | tslib: 'tslib', 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /\.scss$/, 36 | use: [ 37 | { loader: 'style-loader' }, 38 | { loader: 'css-loader' }, 39 | { loader: 'sass-loader' }, 40 | ], 41 | }, 42 | { 43 | test: /\.css$/, 44 | use: [ 45 | { loader: 'style-loader' }, 46 | { loader: 'css-loader' }, 47 | ], 48 | }, 49 | { 50 | test: /\.vue$/, 51 | use: [ 52 | { 53 | loader: 'vue-loader-v16', 54 | options: { 55 | 'vue-loader': require('vue-loader-v16/package.json').version, 56 | '@vue/compiler-sfc': require('@vue/compiler-sfc/package.json').version 57 | } 58 | } 59 | ] 60 | }, 61 | { 62 | test: /\.ts$/, 63 | loader: 'ts-loader', 64 | options: { 65 | appendTsSuffixTo: [/\.vue$/], 66 | }, 67 | }, 68 | // { 69 | // test: /\.js$/, 70 | // use: 'babel-loader', 71 | // exclude: /node_modules/, 72 | // }, 73 | { 74 | test: /\.(png|jpg|gif)$/, 75 | loader: 'file-loader', 76 | options: { 77 | name: '[name].[ext]?[hash]', 78 | }, 79 | }, 80 | { 81 | test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/, 82 | use: 'url-loader?limit=100000&name=[name].[ext]', 83 | exclude: path.resolve('./src/assets/svg'), 84 | }, 85 | ], 86 | }, 87 | plugins: [ 88 | new VueLoader.VueLoaderPlugin(), 89 | new CleanWebpackPlugin(), 90 | // new BundleAnalyzerPlugin(), 91 | ], 92 | devtool: '#source-map', 93 | } 94 | -------------------------------------------------------------------------------- /packages/vue-book/src/classes/Factory/DemoFolderFactory.ts: -------------------------------------------------------------------------------- 1 | import { TreeFolder } from '../Main/TreeFolder' 2 | import { TreeFileFactory } from './TreeFileFactory' 3 | 4 | export default class DemoFolderFactory { 5 | 6 | static getEmpty (): TreeFolder { 7 | return new TreeFolder({ 8 | name: 'name', 9 | }) 10 | } 11 | 12 | static getWithFiles (): TreeFolder { 13 | return new TreeFolder({ 14 | files: TreeFileFactory.getWithVariousStatuses(), 15 | name: 'name', 16 | }) 17 | } 18 | 19 | static getWithFolders (): TreeFolder { 20 | return new TreeFolder({ 21 | folders: [ 22 | DemoFolderFactory.getEmpty(), 23 | DemoFolderFactory.getEmpty(), 24 | ], 25 | name: 'name', 26 | }) 27 | } 28 | 29 | static getWithFoldersAndFiles (): TreeFolder { 30 | return new TreeFolder({ 31 | folders: [ 32 | DemoFolderFactory.getEmpty(), 33 | DemoFolderFactory.getEmpty(), 34 | ], 35 | files: TreeFileFactory.getWithVariousStatuses(), 36 | name: 'name', 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/vue-book/src/classes/Factory/TreeFileFactory.ts: -------------------------------------------------------------------------------- 1 | import { TreeFile } from '../Main/TreeFile' 2 | 3 | export class TreeFileFactory { 4 | static getWithShortPath (): TreeFile { 5 | return new TreeFile({ path: '/short/short.path' }) 6 | } 7 | 8 | static getWithLongPath (): TreeFile { 9 | return new TreeFile({ path: '/long/long/long/long/long.path' }) 10 | } 11 | 12 | static getWithVariousStatuses (): Array { 13 | return ['wip', 'stable', 'unstable', 'hold'] 14 | .map(name => new TreeFile({ path: `/${status}.path` })) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/vue-book/src/classes/Main/TreeFile.ts: -------------------------------------------------------------------------------- 1 | import { TreeFolder } from './TreeFolder' 2 | 3 | export class TreeFile { 4 | path: string = '' // Path is unique for tree file 5 | component: any | null = null // demo component 6 | folder: TreeFolder | null = null 7 | 8 | constructor (data: Partial = {}) { 9 | Object.assign(this, data) 10 | } 11 | 12 | openFolder (): void { 13 | this.folder && this.folder.open() 14 | } 15 | 16 | // returns `ComponentDemo.vue` 17 | getFilename (): string { 18 | return this.path.split('/').pop() || '' 19 | } 20 | 21 | getFilenameWithoutExtension (): string { 22 | return this.getFilename().split('.')[0] 23 | } 24 | 25 | getParentFolderPath (): string { 26 | return this.path.split('/').slice(0, -1).join('/') 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/vue-book/src/classes/Main/TreeFileCollection.ts: -------------------------------------------------------------------------------- 1 | import { TreeFile } from './TreeFile' 2 | 3 | export class TreeFileCollection { 4 | treeFiles: TreeFile[] = [] 5 | 6 | constructor (data: Partial = {}) { 7 | Object.assign(this, data) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/vue-book/src/classes/Main/TreeFolder.ts: -------------------------------------------------------------------------------- 1 | import { TreeFile } from './TreeFile' 2 | import { TreeFileCollection } from './TreeFileCollection' 3 | 4 | export class TreeFolder { 5 | name: string = '' 6 | isOpen: boolean = false 7 | folders: TreeFolder[] = [] 8 | files: TreeFile[] = [] 9 | parentFolder: TreeFolder | null = null 10 | 11 | constructor (data: Partial = {}) { 12 | Object.assign(this, data) 13 | } 14 | 15 | static createFromDemoFileCollection (treeFileCollection: TreeFileCollection): TreeFolder { 16 | const folderTemporary = new TreeFolder() 17 | 18 | // Add all files to temporary folder. 19 | const files = treeFileCollection.treeFiles 20 | files.forEach((node: any) => folderTemporary.addTreeFile(node)) 21 | 22 | const rootFolder = folderTemporary.folders[0] || folderTemporary 23 | 24 | // Bind nodes to folders. 25 | rootFolder.fillParents() 26 | // Open topmost folder for convenience. 27 | rootFolder.open() 28 | 29 | return rootFolder 30 | } 31 | 32 | /** 33 | * TODO Figure out how is that different from 'addFile' 34 | */ 35 | addFile (treeFile: TreeFile, relativePath: string): void { 36 | if (relativePath) { 37 | const folderNameArray = relativePath.split('/') 38 | const folderName = folderNameArray.shift() 39 | this.findOrCreateFolder(folderName) 40 | .addFile(treeFile, folderNameArray.join('/')) 41 | return 42 | } 43 | 44 | this.files.push(treeFile) 45 | } 46 | 47 | toggle (): void { 48 | this.isOpen ? this.close() : this.open() 49 | } 50 | 51 | open (): void { 52 | this.isOpen = true 53 | if (this.parentFolder && !this.parentFolder.isOpen) { 54 | this.parentFolder.open() 55 | } 56 | } 57 | 58 | close (): void { 59 | this.isOpen = false 60 | this.folders.forEach(folder => folder.close()) 61 | } 62 | 63 | findOrCreateFolder (name: string): TreeFolder { 64 | const foundFolder = this.folders.find(folder => folder.name === name) 65 | if (foundFolder) { 66 | return foundFolder 67 | } 68 | const folder = new TreeFolder({ name }) 69 | this.folders.push(folder) 70 | return folder 71 | } 72 | 73 | /** 74 | * Create reverse relations in a tree. 75 | */ 76 | fillParents () { 77 | this.files.forEach((treeFile: TreeFile) => { 78 | treeFile.folder = this 79 | }) 80 | this.folders.forEach((treeFolder: TreeFolder) => { 81 | treeFolder.parentFolder = this 82 | treeFolder.fillParents() 83 | }) 84 | } 85 | 86 | /** 87 | * TODO Figure out how is that different from 'addTreeFile' 88 | */ 89 | addTreeFile (treeFile: TreeFile): void { 90 | const relativePath = treeFile.getParentFolderPath().split('/').slice(1) 91 | .join('/') 92 | this.addFile(treeFile, relativePath) 93 | } 94 | 95 | isEmpty (): boolean { 96 | return !(this.folders.length || this.files.length) 97 | } 98 | 99 | /** 100 | * Take only open folders from existing tree. 101 | * This acts as clone and doesn't have files. 102 | * Intended for saving in storage to keep open folders synced. 103 | */ 104 | getOpenFolders (): TreeFolder[] { 105 | return this.folders.filter(folder => folder.isOpen) 106 | .map((folder: TreeFolder) => { 107 | return new TreeFolder({ 108 | name: folder.name, 109 | folders: folder.getOpenFolders(), 110 | isOpen: true, 111 | }) 112 | }) 113 | } 114 | 115 | /** 116 | * Open all folders from passed structure. Nesting counts. 117 | */ 118 | mergeWithFolders (folders: TreeFolder[]) { 119 | folders.forEach((folder: TreeFolder) => { 120 | const selfFolder = this.folders.find((selfFolder: TreeFolder) => { 121 | return folder.name === selfFolder.name 122 | }) 123 | if (!selfFolder) { 124 | return 125 | } 126 | selfFolder.isOpen = true 127 | selfFolder.mergeWithFolders(folder.folders) 128 | }) 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /packages/vue-book/src/classes/Main/VueBookConfig.ts: -------------------------------------------------------------------------------- 1 | export class VueBookConfig { 2 | requireContext: any 3 | path!: string | RegExp 4 | hideFileExtensions: boolean = false 5 | hideNavigation: boolean = false 6 | 7 | constructor (data: Partial = {}) { 8 | if (!data.requireContext) { 9 | throw(`'requireContext' is not defined on VueBookConfig`) 10 | } 11 | Object.assign(this, data) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/vue-book/src/classes/Mapper/DemoFolderMapper.ts: -------------------------------------------------------------------------------- 1 | import { TreeFolder } from '../Main/TreeFolder' 2 | import { TreeFileMapper } from './TreeFileMapper' 3 | 4 | export default class DemoFolderMapper { 5 | static map ({ name = '', isOpen = false, files = [], folders = [] } = {}): TreeFolder { 6 | return new TreeFolder({ 7 | name, 8 | isOpen, 9 | files: files.map(TreeFileMapper.toClass), 10 | folders: folders.map(DemoFolderMapper.map), 11 | }) 12 | } 13 | 14 | static transform (treeFolder: TreeFolder): any { 15 | return { 16 | name: treeFolder.name, 17 | isOpen: treeFolder.isOpen, 18 | files: treeFolder.files.map(TreeFileMapper.toComponent), 19 | folders: treeFolder.folders.map(DemoFolderMapper.transform), 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/vue-book/src/classes/Mapper/TreeFileMapper.ts: -------------------------------------------------------------------------------- 1 | import { TreeFile } from '../Main/TreeFile' 2 | import { Vue } from 'vue-class-component' 3 | 4 | export class TreeFileMapper { 5 | static toClass ({ path, component }: { path: string, component: Vue }): TreeFile { 6 | return new TreeFile({ 7 | path, 8 | component, 9 | }) 10 | } 11 | 12 | static toComponent (demoFile: TreeFile) { 13 | return { 14 | path: demoFile.path, 15 | component: {}, 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/ComButtonIcon/ComButtonIcon.demo.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 29 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/ComButtonIcon/ComButtonIcon.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | 28 | 46 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/ComInput/VbInput.demo.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 23 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/ComInput/VbInput.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 58 | 59 | 73 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/DemoPageConfig.ts: -------------------------------------------------------------------------------- 1 | export enum DemoPageMode { 2 | Tree = 'Tree', 3 | Search = 'Search', 4 | } 5 | 6 | export default class DemoPageConfig { 7 | mode: DemoPageMode = DemoPageMode.Search 8 | isHidden: boolean | null = null 9 | isFlat: boolean = false 10 | searchText: string = '' 11 | width: number = 300 12 | 13 | constructor (data: Partial = {}) { 14 | Object.assign(this, data) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/DemoPageMenu.demo.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/VbMenu.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 55 | 56 | 67 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/VbNotFound.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 32 | 33 | 51 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/VbPage.vue: -------------------------------------------------------------------------------- 1 | 95 | 96 | 375 | 376 | 474 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/VueBookTreeOptions.ts: -------------------------------------------------------------------------------- 1 | import { TreeFile } from '../../classes/Main/TreeFile' 2 | 3 | export const VueBookTreeOptionsInterface = 'VueBookTreeOptionsInterface' 4 | 5 | export class VueBookTreeOptions { 6 | noRouter: boolean = false 7 | selectedTreeFile: TreeFile | null = null 8 | hideFileExtensions: boolean = false 9 | 10 | constructor (data: Partial = {}) { 11 | Object.assign(this, data) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/DemoPage/demo-file.md: -------------------------------------------------------------------------------- 1 | In demo component you can use `beforeRouteUpdate` hook to wipe state before transition to another component. 2 | For state set-up you can use `created` or `mounted`. 3 | 4 | Other hooks are not available because demo components are not registered as routes in vue-router, part of url is parsed instead. 5 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/Exposed/ContainerFocusService.ts: -------------------------------------------------------------------------------- 1 | import { Options, Vue } from 'vue-class-component' 2 | import { ArrayHelpers } from 'asva-helpers' 3 | import { Inject, Prop } from 'vue-property-decorator' 4 | 5 | const createContainerFocusService = () => { 6 | class Container extends Vue { 7 | focusedContainers: string[] = [] 8 | 9 | focusContainer (id: string): void { 10 | this.focusedContainers.push(id) 11 | } 12 | 13 | unfocusContainer (id: string): void { 14 | ArrayHelpers.remove(this.focusedContainers, id) 15 | } 16 | 17 | isUnfocused (id: string): boolean { 18 | // TODO Use proper TS. 19 | return (this as any).focusedContainers.length && 20 | !this.focusedContainers.includes(id) 21 | } 22 | } 23 | return Container 24 | } 25 | 26 | export class ContainerFocusProvideMixin extends Vue { 27 | provide () { 28 | return { 29 | vbFocusService: createContainerFocusService(), 30 | } 31 | } 32 | } 33 | 34 | export class ContainerFocusInjectMixin extends Vue { 35 | @Inject({ default: null }) vbFocusService!: any 36 | @Prop(Boolean) focus!: boolean 37 | 38 | id = Math.round(Math.random() * 100000) + '' 39 | 40 | created () { 41 | if (!this.vbFocusService) { 42 | return 43 | } 44 | if (this.focus) { 45 | this.vbFocusService.focusContainer(this.id) 46 | } 47 | } 48 | 49 | beforeDestroy () { 50 | if (!this.vbFocusService) { 51 | return 52 | } 53 | if (this.focus) { 54 | this.vbFocusService.unfocusContainer(this.id) 55 | } 56 | } 57 | 58 | get isHiddenAsUnfocused () { 59 | if (!this.vbFocusService) { 60 | return 61 | } 62 | return this.vbFocusService.isUnfocused(this.id) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/Exposed/VbCard-focus.demo.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 28 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/Exposed/VbCard.demo.vue: -------------------------------------------------------------------------------- 1 | 52 | 53 | 70 | 71 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/Exposed/VbCard.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 113 | 114 | 199 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/Exposed/VbDemo.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | 21 | 32 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/Exposed/__demo__/RefreshCounter.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 24 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/FileTree/BookComponentListFolder.demo.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 36 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/FileTree/BookComponentListFolder.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 89 | 90 | 125 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/FileTree/BookComponentListItem.demo.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 31 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/FileTree/BookComponentListItem.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 67 | 68 | 96 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/FileTree/DemoFileList.demo.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 34 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/FileTree/DemoFileList.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 38 | 39 | 54 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/FileTree/ListCursor.ts: -------------------------------------------------------------------------------- 1 | import { TreeFile } from '../../classes/Main/TreeFile' 2 | 3 | export class ListCursor { 4 | preSelectedItem: TreeFile | null = null 5 | 6 | constructor (data: Partial = {}) { 7 | Object.assign(this, data) 8 | } 9 | 10 | clean (): void { 11 | this.preSelectedItem = null 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/FileTree/TreeDemoFileList.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | 23 | 36 | -------------------------------------------------------------------------------- /packages/vue-book/src/components/Service/VueBookResizeLine.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 41 | 42 | 54 | -------------------------------------------------------------------------------- /packages/vue-book/src/plugins/font-awesome-config.ts: -------------------------------------------------------------------------------- 1 | // Vue font awesome config. 2 | import { library } from '@fortawesome/fontawesome-svg-core' 3 | // NOTE Importing them all in one import doesn't trigger webpack tree-shaking. 4 | // As a result - whole file is included, giving additional 600Kb to bundle size. 5 | // See https://github.com/FortAwesome/react-fontawesome/issues/70 6 | import { faArrowsAltV } from '@fortawesome/free-solid-svg-icons/faArrowsAltV' 7 | import { faBars } from '@fortawesome/free-solid-svg-icons/faBars' 8 | import { faCaretDown } from '@fortawesome/free-solid-svg-icons/faCaretDown' 9 | import { faCaretRight } from '@fortawesome/free-solid-svg-icons/faCaretRight' 10 | import { faDotCircle } from '@fortawesome/free-solid-svg-icons/faDotCircle' 11 | import { faExchangeAlt } from '@fortawesome/free-solid-svg-icons/faExchangeAlt' 12 | import { faFile } from '@fortawesome/free-solid-svg-icons/faFile' 13 | import { faFolder } from '@fortawesome/free-solid-svg-icons/faFolder' 14 | import { faSearch } from '@fortawesome/free-solid-svg-icons/faSearch' 15 | import { faServer } from '@fortawesome/free-solid-svg-icons/faServer' 16 | import { faTimes } from '@fortawesome/free-solid-svg-icons/faTimes' 17 | import { faSync } from '@fortawesome/free-solid-svg-icons/faSync' 18 | import { faArrowLeft } from '@fortawesome/free-solid-svg-icons/faArrowLeft' 19 | 20 | library.add(faServer, faFolder, faSearch, faBars, faExchangeAlt, faDotCircle, faCaretDown, faCaretRight, faFile, faArrowsAltV, faSync, faTimes, faArrowLeft) 21 | -------------------------------------------------------------------------------- /packages/vue-book/src/scss/app.scss: -------------------------------------------------------------------------------- 1 | @import 'variables/variables'; 2 | @import 'mixins/mixins'; 3 | 4 | // Font for icons. 5 | @import url(https://fonts.googleapis.com/icon?family=Material+Icons); 6 | -------------------------------------------------------------------------------- /packages/vue-book/src/scss/mixins/mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin reset() { 2 | body, div, dl, dt, dd, ul, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, input, textarea, p, blockquote, th, td { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | table { 7 | border-collapse: collapse; 8 | border-spacing: 0; 9 | } 10 | fieldset, img, abbr { 11 | border: 0; 12 | } 13 | address, caption, cite, code, dfn, em, strong, th, var { 14 | font-style: normal; 15 | font-weight: normal; 16 | } 17 | ul li { 18 | list-style: none; 19 | } 20 | caption, th { 21 | text-align: left; 22 | } 23 | h1, h2, h3, h4, h5, h6 { 24 | font-size: 100%; 25 | font-weight: normal; 26 | } 27 | sup { 28 | vertical-align: text-top; 29 | } 30 | sub { 31 | vertical-align: text-bottom; 32 | } 33 | input, textarea, select { 34 | font-family: inherit; 35 | font-size: inherit; 36 | font-weight: inherit; 37 | } 38 | legend { 39 | color: #000; 40 | } 41 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, main { 42 | display: block; 43 | } 44 | img { 45 | max-width: 100%; 46 | height: auto; 47 | } 48 | } 49 | 50 | @mixin flexCenter() { 51 | display: flex; 52 | justify-content: center; 53 | align-items: center; 54 | } 55 | -------------------------------------------------------------------------------- /packages/vue-book/src/scss/reset.scss: -------------------------------------------------------------------------------- 1 | pre { 2 | margin: 0; 3 | } -------------------------------------------------------------------------------- /packages/vue-book/src/scss/resources.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/mixins"; 2 | @import "variables/variables"; -------------------------------------------------------------------------------- /packages/vue-book/src/scss/smart-grid/smart-grid-config.js: -------------------------------------------------------------------------------- 1 | // In order to generate smart grid - run this file with node directly 2 | 3 | var smartgrid = require('smart-grid') 4 | 5 | /* It's principal settings in smart grid project */ 6 | var settings = { 7 | outputStyle: 'scss', /* less || scss || sass || styl */ 8 | columns: 12, /* number of grid columns */ 9 | offset: '30px', /* gutter width px || % */ 10 | mobileFirst: true, /* mobileFirst ? 'min-width' : 'max-width' */ 11 | container: { 12 | maxWidth: '1200px', /* max-width оn very large screen */ 13 | fields: '30px', /* side fields */ 14 | }, 15 | breakPoints: { 16 | lg: { 17 | width: '1100px', /* -> @media (max-width: 1100px) */ 18 | }, 19 | md: { 20 | width: '960px', 21 | }, 22 | sm: { 23 | width: '780px', 24 | fields: '15px', /* set fields only if you want to change container.fields */ 25 | }, 26 | xs: { 27 | width: '560px', 28 | }, 29 | /* 30 | We can create any quantity of break points. 31 | 32 | some_name: { 33 | width: 'Npx', 34 | fields: 'N(px|%|rem)', 35 | offset: 'N(px|%|rem)' 36 | } 37 | */ 38 | }, 39 | } 40 | 41 | smartgrid('./', settings) 42 | -------------------------------------------------------------------------------- /packages/vue-book/src/scss/smart-grid/smart-grid.scss: -------------------------------------------------------------------------------- 1 | $columns: 12; 2 | $atom: (100% / $columns); 3 | 4 | $break_xs: 560px; 5 | $break_sm: 780px; 6 | $break_md: 960px; 7 | $break_lg: 1100px; 8 | 9 | $offset: 8px; 10 | $offset_xs: $offset; 11 | $offset_sm: $offset; 12 | $offset_md: $offset; 13 | $offset_lg: $offset; 14 | 15 | $offset_one_side: ($offset / 2); 16 | $offset_xs_one_side: ($offset_xs / 2); 17 | $offset_sm_one_side: ($offset_sm / 2); 18 | $offset_md_one_side: ($offset_md / 2); 19 | $offset_lg_one_side: ($offset_lg / 2); 20 | 21 | $fields: 30px; 22 | $fields_sm: 15px; 23 | 24 | @mixin wrapper-full() { 25 | padding-left: $fields; 26 | padding-right: $fields; 27 | 28 | @include sm-block() { 29 | padding-left: $fields_sm; 30 | padding-right: $fields_sm; 31 | } 32 | } 33 | 34 | @mixin row-offsets() { 35 | margin-left: ($offset_one_side * -1); 36 | margin-right: ($offset_one_side * -1); 37 | } 38 | 39 | @mixin col-offsets($type) { 40 | #{$type}-left: $offset_one_side; 41 | #{$type}-right: $offset_one_side; 42 | } 43 | 44 | @mixin wrapper() { 45 | max-width: 1200px; 46 | margin: 0 auto; 47 | @include wrapper-full(); 48 | } 49 | 50 | @mixin row-flex() { 51 | display: flex; 52 | flex-wrap: wrap; 53 | @include row-offsets(); 54 | } 55 | 56 | @mixin row-float() { 57 | @include row-offsets(); 58 | @include clearfix(); 59 | } 60 | 61 | @mixin row-ib() { 62 | @include row-offsets(); 63 | } 64 | 65 | @mixin col() { 66 | box-sizing: border-box; 67 | word-wrap: break-word; 68 | @include col-offsets(margin); 69 | } 70 | 71 | @mixin col-float() { 72 | float: left; 73 | } 74 | 75 | @mixin col-ib() { 76 | display: inline-block; 77 | vertical-align: top; 78 | } 79 | 80 | @mixin col-padding() { 81 | word-wrap: break-word; 82 | @include col-offsets(padding); 83 | } 84 | 85 | @mixin size($n) { 86 | $val: 100% / $columns * $n; 87 | width: #{calc(#{$val} - #{$offset})}; 88 | } 89 | 90 | @mixin size-xs($n) { 91 | $val: 100% / $columns * $n; 92 | @include xs(width, #{calc(#{$val} - #{$offset_xs})}); 93 | } 94 | 95 | @mixin size-sm($n) { 96 | $val: 100% / $columns * $n; 97 | @include sm(width, #{calc(#{$val} - #{$offset_sm})}); 98 | } 99 | 100 | @mixin size-md($n) { 101 | $val: 100% / $columns * $n; 102 | @include md(width, #{calc(#{$val} - #{$offset_md})}); 103 | } 104 | 105 | @mixin size-lg($n) { 106 | $val: 100% / $columns * $n; 107 | @include lg(width, #{calc(#{$val} - #{$offset_lg})}); 108 | } 109 | 110 | @mixin shift($n) { 111 | $val: 100% / $columns * $n; 112 | margin-left: #{calc(#{$val} + #{$offset_one_side})}; 113 | margin-right: #{calc(#{$val} + #{$offset_one_side})}; 114 | } 115 | 116 | @mixin shift-left($n) { 117 | $val: 100% / $columns * $n; 118 | margin-left: #{calc(#{$val} + #{$offset_one_side})}; 119 | } 120 | 121 | @mixin shift-right($n) { 122 | $val: 100% / $columns * $n; 123 | margin-right: #{calc(#{$val} + #{$offset_one_side})}; 124 | } 125 | 126 | @mixin shift-padding($n) { 127 | $val: 100% / $columns * $n; 128 | padding-left: #{calc(#{$val} + #{$offset_one_side})}; 129 | padding-right: #{calc(#{$val} + #{$offset_one_side})}; 130 | } 131 | 132 | @mixin shift-padding-left($n) { 133 | $val: 100% / $columns * $n; 134 | padding-left: #{calc(#{$val} + #{$offset_one_side})}; 135 | } 136 | 137 | @mixin shift-padding-right($n) { 138 | $val: 100% / $columns * $n; 139 | padding-right: #{calc(#{$val} + #{$offset_one_side})}; 140 | } 141 | 142 | @mixin shift-xs($n) { 143 | $val: 100% / $columns * $n; 144 | @include xs(margin-left, #{calc(#{$val} + #{$offset_xs_one_side})}); 145 | @include xs(margin-right, #{calc(#{$val} + #{$offset_xs_one_side})}); 146 | } 147 | 148 | @mixin shift-xs-left($n) { 149 | $val: 100% / $columns * $n; 150 | @include xs(margin-left, #{calc(#{$val} + #{$offset_xs_one_side})}); 151 | } 152 | 153 | @mixin shift-xs-right($n) { 154 | $val: 100% / $columns * $n; 155 | @include xs(margin-right, #{calc(#{$val} + #{$offset_xs_one_side})}); 156 | } 157 | 158 | @mixin shift-xs-padding($n) { 159 | $val: 100% / $columns * $n; 160 | @include xs(padding-left, #{calc(#{$val} + #{$offset_xs_one_side})}); 161 | @include xs(padding-right, #{calc(#{$val} + #{$offset_xs_one_side})}); 162 | } 163 | 164 | @mixin shift-xs-padding-left($n) { 165 | $val: 100% / $columns * $n; 166 | @include xs(padding-left, #{calc(#{$val} + #{$offset_xs_one_side})}); 167 | } 168 | 169 | @mixin shift-xs-padding-right($n) { 170 | $val: 100% / $columns * $n; 171 | @include xs(padding-right, #{calc(#{$val} + #{$offset_xs_one_side})}); 172 | } 173 | 174 | @mixin shift-sm($n) { 175 | $val: 100% / $columns * $n; 176 | @include sm(margin-left, #{calc(#{$val} + #{$offset_sm_one_side})}); 177 | @include sm(margin-right, #{calc(#{$val} + #{$offset_sm_one_side})}); 178 | } 179 | 180 | @mixin shift-sm-left($n) { 181 | $val: 100% / $columns * $n; 182 | @include sm(margin-left, #{calc(#{$val} + #{$offset_sm_one_side})}); 183 | } 184 | 185 | @mixin shift-sm-right($n) { 186 | $val: 100% / $columns * $n; 187 | @include sm(margin-right, #{calc(#{$val} + #{$offset_sm_one_side})}); 188 | } 189 | 190 | @mixin shift-sm-padding($n) { 191 | $val: 100% / $columns * $n; 192 | @include sm(padding-left, #{calc(#{$val} + #{$offset_sm_one_side})}); 193 | @include sm(padding-right, #{calc(#{$val} + #{$offset_sm_one_side})}); 194 | } 195 | 196 | @mixin shift-sm-padding-left($n) { 197 | $val: 100% / $columns * $n; 198 | @include sm(padding-left, #{calc(#{$val} + #{$offset_sm_one_side})}); 199 | } 200 | 201 | @mixin shift-sm-padding-right($n) { 202 | $val: 100% / $columns * $n; 203 | @include sm(padding-right, #{calc(#{$val} + #{$offset_sm_one_side})}); 204 | } 205 | 206 | @mixin shift-md($n) { 207 | $val: 100% / $columns * $n; 208 | @include md(margin-left, #{calc(#{$val} + #{$offset_md_one_side})}); 209 | @include md(margin-right, #{calc(#{$val} + #{$offset_md_one_side})}); 210 | } 211 | 212 | @mixin shift-md-left($n) { 213 | $val: 100% / $columns * $n; 214 | @include md(margin-left, #{calc(#{$val} + #{$offset_md_one_side})}); 215 | } 216 | 217 | @mixin shift-md-right($n) { 218 | $val: 100% / $columns * $n; 219 | @include md(margin-right, #{calc(#{$val} + #{$offset_md_one_side})}); 220 | } 221 | 222 | @mixin shift-md-padding($n) { 223 | $val: 100% / $columns * $n; 224 | @include md(padding-left, #{calc(#{$val} + #{$offset_md_one_side})}); 225 | @include md(padding-right, #{calc(#{$val} + #{$offset_md_one_side})}); 226 | } 227 | 228 | @mixin shift-md-padding-left($n) { 229 | $val: 100% / $columns * $n; 230 | @include md(padding-left, #{calc(#{$val} + #{$offset_md_one_side})}); 231 | } 232 | 233 | @mixin shift-md-padding-right($n) { 234 | $val: 100% / $columns * $n; 235 | @include md(padding-right, #{calc(#{$val} + #{$offset_md_one_side})}); 236 | } 237 | 238 | @mixin shift-lg($n) { 239 | $val: 100% / $columns * $n; 240 | @include lg(margin-left, #{calc(#{$val} + #{$offset_lg_one_side})}); 241 | @include lg(margin-right, #{calc(#{$val} + #{$offset_lg_one_side})}); 242 | } 243 | 244 | @mixin shift-lg-left($n) { 245 | $val: 100% / $columns * $n; 246 | @include lg(margin-left, #{calc(#{$val} + #{$offset_lg_one_side})}); 247 | } 248 | 249 | @mixin shift-lg-right($n) { 250 | $val: 100% / $columns * $n; 251 | @include lg(margin-right, #{calc(#{$val} + #{$offset_lg_one_side})}); 252 | } 253 | 254 | @mixin shift-lg-padding($n) { 255 | $val: 100% / $columns * $n; 256 | @include lg(padding-left, #{calc(#{$val} + #{$offset_lg_one_side})}); 257 | @include lg(padding-right, #{calc(#{$val} + #{$offset_lg_one_side})}); 258 | } 259 | 260 | @mixin shift-lg-padding-left($n) { 261 | $val: 100% / $columns * $n; 262 | @include lg(padding-left, #{calc(#{$val} + #{$offset_lg_one_side})}); 263 | } 264 | 265 | @mixin shift-lg-padding-right($n) { 266 | $val: 100% / $columns * $n; 267 | @include lg(padding-right, #{calc(#{$val} + #{$offset_lg_one_side})}); 268 | } 269 | 270 | @mixin xs($name, $value) { 271 | @media screen and (min-width: $break_xs) { 272 | #{$name}: $value; 273 | } 274 | } 275 | 276 | @mixin xs-block() { 277 | @media screen and (min-width: $break_xs) { 278 | @content; 279 | } 280 | } 281 | 282 | @mixin sm($name, $value) { 283 | @media screen and (min-width: $break_sm) { 284 | #{$name}: $value; 285 | } 286 | } 287 | 288 | @mixin sm-block() { 289 | @media screen and (min-width: $break_sm) { 290 | @content; 291 | } 292 | } 293 | 294 | @mixin md($name, $value) { 295 | @media screen and (min-width: $break_md) { 296 | #{$name}: $value; 297 | } 298 | } 299 | 300 | @mixin md-block() { 301 | @media screen and (min-width: $break_md) { 302 | @content; 303 | } 304 | } 305 | 306 | @mixin lg($name, $value) { 307 | @media screen and (min-width: $break_lg) { 308 | #{$name}: $value; 309 | } 310 | } 311 | 312 | @mixin lg-block() { 313 | @media screen and (min-width: $break_lg) { 314 | @content; 315 | } 316 | } 317 | 318 | @mixin from($min_width) { 319 | @media screen and (min-width: $min_width) { 320 | @content; 321 | } 322 | } 323 | 324 | @mixin to($max_width) { 325 | @media screen and (max-width: $max_width) { 326 | @content; 327 | } 328 | } 329 | 330 | @mixin from-to($min_width, $max_width) { 331 | @media screen and (min-width: $min_width) and (max-width: $max_width) { 332 | @content; 333 | } 334 | } 335 | 336 | @mixin reset() { 337 | body, div, dl, dt, dd, ul, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, input, textarea, p, blockquote, th, td { 338 | margin: 0; 339 | padding: 0; 340 | } 341 | table { 342 | border-collapse: collapse; 343 | border-spacing: 0; 344 | } 345 | fieldset, img, abbr { 346 | border: 0; 347 | } 348 | address, caption, cite, code, dfn, em, strong, th, var { 349 | font-style: normal; 350 | font-weight: normal; 351 | } 352 | ul li { 353 | list-style: none; 354 | } 355 | caption, th { 356 | text-align: left; 357 | } 358 | h1, h2, h3, h4, h5, h6 { 359 | font-size: 100%; 360 | font-weight: normal; 361 | } 362 | sup { 363 | vertical-align: text-top; 364 | } 365 | sub { 366 | vertical-align: text-bottom; 367 | } 368 | input, textarea, select { 369 | font-family: inherit; 370 | font-size: inherit; 371 | font-weight: inherit; 372 | } 373 | legend { 374 | color: #000; 375 | } 376 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, main { 377 | display: block; 378 | } 379 | img { 380 | max-width: 100%; 381 | height: auto; 382 | } 383 | } 384 | 385 | @mixin debug($background, $outline) { 386 | height: 100vh; 387 | position: fixed; 388 | width: 100%; 389 | 390 | > div { 391 | height: inherit; 392 | @include wrapper(); 393 | 394 | > div { 395 | height: inherit; 396 | @include row-flex(); 397 | 398 | > div { 399 | @include col(); 400 | @include size(1); 401 | height: inherit; 402 | outline: $outline; 403 | background: $background; 404 | } 405 | } 406 | } 407 | } 408 | 409 | @mixin clearfix() { 410 | &::after { 411 | display: block; 412 | content: ""; 413 | clear: both; 414 | } 415 | } 416 | -------------------------------------------------------------------------------- /packages/vue-book/src/scss/variables/colors.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvae/vue-book/93aeb6326dc1c8922c9196166a2154f54b35b5bd/packages/vue-book/src/scss/variables/colors.scss -------------------------------------------------------------------------------- /packages/vue-book/src/scss/variables/variables.scss: -------------------------------------------------------------------------------- 1 | $color--main: #1fc8db; 2 | $color--white: white; 3 | $color--icon: #3f506e; 4 | $color--icon--hover: lighten($color--icon, 30%); 5 | 6 | $border-color--main: $color--main; 7 | 8 | $border-radius--main: 3px; 9 | -------------------------------------------------------------------------------- /packages/vue-book/src/services/ScreenSizeService.ts: -------------------------------------------------------------------------------- 1 | import { reactive } from 'vue' 2 | 3 | export class ScreenSizeService { 4 | public width = window.innerWidth 5 | constructor () { 6 | window.addEventListener('resize', () => { 7 | this.width = window.innerWidth 8 | }) 9 | } 10 | 11 | get widthPx (): string { 12 | return `${this.width}px` 13 | } 14 | 15 | get isMobile (): boolean { 16 | return this.width <= 512 17 | } 18 | } 19 | 20 | export const screenSizeService = reactive(new ScreenSizeService()) 21 | -------------------------------------------------------------------------------- /packages/vue-book/src/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from 'vue' 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode { 7 | } 8 | 9 | // tslint:disable no-empty-interface 10 | interface ElementClass extends Vue { 11 | } 12 | 13 | interface IntrinsicElements { 14 | [elem: string]: any; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/vue-book/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | export default Vue 4 | } 5 | 6 | // Hacky globals (should be fixed on library maintainer side) 7 | declare module '@fortawesome/*' 8 | declare module 'vue-book' 9 | -------------------------------------------------------------------------------- /packages/vue-book/src/store/FoldersStore.ts: -------------------------------------------------------------------------------- 1 | import storage from './storage' 2 | import { TreeFolder } from '../classes/Main/TreeFolder' 3 | import DemoFolderMapper from '../classes/Mapper/DemoFolderMapper' 4 | 5 | const STORAGE_KEY = 'openFolders' 6 | 7 | export class FoldersStore { 8 | public openFolders: TreeFolder[] = [] 9 | 10 | load (): void { 11 | const data = storage.fetch(STORAGE_KEY) || [] 12 | const folders = data.map(DemoFolderMapper.map) 13 | 14 | this.openFolders = folders 15 | } 16 | 17 | save (): void { 18 | const data = this.openFolders.map(DemoFolderMapper.transform) 19 | storage.store(STORAGE_KEY, data) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/vue-book/src/store/configStore.ts: -------------------------------------------------------------------------------- 1 | import storage from './storage' 2 | import DemoPageConfig from '../components/DemoPage/DemoPageConfig' 3 | 4 | const STORAGE_KEY = 'config' 5 | 6 | export class ConfigStore { 7 | public config: DemoPageConfig | null = null 8 | 9 | load (): void { 10 | const data = storage.fetch(STORAGE_KEY) || new DemoPageConfig() 11 | this.config = new DemoPageConfig(data) 12 | } 13 | 14 | save (): void { 15 | storage.store(STORAGE_KEY, this.config) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/vue-book/src/store/storage.ts: -------------------------------------------------------------------------------- 1 | const STORAGE_KEY = 'vue-book' 2 | 3 | export default { 4 | store (key: string, value: any): void { 5 | const all: { [key: string]: any } = this.getAll() 6 | all[key] = value 7 | localStorage.setItem(STORAGE_KEY, JSON.stringify(all)) 8 | }, 9 | fetch (key: string): any { 10 | return this.getAll()[key] 11 | }, 12 | getAll (): { [key: string]: any } { 13 | const defaultItems = this.getDefault() 14 | if (localStorage.getItem(STORAGE_KEY) === undefined) { 15 | return defaultItems 16 | } 17 | const storedItems = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]') 18 | return Object.assign(defaultItems, storedItems) 19 | }, 20 | getDefault () { 21 | return {} 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /packages/vue-book/tests/unit/DemoFolder.spec.ts: -------------------------------------------------------------------------------- 1 | import { TreeFolder } from '../../src/classes/Main/TreeFolder' 2 | import { TreeFile } from '../../src/classes/Main/TreeFile' 3 | 4 | describe('DemoFolder', () => { 5 | it('is initialized', () => { 6 | const folder = new TreeFolder() 7 | expect(folder.name).toBe('') 8 | expect(folder.folders).toEqual([]) 9 | expect(folder.files).toEqual([]) 10 | }) 11 | it('findOrCreateFolder', () => { 12 | const folder = new TreeFolder() 13 | const newFolder = folder.findOrCreateFolder('name') 14 | expect(newFolder.name).toBe('name') 15 | const oldFolder = folder.findOrCreateFolder('name') 16 | expect(oldFolder).toBe(newFolder) 17 | }) 18 | it('addFile', () => { 19 | const folder = new TreeFolder() 20 | folder.addFile(new TreeFile(), 'one/two') 21 | const folderOne = folder.folders[0] 22 | expect(folderOne.name).toBe('one') 23 | const folderTwo = folderOne.folders[0] 24 | expect(folderTwo.name).toBe('two') 25 | }) 26 | it('addTreeFile', () => { 27 | const folder = new TreeFolder() 28 | folder.addTreeFile(new TreeFile({ path: '/one/two/file.js' })) 29 | folder.addTreeFile(new TreeFile({ path: '/one/two/file1.js' })) 30 | folder.addTreeFile(new TreeFile({ path: '/one/file2.js' })) 31 | const folderOne = folder.folders[0] 32 | expect(folderOne.name).toBe('one') 33 | expect(folderOne.files.length).toBe(1) 34 | const folderTwo = folderOne.folders[0] 35 | expect(folderTwo.name).toBe('two') 36 | expect(folderTwo.files.length).toBe(2) 37 | }) 38 | it('getOpenFolders', () => { 39 | const folder = new TreeFolder() 40 | folder.addTreeFile(new TreeFile({ path: '/one/file1.js' })) 41 | folder.addTreeFile(new TreeFile({ path: '/two/file2.js' })) 42 | folder.addTreeFile(new TreeFile({ path: '/three/file3.js' })) 43 | expect(folder.getOpenFolders().length).toBe(0) 44 | folder.folders[0].open() 45 | expect(folder.getOpenFolders().length).toBe(1) 46 | folder.folders[0].close() 47 | expect(folder.getOpenFolders().length).toBe(0) 48 | folder.folders[1].open() 49 | folder.folders[2].open() 50 | expect(folder.getOpenFolders().length).toBe(2) 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /packages/vue-book/tests/unit/DemoNode.spec.ts: -------------------------------------------------------------------------------- 1 | import { TreeFile } from '../../src/classes/Main/TreeFile' 2 | 3 | describe('TreeFile', () => { 4 | it('is initialized', () => { 5 | const node = new TreeFile() 6 | expect(node.path).toBe('') 7 | }) 8 | it('getParentFolder', () => { 9 | const treeFile = new TreeFile({ path: 'one/two/file.js' }) 10 | expect(treeFile.getParentFolderPath()).toBe('one/two') 11 | const rootTreeFile = new TreeFile({ path: 'file.js' }) 12 | expect(rootTreeFile.getParentFolderPath()).toBe('') 13 | }) 14 | it('getFileName', () => { 15 | const treeFile = new TreeFile({ path: 'one/two/file.js' }) 16 | expect(treeFile.getFilename()).toBe('file.js') 17 | const rootTreeFile = new TreeFile({ path: 'file.js' }) 18 | expect(rootTreeFile.getFilename()).toBe('file.js') 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/vue-book/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "experimentalDecorators": true, 10 | "esModuleInterop": true, 11 | "allowSyntheticDefaultImports": true, 12 | "sourceMap": true, 13 | "baseUrl": ".", 14 | "types": [ 15 | "webpack-env", 16 | "jest" 17 | ], 18 | "lib": [ 19 | "es2015", 20 | "dom", 21 | "dom.iterable", 22 | "es7", 23 | "scripthost" 24 | ] 25 | }, 26 | "include": [ 27 | "src/**/*.ts", 28 | "src/**/*.tsx", 29 | "src/**/*.vue", 30 | "tests/**/*.ts", 31 | "tests/**/*.tsx" 32 | ], 33 | "exclude": [ 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/vue-book/vue-book.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'vue-book' { 2 | export function createRoute (options: any): any 3 | export function createComponent (options: any): any 4 | 5 | export function VueBookComponents (): any 6 | } 7 | -------------------------------------------------------------------------------- /packages/vue-book/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | lintOnSave: false, 3 | transpileDependencies: [ 4 | 'vuestic-ui', 5 | ], 6 | configureWebpack: { 7 | entry: __dirname + '/demo/main.ts', 8 | devServer: { 9 | inline: true, 10 | historyApiFallback: { 11 | disableDotRule: true, 12 | index: '/demo/index.html', 13 | }, 14 | overlay: { 15 | warnings: true, 16 | errors: true, 17 | }, 18 | }, 19 | }, 20 | } 21 | --------------------------------------------------------------------------------